UNPKG

@postnord/web-components

Version:
715 lines (714 loc) 27.4 kB
/*! * Built with Stencil * By PostNord. */ import { Host, h } from "@stencil/core"; import { uuidv4 } from "../../../globals/helpers"; /** * The `pn-textarea` is built with a native `textarea`. * This means you can use native events to listen to the input. * * @nativeInput Use the `input` event to listen to content being modified by the user. * * @slot helpertext - You can use this slot instead of the prop `helpertext`. Recommended, only if you need to include additional HTML markup. Such as a `pn-text-link`. Use a `span` element to wrap the text and link. {@since v7.25.0} * @slot error - You can use this slot instead of the prop `error`. Recommended, only if you need to include additional HTML markup. Such as a `pn-text-link`. Use a `span` element to wrap the text and link. {@since v7.25.0} */ export class PnTextarea { id = `pn-textarea-${uuidv4()}`; idHelper = `${this.id}-text`; idError = `${this.id}-error`; hostElement; /** The label describing the textarea. */ label; /** Helper text that will appear underneath the textarea. Will be overwritten if you set an `error` string */ helpertext; /** The textarea content, do not provide slotted content. @category Native attributes */ value = ''; /** HTML name. @category Native attributes */ name; /** Placeholder for the textarea. @category Native attributes */ placeholder; /** Set the associated form. @category Native attributes */ form; /** Set the row count for the textarea. @category Native attributes */ rows = 2; /** Set the col count for the textarea. @category Native attributes */ cols = 20; /** Set the wrap control. @category Native attributes */ wrap = 'soft'; /** The maximum number of characters the user should be able to add, also adds a visible counter. @category Native attributes */ maxlength; /** Allow the browser to autocomplete the textarea. @category Native attributes */ autocomplete = 'off'; /** Allow the browser to spellcheck the textarea. @category Native attributes */ spellcheck = false; /** Allow the user to resize the textarea vertically. Handle width in your own layout. @category Native attributes */ resize = false; /** Make the textarea required. @category Native attributes */ required = false; /** Disable the textarea. @category Native attributes */ disabled = false; /** Make the textarea readonly. @category Native attributes */ readonly = false; /** Use the compact label variant. @since v7.21.0 @category Features */ compact = false; /** Set the textarea as `valid`, will make the Label and focus rings green. @category Features */ valid = false; /** Set the textarea as `invalid`, will make the Label and focus rings red. @category Features */ invalid = false; /** Same as `invalid`, but will display the string as an error message under the textarea. @category Features */ error; /** Set a custom ID for the textarea. @since v7.25.0 @category HTML attributes */ pnId; /** * Provide the label via an aria attribute. * We strongly recommend you use the `label` prop instead. * @since v7.25.0 * @category HTML attributes */ pnAriaLabel; /** * Provide the label from another element via its ID. * We strongly recommend you use the `label` prop instead. * @since v7.25.0 * @category HTML attributes */ pnAriaLabelledby; /** Set a custom ID for the textarea. @deprecated Use `pn-id` instead. @category HTML attributes */ textareaid; handleId() { this.idHelper = `${this.getId()}-helpertext`; this.idError = `${this.getId()}-error`; } setVal(event) { const value = event.target.value; this.value = value; } hasHelperText() { return this.helpertext?.length > 0 || this.checkSlottedHelper(); } /** If any `error` text is present, either via prop/slot. */ hasErrorMessage() { return this.error?.length > 0 || this.checkSlottedError(); } /** If any `error` is active, either via the prop `invalid` or `error` prop/slot. */ hasError() { return this.hasErrorMessage() || this.invalid || this.checkSlottedError(); } checkSlottedHelper() { return !!this.hostElement.querySelector('[slot=helpertext]'); } checkSlottedError() { return !!this.hostElement.querySelector('[slot=error]'); } hideHelpertext() { return this.hasErrorMessage() || !this.hasHelperText(); } hideError() { return !this.hasErrorMessage(); } getId() { return this.pnId || this.textareaid || this.id; } displayLabel() { return !!this.label; } getAriaLabel() { return !this.displayLabel() && !this.pnAriaLabelledby ? this.pnAriaLabel : null; } getAriaLabelledby() { return !this.displayLabel() && !this.pnAriaLabel ? this.pnAriaLabelledby : null; } getAriaDescribedby() { const list = []; if (this.hasErrorMessage()) list.push(this.idError); else if (this.hasHelperText()) list.push(this.idHelper); return list.length ? list.join(' ') : null; } renderLabel() { return (h("label", { class: "pn-textarea-label", htmlFor: this.getId(), "data-compact": this.compact }, h("span", null, this.label), this.maxlength >= 1 && h("span", null, `${this.value?.length || 0}/${this.maxlength}`))); } render() { return (h(Host, { key: '30ea927b4d57c041164f7ccfd052121d3723591b' }, h("div", { key: '2c927468a5159cd2544af2bd351df2b45a5abf55', class: "pn-textarea", "data-valid": this.valid, "data-error": this.hasError(), "data-resize": this.resize }, !this.compact && this.renderLabel(), h("textarea", { key: '2f933bd8e3477c3f7010d676f4fde0f49e2ebc9e', class: "pn-textarea-element", id: this.getId(), value: this.value, name: this.name, placeholder: this.compact ? this.placeholder || ' ' : this.placeholder, rows: this.rows, cols: this.cols, wrap: this.wrap, autocomplete: this.autocomplete, spellcheck: this.spellcheck, maxlength: this.maxlength, required: this.required, disabled: this.disabled, readonly: this.readonly, "aria-label": this.getAriaLabel(), "aria-labelledby": this.getAriaLabelledby(), "aria-describedby": this.getAriaDescribedby(), "aria-invalid": this.hasError().toString(), "data-compact": this.compact, onInput: e => this.setVal(e) }), this.compact && this.renderLabel(), h("p", { key: '368de1a346ca5161b8e6da6170453cd68605e92c', id: this.idHelper, class: "pn-textarea-text", hidden: this.hideHelpertext() }, h("span", { key: '055d5ea03484c61e64bb674bad2a8bc5bffb253e' }, this.helpertext), h("slot", { key: '3782f2b397e46f3dd8e0d4253b1071b1d98ffb65', name: "helpertext" })), h("p", { key: '7a092d28df13950e4fba9e4df46c8e6176a70ae3', id: this.idError, class: "pn-textarea-text", role: "alert", hidden: this.hideError() }, h("span", { key: '49ef6664c21f2a4281dd8f8919cfa0d66d7554fb' }, this.error), h("slot", { key: '51819bfeff00a85706a4c60de35926e65e3cd22d', name: "error" }))))); } static get is() { return "pn-textarea"; } static get originalStyleUrls() { return { "$": ["pn-textarea.scss"] }; } static get styleUrls() { return { "$": ["pn-textarea.css"] }; } static get properties() { return { "label": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "The label describing the textarea." }, "getter": false, "setter": false, "reflect": false, "attribute": "label" }, "helpertext": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Helper text that will appear underneath the textarea. Will be overwritten if you set an `error` string" }, "getter": false, "setter": false, "reflect": false, "attribute": "helpertext" }, "value": { "type": "string", "mutable": true, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "The textarea content, do not provide slotted content." }, "getter": false, "setter": false, "reflect": false, "attribute": "value", "defaultValue": "''" }, "name": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "HTML name." }, "getter": false, "setter": false, "reflect": false, "attribute": "name" }, "placeholder": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "Placeholder for the textarea." }, "getter": false, "setter": false, "reflect": false, "attribute": "placeholder" }, "form": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "Set the associated form." }, "getter": false, "setter": false, "reflect": false, "attribute": "form" }, "rows": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "Set the row count for the textarea." }, "getter": false, "setter": false, "reflect": false, "attribute": "rows", "defaultValue": "2" }, "cols": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "Set the col count for the textarea." }, "getter": false, "setter": false, "reflect": false, "attribute": "cols", "defaultValue": "20" }, "wrap": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "Set the wrap control." }, "getter": false, "setter": false, "reflect": false, "attribute": "wrap", "defaultValue": "'soft'" }, "maxlength": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "The maximum number of characters the user should be able to add, also adds a visible counter." }, "getter": false, "setter": false, "reflect": false, "attribute": "maxlength" }, "autocomplete": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "Allow the browser to autocomplete the textarea." }, "getter": false, "setter": false, "reflect": false, "attribute": "autocomplete", "defaultValue": "'off'" }, "spellcheck": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "Allow the browser to spellcheck the textarea." }, "getter": false, "setter": false, "reflect": false, "attribute": "spellcheck", "defaultValue": "false" }, "resize": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "Allow the user to resize the textarea vertically. Handle width in your own layout." }, "getter": false, "setter": false, "reflect": false, "attribute": "resize", "defaultValue": "false" }, "required": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "Make the textarea required." }, "getter": false, "setter": false, "reflect": false, "attribute": "required", "defaultValue": "false" }, "disabled": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "Disable the textarea." }, "getter": false, "setter": false, "reflect": false, "attribute": "disabled", "defaultValue": "false" }, "readonly": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Native attributes" }], "text": "Make the textarea readonly." }, "getter": false, "setter": false, "reflect": false, "attribute": "readonly", "defaultValue": "false" }, "compact": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "since", "text": "v7.21.0" }, { "name": "category", "text": "Features" }], "text": "Use the compact label variant." }, "getter": false, "setter": false, "reflect": false, "attribute": "compact", "defaultValue": "false" }, "valid": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Features" }], "text": "Set the textarea as `valid`, will make the Label and focus rings green." }, "getter": false, "setter": false, "reflect": false, "attribute": "valid", "defaultValue": "false" }, "invalid": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Features" }], "text": "Set the textarea as `invalid`, will make the Label and focus rings red." }, "getter": false, "setter": false, "reflect": false, "attribute": "invalid", "defaultValue": "false" }, "error": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Features" }], "text": "Same as `invalid`, but will display the string as an error message under the textarea." }, "getter": false, "setter": false, "reflect": false, "attribute": "error" }, "pnId": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "since", "text": "v7.25.0" }, { "name": "category", "text": "HTML attributes" }], "text": "Set a custom ID for the textarea." }, "getter": false, "setter": false, "reflect": false, "attribute": "pn-id" }, "pnAriaLabel": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "since", "text": "v7.25.0" }, { "name": "category", "text": "HTML attributes" }], "text": "Provide the label via an aria attribute.\nWe strongly recommend you use the `label` prop instead." }, "getter": false, "setter": false, "reflect": false, "attribute": "pn-aria-label" }, "pnAriaLabelledby": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "since", "text": "v7.25.0" }, { "name": "category", "text": "HTML attributes" }], "text": "Provide the label from another element via its ID.\nWe strongly recommend you use the `label` prop instead." }, "getter": false, "setter": false, "reflect": false, "attribute": "pn-aria-labelledby" }, "textareaid": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "deprecated", "text": "Use `pn-id` instead." }, { "name": "category", "text": "HTML attributes" }], "text": "Set a custom ID for the textarea." }, "getter": false, "setter": false, "reflect": false, "attribute": "textareaid" } }; } static get elementRef() { return "hostElement"; } static get watchers() { return [{ "propName": "textareaid", "methodName": "handleId" }, { "propName": "pnId", "methodName": "handleId", "handlerOptions": { "immediate": true } }]; } }