@postnord/web-components
Version:
PostNord Web Components
715 lines (714 loc) • 27.4 kB
JavaScript
/*!
* 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
}
}];
}
}