import { LitElement, PropertyValues, html, nothing } from "lit"; import { customElement, property } from "lit/decorators.js"; import { translateText } from "../Utils"; const ACTIVE_CARD = "bg-blue-500/20 border-blue-500/50 shadow-[0_0_15px_rgba(59,130,246,0.2)]"; const INACTIVE_CARD = "bg-white/5 border-white/10 hover:bg-white/10 hover:border-white/20"; const INPUT_CLASS = "w-full text-center rounded bg-black/60 text-white text-sm font-bold border border-white/20 focus:outline-none focus:border-blue-500 p-1 my-1"; const CARD_LABEL_CLASS = "text-xs uppercase font-bold tracking-wider leading-tight break-words hyphens-auto"; function cardClass(active: boolean, extra = ""): string { return `w-full h-full rounded-xl border cursor-pointer transition-all duration-200 active:scale-95 ${extra} ${active ? ACTIVE_CARD : INACTIVE_CARD}`; } @customElement("toggle-input-card") export class ToggleInputCard extends LitElement { @property({ attribute: false }) labelKey = ""; @property({ type: Boolean, attribute: false }) checked = false; @property({ attribute: false }) inputId?: string; @property({ attribute: false }) inputType = "number"; @property({ attribute: false }) inputMin?: number | string; @property({ attribute: false }) inputMax?: number | string; @property({ attribute: false }) inputStep?: number | string; @property({ attribute: false }) inputValue?: number | string; @property({ attribute: false }) inputAriaLabel?: string; @property({ attribute: false }) inputPlaceholder?: string; @property({ attribute: false }) defaultInputValue?: number | string; @property({ attribute: false }) minValidOnEnable?: number; @property({ attribute: false }) onToggle?: ( checked: boolean, value: number | string | undefined, ) => void; @property({ attribute: false }) onInput?: (e: Event) => void; @property({ attribute: false }) onChange?: (e: Event) => void; @property({ attribute: false }) onKeyDown?: (e: KeyboardEvent) => void; createRenderRoot() { return this; } protected updated(changedProperties: PropertyValues) { if (!changedProperties.has("checked")) return; const previousChecked = changedProperties.get("checked"); if (previousChecked === false && this.checked) { const input = this.querySelector("input"); if (input) { input.focus(); input.select(); } } } private toOptionalNumber( value: number | string | undefined, ): number | undefined { if (typeof value === "number") { return Number.isFinite(value) ? value : undefined; } if (typeof value === "string") { const trimmed = value.trim(); if (!trimmed) return undefined; const numeric = Number(trimmed); return Number.isFinite(numeric) ? numeric : undefined; } return undefined; } private resolveValueOnEnable(): number | string | undefined { const currentValue = this.inputValue; if ( currentValue === undefined || currentValue === null || currentValue === "" ) { return this.defaultInputValue; } if (this.minValidOnEnable === undefined) { return currentValue; } const numericValue = this.toOptionalNumber(currentValue); if (numericValue === undefined || numericValue < this.minValidOnEnable) { return this.defaultInputValue; } return numericValue; } private emitToggle() { const nextChecked = !this.checked; const nextValue = nextChecked ? this.resolveValueOnEnable() : undefined; this.onToggle?.(nextChecked, nextValue); } private handleCardClick = () => { this.emitToggle(); }; render() { return html`
${this.checked ? html`
` : nothing}
`; } }