UNPKG

@scania/tegel

Version:
754 lines (753 loc) 30.4 kB
import { h } from "@stencil/core"; import hasSlot from "../../utils/hasSlot"; import generateUniqueId from "../../utils/generateUniqueId"; import { getAriaInvalid } from "../../utils/getAriaInvalid"; /** * @slot prefix - Slot for the prefix in the component. * @slot suffix - Slot for the suffix in the component. Suffix is hidden when the input is in readonly state. */ export class TdsTextField { constructor() { this.uuid = generateUniqueId(); /** Which input type, text, password or similar */ this.type = 'text'; /** Position of the label for the Text Field. */ this.labelPosition = 'no-label'; /** Label text */ this.label = ''; /** Placeholder text */ this.placeholder = ''; /** Value of the input text */ this.value = ''; /** Set input in disabled state */ this.disabled = false; /** Set input in readonly state */ this.readOnly = false; /** Hides the read-only icon in the Text Field. Requires Read Only to be enabled. */ this.hideReadOnlyIcon = false; /** Size of the input */ this.size = 'lg'; /** Mode variant of the Text Field */ this.modeVariant = null; /** Unset minimum width of 208px. */ this.noMinWidth = false; /** Name property */ this.name = ''; /** Error state of input */ this.state = 'default'; /** Autofocus for input */ this.autofocus = false; /** Makes the text field required */ this.required = false; /** Value to be used for the text field's autocomplete attribute */ this.autocomplete = 'off'; /** Hides the native arrows on number input type */ this.hideNumberArrows = false; /** Listen to the focus state of the input */ this.focusInput = false; } handleChange(event) { this.tdsChange.emit(event); } /** Data input event in value prop */ handleInput(event) { const inputEl = event.target; const { value } = inputEl; this.value = value; this.tdsInput.emit(event); } /** Set the input as focus when clicking the whole Text Field with suffix/prefix */ handleFocus(event) { var _a; (_a = this.textInput) === null || _a === void 0 ? void 0 : _a.focus(); this.focusInput = true; this.tdsFocus.emit(event); } /** Set the input as focus when clicking the whole Text Field with suffix/prefix */ handleBlur(event) { this.focusInput = false; /** Custom handling of number inputs when min/max are set */ if (this.type === 'number' && this.textInput) { const numericValue = this.textInput.valueAsNumber; const minNum = this.min !== undefined ? Number(this.min) : undefined; const maxNum = this.max !== undefined ? Number(this.max) : undefined; if (minNum !== undefined && maxNum !== undefined && minNum > maxNum) { console.warn('tds-text-field: min value is greater than max value'); return; } if (!isNaN(numericValue)) { const originalValue = this.textInput.value; let clampedValue = originalValue; let clampReason = null; if (minNum !== undefined && numericValue < minNum) { clampedValue = String(this.min); clampReason = 'min'; } if (maxNum !== undefined && numericValue > maxNum) { clampedValue = String(this.max); clampReason = 'max'; } if (clampedValue !== originalValue && clampReason) { this.textInput.value = clampedValue; this.value = clampedValue; this.tdsError.emit({ originalValue, clampedValue, reason: clampReason, }); } } } this.tdsBlur.emit(event); } /** Method to handle focus */ async focusElement() { if (this.textInput) { this.textInput.focus(); } } render() { var _a, _b, _c, _d; const usesPrefixSlot = hasSlot('prefix', this.host); const usesSuffixSlot = hasSlot('suffix', this.host); return (h("div", { key: 'f16b01caa6aab76ff91b1bbd339726bc091073b4', class: { 'form-text-field': true, 'form-text-field-nomin': this.noMinWidth, 'text-field-focus': this.focusInput && !this.disabled, 'text-field-data': this.value !== '' && this.value !== null, 'text-field-container-label-inside': this.labelPosition === 'inside' && this.size !== 'sm', 'form-text-field-disabled': this.disabled, 'form-text-field-readonly': this.disabled ? false : this.readOnly, 'tds-mode-variant-primary': this.readOnly ? this.modeVariant === 'secondary' : this.modeVariant === 'primary', 'tds-mode-variant-secondary': this.readOnly ? this.modeVariant === 'primary' : this.modeVariant === 'secondary', 'form-text-field-md': this.size === 'md', 'form-text-field-sm': this.size === 'sm', 'form-text-field-error': this.state === 'error', 'form-text-field-success': this.state === 'success', } }, this.labelPosition === 'outside' && (h("div", { key: '05a6ee014f2d3e6e4394050423282d18cf5908b0', class: "text-field-label-outside" }, h("label", { key: 'cf3b333f2a898c048a1d456c6b7f6c65390615f0', htmlFor: `text-field-input-element-${this.uuid}` }, this.label))), h("div", { key: 'fc4a03cf20e81fa191ba536d2b79a0f1b0c535dd', onClick: () => { var _a; return (_a = this.textInput) === null || _a === void 0 ? void 0 : _a.focus(); }, class: "text-field-container" }, usesPrefixSlot && (h("div", { key: '3638c5a1acde4ad2eabc403d74a551d6185985a8', class: { 'text-field-slot-wrap-prefix': true, 'text-field-error': this.state === 'error', 'text-field-success': this.state === 'success', 'text-field-default': this.state === 'default', } }, h("slot", { key: 'aa86f986720a076698b3193009eb8ebc5022e531', name: "prefix" }))), h("div", { key: '5b884728b755f3c604b233f706da028dc12ab0f8', class: "text-field-input-container" }, h("input", { key: 'a04b70515c8ea73d3435292249fb3aea9a43663a', ref: (inputEl) => { this.textInput = inputEl; }, class: { 'text-field-input': true, 'text-field-input-sm': this.size === 'sm', 'text-field-input-md': this.size === 'md', 'text-field-input-lg': this.size === 'lg', 'text-field-input-no-arrows': this.hideNumberArrows, }, type: this.type, disabled: this.disabled, readonly: this.disabled ? false : this.readOnly, placeholder: this.placeholder, value: this.value, autofocus: this.autofocus, maxlength: this.maxLength, name: this.name, min: this.min, max: this.max, step: this.step, onInput: (event) => this.handleInput(event), onChange: (event) => this.handleChange(event), onFocus: (event) => { if (!this.readOnly) { this.handleFocus(event); } }, onBlur: (event) => { if (!this.readOnly) { this.handleBlur(event); } }, "aria-invalid": getAriaInvalid(this.host, this.state), "aria-label": this.tdsAriaLabel ? this.tdsAriaLabel : this.label, "aria-describedby": `text-field-helper-element-${this.uuid}`, "aria-readonly": this.readOnly, id: `text-field-input-element-${this.uuid}`, required: this.required, autocomplete: this.autocomplete }), this.labelPosition === 'inside' && this.size !== 'sm' && (h("label", { key: '2b4adf151e255ac983027b61b43f18e81399f11a', class: "text-field-label-inside", htmlFor: `text-field-input-element-${this.uuid}` }, this.label))), usesSuffixSlot && (h("div", { key: '70fccd2b3ffcab91b2537ef1512d2bbe86c4a1e5', class: { 'text-field-slot-wrap-suffix': true, 'text-field-error': this.state === 'error', 'text-field-success': this.state === 'success', 'text-field-default': this.state === 'default', 'tds-u-display-none': this.readOnly, } }, h("slot", { key: '631a64c5239415bbf8449e90d046a3a2eb8fdf3c', name: "suffix" }))), this.readOnly && !this.hideReadOnlyIcon && (h("span", { key: '975a0d8877d271c45c6b5f210537b11b5b70004e', class: "text-field-icon__readonly" }, h("tds-tooltip", { key: 'e0aa565b62e640afcf13f270187269dbe79b9a48', placement: "top-end", text: "This field is non-editable", selector: "#readonly-tooltip" }), h("tds-icon", { key: '9dadaaa674e0ef4f47e24889ff9e418e7ff3a168', id: "readonly-tooltip", name: "edit_inactive", size: "20px" })))), h("div", { key: '787ae2f6f83ff667885adec7b30ac31c3d99a8e4', "aria-live": "assertive" }, (this.helper || ((_a = this.maxLength) !== null && _a !== void 0 ? _a : 0) > 0) && (h("div", { key: 'f655beff3ed7f0a3441c790fce325ce830770707', class: "text-field-helper", id: `text-field-helper-element-${this.uuid}` }, this.state === 'error' && (h("div", { key: '1e2ec411ebb607637b0584a54c1c19ff6d0e031e', class: "text-field-helper-error-state" }, !this.readOnly && h("tds-icon", { key: 'ce34402f70808ab965669863d46c9d84fb66609d', name: "error", size: "16px" }), this.helper)), this.state !== 'error' && this.helper, !this.readOnly && ((_b = this.maxLength) !== null && _b !== void 0 ? _b : 0) > 0 && (h("span", { key: '17945ce6d01531279d561fc2115cc8461b59b6ea', class: { 'text-field-textcounter-divider': true, 'text-field-textcounter-disabled': this.disabled, } }, this.value === null ? 0 : (_c = this.value) === null || _c === void 0 ? void 0 : _c.length, " / ", (_d = this.maxLength) !== null && _d !== void 0 ? _d : 0))))))); } static get is() { return "tds-text-field"; } static get encapsulation() { return "scoped"; } static get originalStyleUrls() { return { "$": ["text-field.scss"] }; } static get styleUrls() { return { "$": ["text-field.css"] }; } static get properties() { return { "type": { "type": "string", "mutable": false, "complexType": { "original": "'text' | 'password' | 'number' | 'email' | 'tel'", "resolved": "\"email\" | \"number\" | \"password\" | \"tel\" | \"text\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Which input type, text, password or similar" }, "getter": false, "setter": false, "reflect": true, "attribute": "type", "defaultValue": "'text'" }, "labelPosition": { "type": "string", "mutable": false, "complexType": { "original": "'inside' | 'outside' | 'no-label'", "resolved": "\"inside\" | \"no-label\" | \"outside\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Position of the label for the Text Field." }, "getter": false, "setter": false, "reflect": false, "attribute": "label-position", "defaultValue": "'no-label'" }, "label": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Label text" }, "getter": false, "setter": false, "reflect": false, "attribute": "label", "defaultValue": "''" }, "min": { "type": "any", "mutable": false, "complexType": { "original": "string | number", "resolved": "number | string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Min allowed value for input type number" }, "getter": false, "setter": false, "reflect": false, "attribute": "min" }, "max": { "type": "any", "mutable": false, "complexType": { "original": "string | number", "resolved": "number | string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Max allowed value for input type number" }, "getter": false, "setter": false, "reflect": false, "attribute": "max" }, "step": { "type": "any", "mutable": false, "complexType": { "original": "string | number", "resolved": "number | string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Step value for input type number" }, "getter": false, "setter": false, "reflect": false, "attribute": "step" }, "helper": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Helper text" }, "getter": false, "setter": false, "reflect": false, "attribute": "helper" }, "placeholder": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Placeholder text" }, "getter": false, "setter": false, "reflect": false, "attribute": "placeholder", "defaultValue": "''" }, "value": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Value of the input text" }, "getter": false, "setter": false, "reflect": true, "attribute": "value", "defaultValue": "''" }, "disabled": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Set input in disabled state" }, "getter": false, "setter": false, "reflect": false, "attribute": "disabled", "defaultValue": "false" }, "readOnly": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Set input in readonly state" }, "getter": false, "setter": false, "reflect": false, "attribute": "read-only", "defaultValue": "false" }, "hideReadOnlyIcon": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Hides the read-only icon in the Text Field. Requires Read Only to be enabled." }, "getter": false, "setter": false, "reflect": false, "attribute": "hide-read-only-icon", "defaultValue": "false" }, "size": { "type": "string", "mutable": false, "complexType": { "original": "'sm' | 'md' | 'lg'", "resolved": "\"lg\" | \"md\" | \"sm\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Size of the input" }, "getter": false, "setter": false, "reflect": false, "attribute": "size", "defaultValue": "'lg'" }, "modeVariant": { "type": "string", "mutable": false, "complexType": { "original": "'primary' | 'secondary' | null", "resolved": "\"primary\" | \"secondary\" | null", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Mode variant of the Text Field" }, "getter": false, "setter": false, "reflect": false, "attribute": "mode-variant", "defaultValue": "null" }, "noMinWidth": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Unset minimum width of 208px." }, "getter": false, "setter": false, "reflect": false, "attribute": "no-min-width", "defaultValue": "false" }, "name": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Name property" }, "getter": false, "setter": false, "reflect": false, "attribute": "name", "defaultValue": "''" }, "state": { "type": "string", "mutable": false, "complexType": { "original": "'error' | 'success' | 'default'", "resolved": "\"default\" | \"error\" | \"success\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Error state of input" }, "getter": false, "setter": false, "reflect": false, "attribute": "state", "defaultValue": "'default'" }, "maxLength": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Max length of input" }, "getter": false, "setter": false, "reflect": false, "attribute": "max-length" }, "autofocus": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Autofocus for input" }, "getter": false, "setter": false, "reflect": false, "attribute": "autofocus", "defaultValue": "false" }, "tdsAriaLabel": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Value to be used for the aria-label attribute. Can be used for announcing that readOnly prop is set to true." }, "getter": false, "setter": false, "reflect": false, "attribute": "tds-aria-label" }, "required": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Makes the text field required" }, "getter": false, "setter": false, "reflect": false, "attribute": "required", "defaultValue": "false" }, "autocomplete": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Value to be used for the text field's autocomplete attribute" }, "getter": false, "setter": false, "reflect": false, "attribute": "autocomplete", "defaultValue": "'off'" }, "hideNumberArrows": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Hides the native arrows on number input type" }, "getter": false, "setter": false, "reflect": false, "attribute": "hide-number-arrows", "defaultValue": "false" } }; } static get states() { return { "focusInput": {} }; } static get events() { return [{ "method": "tdsChange", "name": "tdsChange", "bubbles": true, "cancelable": false, "composed": true, "docs": { "tags": [], "text": "Change event for the Text Field" }, "complexType": { "original": "any", "resolved": "any", "references": {} } }, { "method": "tdsInput", "name": "tdsInput", "bubbles": true, "cancelable": false, "composed": true, "docs": { "tags": [], "text": "Input event for the Text Field" }, "complexType": { "original": "InputEvent", "resolved": "InputEvent", "references": { "InputEvent": { "location": "global", "id": "global::InputEvent" } } } }, { "method": "tdsFocus", "name": "tdsFocus", "bubbles": true, "cancelable": false, "composed": true, "docs": { "tags": [], "text": "Focus event for the Text Field" }, "complexType": { "original": "FocusEvent", "resolved": "FocusEvent", "references": { "FocusEvent": { "location": "global", "id": "global::FocusEvent" } } } }, { "method": "tdsBlur", "name": "tdsBlur", "bubbles": true, "cancelable": false, "composed": true, "docs": { "tags": [], "text": "Blur event for the Text Field" }, "complexType": { "original": "FocusEvent", "resolved": "FocusEvent", "references": { "FocusEvent": { "location": "global", "id": "global::FocusEvent" } } } }, { "method": "tdsError", "name": "tdsError", "bubbles": true, "cancelable": false, "composed": true, "docs": { "tags": [], "text": "Error event for the Text Field - emitted when value is clamped to min/max" }, "complexType": { "original": "{ originalValue: string; clampedValue: string; reason: 'min' | 'max' }", "resolved": "{ originalValue: string; clampedValue: string; reason: \"min\" | \"max\"; }", "references": {} } }]; } static get methods() { return { "focusElement": { "complexType": { "signature": "() => Promise<void>", "parameters": [], "references": { "Promise": { "location": "global", "id": "global::Promise" } }, "return": "Promise<void>" }, "docs": { "text": "Method to handle focus", "tags": [] } } }; } static get elementRef() { return "host"; } }