UNPKG

@duetds/components

Version:

This package includes Duet Core Components and related tools.

481 lines (480 loc) 16.9 kB
import { Host, h } from "@stencil/core"; import { createID } from "@duetds/js-utils"; export class DuetSelect { constructor() { this.selectId = createID("DuetSelect"); this.errorId = createID("DuetError"); this.labelId = createID("DuetLabel"); /** * Controls the margin of the component. Can be one of: "auto", "none". */ this.margin = "auto"; /** * Display the select in error state along with an error message. */ this.error = ""; /** * Expands the input to fill 100% of the container width. */ this.expand = false; /** * Theme of the select. Can be one of: "default", "turva". */ this.theme = ""; /** * Visually hide the label, but still show it to screen readers. */ this.labelHidden = false; /** * Makes the select component disabled. This prevents users from being able to interact with the select, and conveys its inactive state to assistive technologies. */ this.disabled = false; /** * Label for the select. */ this.label = "label"; /** * Tooltip to display next to the label of the input. */ this.tooltip = ""; /** * Component event handling. */ this.onClick = (ev) => { ev.stopPropagation(); }; this.onChange = event => { const selectedOption = this.element.querySelector("select").value; this.value = selectedOption; this.duetChange.emit({ originalEvent: event, value: this.value, component: "duet-select", }); }; this.onFocus = () => { this.duetFocus.emit(); }; this.onBlur = () => { this.duetBlur.emit(); }; } valueChanged(event) { this.duetChange.emit({ originalEvent: event, value: this.value, component: "duet-select", }); } /** * Component lifecycle events. */ componentWillLoad() { if (this.theme !== "default" && document.documentElement.classList.contains("duet-theme-turva")) { this.theme = "turva"; } } getSelectedItemLabel() { if (!this.hasValidItems()) { return ""; } const item = this.items.find(item => item["value"] + "" === this.value); if (!item) { return ""; } return item["label"]; } hasValidItems() { return Array.isArray(this.items); } /** * Sets focus on the specified `duet-select`. Use this method instead of the global * `select.focus()`. */ async setFocus() { const nativeInput = this.element.querySelector("select"); 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.selectId; const currentValue = "" + this.value; return (h(Host, { onClick: this.onClick, class: { "duet-m-0": this.margin === "none" } }, h("div", { class: { "duet-select-container": true, "duet-label-hidden": this.labelHidden, "duet-theme-turva": this.theme === "turva", "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("div", { class: "duet-select-wrapper" }, h("select", { disabled: this.disabled, name: this.name, id: identifier, role: this.role, "aria-labelledby": this.labelId + " " + this.errorId, "aria-controls": this.accessibleControls, "aria-active-descendant": this.accessibleActiveDescendant, "aria-owns": this.accessibleOwns, onFocus: this.onFocus, onBlur: this.onBlur, onChange: this.onChange }, !this.hasValidItems() ? (h("option", null, "No options available")) : (this.items.map((item) => (h("option", { value: item["value"], selected: currentValue === item["value"] ? true : false }, item["label"]))))), h("div", { class: "duet-select", "aria-hidden": "true" }, this.getSelectedItemLabel(), h("svg", { role: "img", class: "duet-select-icon", fill: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, h("path", { d: "m12 18.999c-.4 0-.776-.156-1.059-.438l-10.721-10.72c-.142-.142-.22-.33-.22-.531 0-.2.078-.389.22-.53.142-.142.33-.22.53-.22s.389.078.53.22l10.72 10.719 10.72-10.719c.142-.142.33-.22.53-.22s.389.078.53.22c.142.142.22.33.22.53s-.078.389-.22.53l-10.72 10.72c-.282.283-.659.439-1.06.439z" })))), h("span", { class: "duet-select-help", id: this.errorId, "aria-live": "assertive", "aria-relevant": "additions removals" }, this.error !== "" ? h("span", null, this.error) : "")))); } static get is() { return "duet-select"; } static get encapsulation() { return "scoped"; } static get originalStyleUrls() { return { "$": ["duet-select.scss"] }; } static get styleUrls() { return { "$": ["duet-select.css"] }; } static get properties() { return { "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 }, "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\"" }, "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 select." }, "attribute": "accessible-owns", "reflect": false }, "error": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Display the select in error state along with an error message." }, "attribute": "error", "reflect": false, "defaultValue": "\"\"" }, "expand": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Expands the input to fill 100% of the container width." }, "attribute": "expand", "reflect": false, "defaultValue": "false" }, "value": { "type": "string", "mutable": true, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "The selected value of the select" }, "attribute": "value", "reflect": true }, "theme": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Theme of the select. Can be one of: \"default\", \"turva\"." }, "attribute": "theme", "reflect": false, "defaultValue": "\"\"" }, "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" }, "identifier": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Adds a unique identifier for the select." }, "attribute": "identifier", "reflect": false }, "name": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Name of the select." }, "attribute": "name", "reflect": false }, "items": { "type": "unknown", "mutable": false, "complexType": { "original": "any[]", "resolved": "any[]", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "An array of items to choose from" } }, "disabled": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Makes the select component disabled. This prevents users from being able to interact with the select, and conveys its inactive state to assistive technologies." }, "attribute": "disabled", "reflect": true, "defaultValue": "false" }, "label": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Label for the select." }, "attribute": "label", "reflect": false, "defaultValue": "\"label\"" }, "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 select." }, "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": "\"\"" } }; } static get events() { return [{ "method": "duetChange", "name": "duetChange", "bubbles": false, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Callback for when the value changed." }, "complexType": { "original": "any", "resolved": "any", "references": {} } }, { "method": "duetFocus", "name": "duetFocus", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted when the select has focus." }, "complexType": { "original": "any", "resolved": "any", "references": {} } }, { "method": "duetBlur", "name": "duetBlur", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted when the select loses 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-select`. Use this method instead of the global\n`select.focus()`.", "tags": [] } } }; } static get elementRef() { return "element"; } }