@duetds/components
Version:
This package includes Duet Core Components and related tools.
584 lines (583 loc) • 19.9 kB
JavaScript
import { Host, h } from "@stencil/core";
import { debounceEvent, createID } from "@duetds/js-utils";
export class DuetTextarea {
constructor() {
this.textareaId = createID("DuetTextarea");
this.labelId = createID("DuetLabel");
this.errorId = createID("DuetError");
/**
* Controls the margin of the component. Can be one of: "auto", "none".
*/
this.margin = "auto";
/**
* Set the amount of time, in milliseconds, to wait to trigger the duetChange event after each keystroke.
*/
this.debounce = 0;
/**
* Theme of the textarea. Can be one of: "default", "turva".
*/
this.theme = "";
/**
* Expands the textarea to fill 100% of the container width.
*/
this.expand = false;
/**
* Makes the textarea component disabled. This prevents users from being able to interact with the textarea, and conveys its inactive state to assistive technologies.
*/
this.disabled = false;
/**
* Set whether the textarea is required or not.
*/
this.required = false;
/**
* Label for the textarea.
*/
this.label = "label";
/**
* Visually hide the label, but still show it to screen readers.
*/
this.labelHidden = false;
/**
* Display the textarea in error state along with an error message.
*/
this.error = "";
/**
* Tooltip to display next to the label of the input.
*/
this.tooltip = "";
/**
* Component event handling.
*/
this.onInput = (ev) => {
const input = ev.target;
if (input) {
this.value = input.value || "";
}
this.duetInput.emit(ev);
};
this.onBlur = () => {
this.duetBlur.emit();
};
this.onFocus = () => {
this.duetFocus.emit();
};
}
debounceChanged() {
this.duetChange = debounceEvent(this.duetChange, this.debounce);
}
/**
* Update the native textarea element when the value changes
*/
valueChanged() {
this.duetChange.emit({
value: this.value,
component: "duet-textarea",
});
}
/**
* Component lifecycle events.
*/
componentWillLoad() {
if (this.theme !== "default" && document.documentElement.classList.contains("duet-theme-turva")) {
this.theme = "turva";
}
}
componentDidLoad() {
this.debounceChanged();
}
/**
* Sets focus on the specified `duet-textarea`. Use this method instead of the global
* `textarea.focus()`.
*/
async setFocus() {
const nativeInput = this.element.querySelector("textarea");
if (nativeInput) {
nativeInput.focus();
}
}
/**
* render() function
* Always the last one in the class.
*/
render() {
if (this.expand) {
this.element.classList.add("duet-expand");
}
const identifier = this.identifier || this.textareaId;
return (h(Host, { class: { "duet-m-0": this.margin === "none" } },
h("div", { class: {
"duet-textarea-container": true,
"duet-theme-turva": this.theme === "turva",
"duet-label-hidden": this.labelHidden,
"has-error": this.error !== "",
} },
h("duet-label", { theme: this.theme === "turva" ? "turva" : "default", id: this.labelId, for: identifier }, this.label),
this.tooltip !== "" ? h("duet-tooltip", null, this.tooltip) : "",
h("textarea", { onInput: this.onInput, onBlur: this.onBlur, onFocus: this.onFocus, class: { "duet-textarea": true, disabled: this.disabled }, value: this.value, disabled: this.disabled, "aria-labelledby": this.labelId + " " + this.errorId, "aria-controls": this.accessibleControls, "aria-autocomplete": this.accessibleAutocomplete, "aria-active-descendant": this.accessibleActiveDescendant, "aria-owns": this.accessibleOwns, placeholder: this.placeholder, spellcheck: "false", required: this.required, minlength: this.minlength, maxlength: this.maxlength, role: this.role, name: this.name, id: identifier }),
h("span", { class: "duet-textarea-help", id: this.errorId, "aria-live": "assertive", "aria-relevant": "additions removals" }, this.error !== "" ? h("span", null, this.error) : ""))));
}
static get is() { return "duet-textarea"; }
static get encapsulation() { return "scoped"; }
static get originalStyleUrls() { return {
"$": ["duet-textarea.scss"]
}; }
static get styleUrls() { return {
"$": ["duet-textarea.css"]
}; }
static get properties() { return {
"margin": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Controls the margin of the component. Can be one of: \"auto\", \"none\"."
},
"attribute": "margin",
"reflect": false,
"defaultValue": "\"auto\""
},
"accessibleActiveDescendant": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Indicates the id of a related component\u2019s visually focused element."
},
"attribute": "accessible-active-descendant",
"reflect": false
},
"accessibleAutocomplete": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Indicates what kind of user input completion suggestions are provided."
},
"attribute": "accessible-autocomplete",
"reflect": false
},
"accessibleControls": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Use this prop to add an aria-controls attribute. Use the attribute to indicate the id of a component controlled by this component."
},
"attribute": "accessible-controls",
"reflect": false
},
"accessibleOwns": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Indicates the id of a component owned by the textarea."
},
"attribute": "accessible-owns",
"reflect": false
},
"debounce": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Set the amount of time, in milliseconds, to wait to trigger the duetChange event after each keystroke."
},
"attribute": "debounce",
"reflect": false,
"defaultValue": "0"
},
"theme": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Theme of the textarea. Can be one of: \"default\", \"turva\"."
},
"attribute": "theme",
"reflect": false,
"defaultValue": "\"\""
},
"expand": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Expands the textarea to fill 100% of the container width."
},
"attribute": "expand",
"reflect": false,
"defaultValue": "false"
},
"disabled": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Makes the textarea component disabled. This prevents users from being able to interact with the textarea, and conveys its inactive state to assistive technologies."
},
"attribute": "disabled",
"reflect": true,
"defaultValue": "false"
},
"identifier": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Adds a unique identifier for the textarea."
},
"attribute": "identifier",
"reflect": false
},
"required": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Set whether the textarea is required or not."
},
"attribute": "required",
"reflect": false,
"defaultValue": "false"
},
"label": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Label for the textarea."
},
"attribute": "label",
"reflect": false,
"defaultValue": "\"label\""
},
"labelHidden": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Visually hide the label, but still show it to screen readers."
},
"attribute": "label-hidden",
"reflect": false,
"defaultValue": "false"
},
"name": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Name of the textarea."
},
"attribute": "name",
"reflect": false
},
"placeholder": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Hint text to display."
},
"attribute": "placeholder",
"reflect": false
},
"maxlength": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Use maxlength to specify the maximum length of the value that can be entered. Please note that this uses native HTML5 pattern validation."
},
"attribute": "maxlength",
"reflect": false
},
"minlength": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Use minlength to specify the minimum length of the value that can be entered. Please note that this uses native HTML5 pattern validation."
},
"attribute": "minlength",
"reflect": false
},
"error": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Display the textarea in error state along with an error message."
},
"attribute": "error",
"reflect": false,
"defaultValue": "\"\""
},
"role": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Defines a specific role attribute for the input."
},
"attribute": "role",
"reflect": false
},
"tooltip": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Tooltip to display next to the label of the input."
},
"attribute": "tooltip",
"reflect": false,
"defaultValue": "\"\""
},
"value": {
"type": "string",
"mutable": true,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Value of the textarea."
},
"attribute": "value",
"reflect": false
}
}; }
static get events() { return [{
"method": "duetInput",
"name": "duetInput",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Emitted when a keyboard input ocurred."
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "duetChange",
"name": "duetChange",
"bubbles": false,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Emitted when the value has changed."
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "duetBlur",
"name": "duetBlur",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Emitted when the input loses focus."
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "duetFocus",
"name": "duetFocus",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Emitted when the input has focus."
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}]; }
static get methods() { return {
"setFocus": {
"complexType": {
"signature": "() => Promise<void>",
"parameters": [],
"references": {
"Promise": {
"location": "global"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Sets focus on the specified `duet-textarea`. Use this method instead of the global\n`textarea.focus()`.",
"tags": []
}
}
}; }
static get elementRef() { return "element"; }
static get watchers() { return [{
"propName": "debounce",
"methodName": "debounceChanged"
}, {
"propName": "value",
"methodName": "valueChanged"
}]; }
}