import { LitElement, html } from "lit"; import { customElement, property, query, state } from "lit/decorators.js"; import { translateText } from "../Utils"; @customElement("fluent-slider") export class FluentSlider extends LitElement { createRenderRoot() { return this; } @property({ type: Number }) value = 0; @property({ type: Number }) min = 0; @property({ type: Number }) max = 400; @property({ type: Number }) step = 1; @property({ type: String }) labelKey = ""; @property({ type: String }) disabledKey = ""; @property({ type: Number }) defaultValue: number | undefined = undefined; @property({ type: String }) defaultLabelKey = ""; @state() private isEditing = false; @query("input[type='number']") private numberInput!: HTMLInputElement; private dispatchValueChange() { this.dispatchEvent( new CustomEvent("value-changed", { detail: { value: this.value }, bubbles: true, composed: true, }), ); } private handleSliderInput(e: Event) { const target = e.target as HTMLInputElement; this.value = target.valueAsNumber; } private handleSliderChange(e: Event) { const target = e.target as HTMLInputElement; this.value = target.valueAsNumber; this.dispatchValueChange(); } private handleNumberInput(e: Event) { const target = e.target as HTMLInputElement; let val = target.valueAsNumber; if (isNaN(val)) { val = this.min; } if (val < this.min) val = this.min; if (val > this.max) val = this.max; this.value = val; // Don't dispatch value change on every input - only on blur/enter } private handleNumberComplete() { // Dispatch the value change when editing is complete this.dispatchValueChange(); } private handleNumberKeyDown(e: KeyboardEvent) { if (e.key === "Enter") { this.isEditing = false; this.handleNumberComplete(); } } private enableEditing() { this.isEditing = true; this.updateComplete.then(() => this.numberInput?.focus()); } render() { const percentage = this.max === this.min ? 0 : ((this.value - this.min) / (this.max - this.min)) * 100; return html`
${this.labelKey ? translateText(this.labelKey) : ""} ${this.isEditing ? html` { this.isEditing = false; this.handleNumberComplete(); }} @keydown=${this.handleNumberKeyDown} />` : html` { if (e.key === "Enter" || e.key === " ") { this.enableEditing(); e.preventDefault(); } }} > ${this.value === 0 && this.disabledKey ? translateText(this.disabledKey) : this.defaultValue !== undefined && this.value === this.defaultValue && this.defaultLabelKey ? html`${this.value} (${translateText(this.defaultLabelKey)})` : this.value} `}
`; } }