coral-spectrum/coral-component-textarea/src/scripts/Textarea.js
- /**
- * Copyright 2019 Adobe. All rights reserved.
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License. You may obtain a copy
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
- * OF ANY KIND, either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
- */
-
- import {BaseComponent} from '../../../coral-base-component';
- import {BaseFormField} from '../../../coral-base-formfield';
- // todo ideally there should be a coral-base-textfield to inherit from
- import '../../../coral-component-textfield';
- import {transform, validate, commons} from '../../../coral-utils';
- import {Decorator} from '../../../coral-decorator';
-
- const CLASSNAME = '_coral-Textfield';
-
- /**
- Enumeration for {@link Textarea} variants.
-
- @typedef {Object} TextareaVariantEnum
-
- @property {String} DEFAULT
- A default textarea.
- @property {String} QUIET
- A textarea with no border or background.
- */
- const variant = {
- DEFAULT: 'default',
- QUIET: 'quiet'
- };
-
- // Builds a string containing all possible variant classnames. This will be used to remove classnames when the variant
- // changes
- const ALL_VARIANT_CLASSES = [];
- for (const variantValue in variant) {
- ALL_VARIANT_CLASSES.push(`${CLASSNAME}--${variant[variantValue]}`);
- }
-
- /**
- @class Coral.Textarea
- @classdesc A Textarea component is the default multi-line text form field.
- @htmltag coral-textarea
- @htmlbasetag textarea
- @extends {HTMLTextAreaElement}
- @extends {BaseComponent}
- @extends {BaseFormField}
- */
- const Textarea = Decorator(class extends BaseFormField(BaseComponent(HTMLTextAreaElement)) {
- /** @ignore */
- constructor() {
- super();
-
- this._delegateEvents(commons.extend(this._events, {
- input: '_onInput'
- }));
- }
-
- /**
- The textarea's variant. See {@link TextareaVariantEnum}.
-
- @type {String}
- @default TextareaVariantEnum.DEFAULT
- @htmlattribute variant
- @htmlattributereflected
- */
- get variant() {
- return this._variant || variant.DEFAULT;
- }
-
- set variant(value) {
- value = transform.string(value).toLowerCase();
- this._variant = validate.enumeration(variant)(value) && value || variant.DEFAULT;
- this._reflectAttribute('variant', this._variant);
-
- // removes every existing variant
- this.classList.remove(...ALL_VARIANT_CLASSES);
-
- if (this._variant !== variant.DEFAULT) {
- this.classList.add(`${CLASSNAME}--${this._variant}`);
- }
-
- // Restore the original height
- if (this._variant === variant.QUIET) {
- this._defaultHeight = this._defaultHeight || this.style.height;
- } else {
- this.style.height = this._defaultHeight;
- this._defaultHeight = undefined;
- }
-
- this._onInput();
- }
-
- /**
- Inherited from {@link BaseFormField#reset}.
- */
- reset() {
- // The textarea uses the textContent to save the old value and not the value attribute
- /** @ignore */
- this.value = this.textContent;
-
- // Reset height if quiet variant
- this._onInput();
- }
-
- /** @private */
- _onInput() {
- if (this.variant === variant.QUIET) {
- requestAnimationFrame(() => {
- this.style.height = 'auto';
- this.style.height = `${this.scrollHeight}px`;
- });
- }
- }
-
- /**
- Returns {@link Textarea} variants.
-
- @return {TextareaVariantEnum}
- */
- static get variant() {
- return variant;
- }
-
- /** @ignore */
- static get observedAttributes() {
- return super._nativeObservedAttributes.concat(['variant']);
- }
-
- /** @ignore */
- render() {
- super.render();
-
- this.classList.add(CLASSNAME, `${CLASSNAME}--multiline`);
-
- // Default reflected attributes
- if (!this._variant) {
- this.variant = variant.DEFAULT;
- }
- }
- });
-
- export default Textarea;