@duetds/components
Version:
This package includes Duet Core Components and related tools.
481 lines (480 loc) • 16.9 kB
JavaScript
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"; }
}