// Mockup https://www.figma.com/design/zsq2ahat30acTnumyy9aqC/00.Small-System?node-id=908-9440&m=dev import { LitElement, css, html, unsafeCSS } from "lit"; import { customElement, property } from "lit/decorators.js"; import CheckboxSvgIcon from "~icons/heroicons-outline/check?raw"; import CheckboxStyle from "@styles/ui/checkbox.scss?inline"; export type TemsCheckboxProps = { type: string; size: "sm" | "md" | "xs"; status: string | undefined; value?: string; name?: string; checked: boolean; disabled: boolean; indeterminate?: boolean; field: Element; }; @customElement("tems-checkbox") export class TemsCheckbox extends LitElement { static styles = css` ${unsafeCSS(CheckboxStyle)} input:checked { background-image: url("data:image/svg+xml;base64,${unsafeCSS( btoa(CheckboxSvgIcon), )}"); } `; @property({ attribute: "type", type: String, reflect: true }) type: TemsCheckboxProps["type"] = "checkbox"; @property({ attribute: "value", type: String, reflect: true }) value: TemsCheckboxProps["value"]; @property({ attribute: "size", type: String, reflect: true }) size: TemsCheckboxProps["size"] = "sm"; @property({ attribute: "status", type: String, reflect: true }) status: TemsCheckboxProps["status"] = undefined; @property({ attribute: "name", type: String, reflect: true }) name: TemsCheckboxProps["name"] = ""; @property({ attribute: "checked", type: Boolean, reflect: true }) checked: TemsCheckboxProps["checked"] = false; @property({ attribute: "disabled", type: Boolean, reflect: true }) disabled: TemsCheckboxProps["disabled"] = false; @property({ attribute: "indeterminate", type: Boolean, reflect: true }) indeterminate: TemsCheckboxProps["indeterminate"]; @property({ type: Element }) field: TemsCheckboxProps["field"] = document.createElement("input"); _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(); } _updateCheckboxState(e: Event) { this.checked = e.target?.checked; if (this.type === "checkbox") { this.value = String(this.checked); } this.dispatchEvent( new CustomEvent("change", { detail: { value: this.checked, checked: e.target?.checked, }, }), ); } _getSizeClasses() { const allowedSizes = ["sm", "md", "xs"]; if (this.size && !allowedSizes.includes(this.size)) { this.size = "sm"; } return this.size; } protected updated() { if (this.type === "checkbox" && this.value === "true") { this.checked = true; } this.field.setAttribute("type", this.type); const classes = []; classes.push(this._getSizeClasses()); if (this.name) { this.field.setAttribute("name", this.name); } else { this.field.removeAttribute("name"); } if (this.value) { this.field.setAttribute("value", this.value); } else { this.field.removeAttribute("value"); } if (this.checked) { this.field.checked = true; this.field.setAttribute("checked", ""); } else { this.field.checked = false; this.field.removeAttribute("checked"); } if (this.disabled) { classes.push("disabled"); this.field.setAttribute("disabled", "true"); } else { this.field.removeAttribute("disabled"); } if (this.indeterminate) { this.field.indeterminate = true; } else { this.field.indeterminate = false; } this.field.setAttribute("class", classes.join(" ")); this._updateStatus(); } protected firstUpdated() { this.field.addEventListener("change", this._updateCheckboxState.bind(this)); } render() { return html``; } }