import { css, CSSResultGroup, html, LitElement, nothing, PropertyValues, } from "lit"; import { customElement, property } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { fireEvent } from "../../common/dom/fire_event"; import { NumberSelector } from "../../data/selector"; import { HomeAssistant } from "../../types"; import "../ha-input-helper-text"; import "../ha-slider"; import "../ha-textfield"; @customElement("ha-selector-number") export class HaNumberSelector extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public selector!: NumberSelector; @property({ type: Number }) public value?: number; @property({ type: Number }) public placeholder?: number; @property() public label?: string; @property() public helper?: string; @property({ type: Boolean }) public required = true; @property({ type: Boolean }) public disabled = false; private _valueStr = ""; protected willUpdate(changedProps: PropertyValues) { if (changedProps.has("value")) { if (this._valueStr === "" || this.value !== Number(this._valueStr)) { this._valueStr = this.value == null || isNaN(this.value) ? "" : this.value.toString(); } } } protected render() { const isBox = this.selector.number?.mode === "box" || this.selector.number?.min === undefined || this.selector.number?.max === undefined; let sliderStep; if (!isBox) { sliderStep = this.selector.number!.step ?? 1; if (sliderStep === "any") { sliderStep = 1; // divide the range of the slider by 100 steps const step = (this.selector.number!.max! - this.selector.number!.min!) / 100; // biggest step size is 1, round the step size to a division of 1 while (sliderStep > step) { sliderStep /= 10; } } } return html` ${this.label && !isBox ? html`${this.label}${this.required ? "*" : ""}` : nothing}
${!isBox ? html` ` : nothing}
${!isBox && this.helper ? html`${this.helper}` : nothing} `; } private _handleInputChange(ev) { ev.stopPropagation(); this._valueStr = ev.target.value; const value = ev.target.value === "" || isNaN(ev.target.value) ? undefined : Number(ev.target.value); if (this.value === value) { return; } fireEvent(this, "value-changed", { value }); } private _handleSliderChange(ev) { ev.stopPropagation(); const value = Number(ev.target.value); if (this.value === value) { return; } fireEvent(this, "value-changed", { value }); } static get styles(): CSSResultGroup { return css` .input { display: flex; justify-content: space-between; align-items: center; direction: ltr; } ha-slider { flex: 1; margin-right: 16px; margin-inline-end: 16px; margin-inline-start: 0; } ha-textfield { --ha-textfield-input-width: 40px; } .single { --ha-textfield-input-width: unset; flex: 1; } `; } } declare global { interface HTMLElementTagNameMap { "ha-selector-number": HaNumberSelector; } }