UNPKG

@trimble-oss/moduswebcomponents

Version:

Modus Web Components is a modern, accessible UI library built with Stencil JS that provides reusable web components following Trimble's Modus design system. This updated version focuses on improved flexibility, enhanced theming options, comprehensive cust

558 lines (557 loc) 21.3 kB
import { h, Host, } from "@stencil/core"; import { convertPropsToClasses } from "./modus-wc-time-input.tailwind"; import { generateRandomId } from "../utils"; import { inheritAriaAttributes } from "../utils"; /** * A customizable input component used to create time inputs. */ export class ModusWcTimeInput { constructor() { this.inheritedAttributes = {}; /** Indicates that the input should have a border. */ this.bordered = true; /** Custom CSS class to apply to the input. */ this.customClass = ''; /** The options to display in the time input dropdown. Options must be in `HH:mm` or `HH:mm:ss` format. */ this.datalistOptions = []; /** Whether the form control is disabled. */ this.disabled = false; /** Whether the value is editable. */ this.readOnly = false; /** A value is required for the form to be submittable. */ this.required = false; /** * Displays the time input format as `HH:mm:ss` if `true`. * Internally sets the `step` to 1 second. * If a `step` value is provided, it will override this attribute. */ this.showSeconds = false; /** The size of the input. */ this.size = 'md'; /** * The value of the time input. * Always in 24-hour format that includes leading zeros: * `HH:mm` or `HH:mm:ss`, regardless of input format which is likely * to be selected based on user's locale (or by the user agent). * If time includes seconds the format is always `HH:mm:ss`. */ this.value = ''; this.handleBlur = (event) => { this.inputBlur.emit(event); }; this.handleFocus = (event) => { this.inputFocus.emit(event); }; this.handleInput = (event) => { this.inputChange.emit(event); }; /* * The ID of the internal <datalist> element. Unique to each instance of the time input component. * This is used as the `datalistId` id when `datalistOptions` are provided. */ this.internalDatalistId = `modus-wc-datalist-${generateRandomId(10)}`; } componentWillLoad() { if (!this.el.ariaLabel) { this.el.ariaLabel = 'Time input'; } // if no datalistId value provided, use internal datalist id to enable time options if (!this.datalistId) { this.datalistId = this.internalDatalistId; } this.inheritedAttributes = inheritAriaAttributes(this.el); } getClasses() { const classList = [ 'modus-wc-time-input', 'modus-wc-input', 'modus-wc-w-full', ]; const propClasses = convertPropsToClasses({ bordered: this.bordered, feedback: this.feedback, readOnly: this.readOnly, size: this.size, }); // The order CSS classes are added matters to CSS specificity if (propClasses) classList.push(propClasses); if (this.customClass) classList.push(this.customClass); return classList.join(' '); } /* * Conditionally renders the datalist element with the time options. * If no time options are provided or the datalistId prop is not the default, * the datalist element will not be rendered (returns `null`). */ renderDatalist() { if (this.datalistOptions.length === 0 || this.datalistId !== this.internalDatalistId) { return null; } return (h("datalist", { id: this.internalDatalistId }, this.datalistOptions.map((time) => (h("option", { value: time }))))); } render() { return (h(Host, { key: '8c8e1b589d39e62e9b83e316f9738aedc6ebf7b2' }, this.label && (h("modus-wc-input-label", { key: 'fc4cbc6467da2421f688a8741122135dc4c78446', forId: this.inputId, labelText: this.label, required: this.required, size: this.size })), h("input", Object.assign({ key: '9b09a9b1e50658d64e3641258c60c91a04593f81', "aria-required": this.required, autocomplete: this.autoComplete, class: this.getClasses(), disabled: this.disabled, id: this.inputId, list: this.datalistId, max: this.max, min: this.min, name: this.name, onBlur: this.handleBlur, onFocus: this.handleFocus, onInput: this.handleInput, readonly: this.readOnly, required: this.required, step: this.step || this.showSeconds ? 1 : 60, tabIndex: this.inputTabIndex, type: "time", value: this.value }, this.inheritedAttributes)), this.renderDatalist(), this.feedback && (h("modus-wc-input-feedback", { key: '34f1d83cf3e936002d100343510a6df1ca61fe0a', level: this.feedback.level, message: this.feedback.message, size: this.size })))); } static get is() { return "modus-wc-time-input"; } static get originalStyleUrls() { return { "$": ["modus-wc-time-input.scss"] }; } static get styleUrls() { return { "$": ["modus-wc-time-input.css"] }; } static get properties() { return { "autoComplete": { "type": "string", "attribute": "auto-complete", "mutable": false, "complexType": { "original": "'on' | 'off'", "resolved": "\"off\" | \"on\" | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Hint for form autofill feature." }, "getter": false, "setter": false, "reflect": false }, "bordered": { "type": "boolean", "attribute": "bordered", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Indicates that the input should have a border." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "true" }, "customClass": { "type": "string", "attribute": "custom-class", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Custom CSS class to apply to the input." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "''" }, "datalistOptions": { "type": "unknown", "attribute": "datalist-options", "mutable": false, "complexType": { "original": "string[]", "resolved": "string[]", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "The options to display in the time input dropdown. Options must be in `HH:mm` or `HH:mm:ss` format." }, "getter": false, "setter": false, "defaultValue": "[]" }, "disabled": { "type": "boolean", "attribute": "disabled", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Whether the form control is disabled." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "false" }, "feedback": { "type": "unknown", "attribute": "feedback", "mutable": false, "complexType": { "original": "IInputFeedbackProp", "resolved": "IInputFeedbackProp | undefined", "references": { "IInputFeedbackProp": { "location": "import", "path": "../types", "id": "src/components/types.ts::IInputFeedbackProp" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Feedback to render below the input." }, "getter": false, "setter": false }, "inputId": { "type": "string", "attribute": "input-id", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "The ID of the input element." }, "getter": false, "setter": false, "reflect": false }, "inputTabIndex": { "type": "number", "attribute": "input-tab-index", "mutable": false, "complexType": { "original": "number", "resolved": "number | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Determine the control's relative ordering for sequential focus navigation (typically with the Tab key)." }, "getter": false, "setter": false, "reflect": false }, "datalistId": { "type": "string", "attribute": "datalist-id", "mutable": true, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "ID of a `<datalist>` element that contains pre-defined time options.\nThe value must be the ID of a `<datalist>` element in the same document." }, "getter": false, "setter": false, "reflect": false }, "label": { "type": "string", "attribute": "label", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "The text to display within the label." }, "getter": false, "setter": false, "reflect": false }, "max": { "type": "string", "attribute": "max", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Maximum value. Format: `HH:mm`, `HH:mm:ss`." }, "getter": false, "setter": false, "reflect": false }, "min": { "type": "string", "attribute": "min", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Minimum value. Format: `HH:mm`, `HH:mm:ss.`" }, "getter": false, "setter": false, "reflect": false }, "name": { "type": "string", "attribute": "name", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Name of the form control. Submitted with the form as part of a name/value pair." }, "getter": false, "setter": false, "reflect": false }, "readOnly": { "type": "boolean", "attribute": "read-only", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Whether the value is editable." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "false" }, "required": { "type": "boolean", "attribute": "required", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "A value is required for the form to be submittable." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "false" }, "showSeconds": { "type": "boolean", "attribute": "show-seconds", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Displays the time input format as `HH:mm:ss` if `true`.\nInternally sets the `step` to 1 second.\nIf a `step` value is provided, it will override this attribute." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "false" }, "size": { "type": "string", "attribute": "size", "mutable": false, "complexType": { "original": "ModusSize", "resolved": "\"lg\" | \"md\" | \"sm\" | undefined", "references": { "ModusSize": { "location": "import", "path": "../types", "id": "src/components/types.ts::ModusSize" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "The size of the input." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "'md'" }, "step": { "type": "number", "attribute": "step", "mutable": false, "complexType": { "original": "number", "resolved": "number | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Specifies the granularity that the `value` must adhere to.\nValue of step given in seconds. Default value is 60 seconds.\nOverrides the `seconds` attribute if both are provided." }, "getter": false, "setter": false, "reflect": false }, "value": { "type": "string", "attribute": "value", "mutable": true, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "The value of the time input.\nAlways in 24-hour format that includes leading zeros:\n`HH:mm` or `HH:mm:ss`, regardless of input format which is likely\nto be selected based on user's locale (or by the user agent).\nIf time includes seconds the format is always `HH:mm:ss`." }, "getter": false, "setter": false, "reflect": true, "defaultValue": "''" } }; } static get events() { return [{ "method": "inputBlur", "name": "inputBlur", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Event emitted when the input loses focus." }, "complexType": { "original": "FocusEvent", "resolved": "FocusEvent", "references": { "FocusEvent": { "location": "global", "id": "global::FocusEvent" } } } }, { "method": "inputChange", "name": "inputChange", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Event emitted when the input value changes." }, "complexType": { "original": "Event", "resolved": "Event", "references": { "Event": { "location": "global", "id": "global::Event" } } } }, { "method": "inputFocus", "name": "inputFocus", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Event emitted when the input gains focus." }, "complexType": { "original": "FocusEvent", "resolved": "FocusEvent", "references": { "FocusEvent": { "location": "global", "id": "global::FocusEvent" } } } }]; } static get elementRef() { return "el"; } }