// Mockup https://www.figma.com/design/zsq2ahat30acTnumyy9aqC/00.Small-System?node-id=1235-18586&m=dev import { LitElement, type TemplateResult, css, html, unsafeCSS } from "lit"; import { customElement, property } from "lit/decorators.js"; import { classMap } from "lit/directives/class-map.js"; import "~icons/mingcute/search-3-line"; import ComponentStyle from "@styles/forms/ui/tems-input-field.scss?inline"; export type TemsInputFieldProps = { disabled?: boolean; field: Element; icon?: TemplateResult; label?: string; name?: string; size: "sm" | "md" | "lg"; status: string | undefined; type: string; value?: string; }; @customElement("tems-input-field") export class TemsInputField extends LitElement { static styles = css` ${unsafeCSS(ComponentStyle)} `; @property({ attribute: "disabled", type: Boolean, reflect: true }) disabled: TemsInputFieldProps["disabled"]; @property({ type: Element }) field: TemsInputFieldProps["field"] = document.createElement("input"); @property({ attribute: false }) icon: TemsInputFieldProps["icon"]; @property({ attribute: "label", type: String, reflect: true }) label: TemsInputFieldProps["label"]; @property({ attribute: "name", type: String, reflect: true }) name: TemsInputFieldProps["name"] = ""; @property({ attribute: "size", type: String, reflect: true }) size: TemsInputFieldProps["size"] = "md"; @property({ attribute: "status", type: String, reflect: true }) status: TemsInputFieldProps["status"] = undefined; @property({ attribute: "type", type: String, reflect: true }) type: TemsInputFieldProps["type"] = "text"; @property({ attribute: "value", type: String, reflect: true }) value: TemsInputFieldProps["value"]; defaultIcon: TemplateResult | symbol = html``; _getSizeClasses() { const allowedSizes = ["sm", "md", "lg"]; if (this.size && !allowedSizes.includes(this.size)) { this.size = "md"; } return { sm: this.size === "sm", md: this.size === "md", lg: this.size === "lg", }; } private _timer: number | undefined; _updateInputValue(e: Event) { e.preventDefault(); if (this._timer) { clearTimeout(this._timer); } this._timer = window.setTimeout(() => { this.value = this.field.value; this._timer = undefined; this.dispatchEvent( new CustomEvent("change", { detail: { value: this.value, }, }), ); }, 100); } _updateStatus() { const status = this.status; if (typeof status === "string") { if (status === "true") { this.field._isValid = true; this.field.setCustomValidity(""); } else { this.field._isValid = false; this.field.setCustomValidity( status === "false" ? "Invalid value" : status, ); } this.field.classList.add("report-validity"); } else { this.field.classList.remove("report-validity"); } this.field.reportValidity(); } protected updated() { this.field.setAttribute("type", this.type); if (this.name) { this.field.setAttribute("name", this.name); } else { this.field.removeAttribute("name"); } if (this.label) { this.field.setAttribute("placeholder", this.label); } else { this.field.removeAttribute("placeholder"); } if (this.value) { this.field.setAttribute("value", this.value); this.field.value = this.value; } else { this.field.setAttribute("value", ""); this.field.value = ""; } if (this.disabled) { this.field.setAttribute("disabled", "true"); } else { this.field.removeAttribute("disabled"); } this._updateStatus(); this._adaptFieldOnUpdate(); } protected firstUpdated() { this.field.addEventListener("change", this._updateInputValue.bind(this)); } _adaptFieldOnUpdate() {} _renderInput() { return html`${ this.icon ? html`${this.icon}` : this.defaultIcon }${this.field}`; } render() { return html``; } }