diff --git a/src/components/ha-currency-picker.ts b/src/components/ha-currency-picker.ts index e5b05a0a75..1fba44b68e 100644 --- a/src/components/ha-currency-picker.ts +++ b/src/components/ha-currency-picker.ts @@ -2,11 +2,16 @@ import { css, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; import memoizeOne from "memoize-one"; import { fireEvent } from "../common/dom/fire_event"; -import { stopPropagation } from "../common/dom/stop_propagation"; import { caseInsensitiveStringCompare } from "../common/string/compare"; -import "./ha-list-item"; -import "./ha-select"; -import type { HaSelect } from "./ha-select"; +import type { FrontendLocaleData } from "../data/translation"; +import type { HomeAssistant, ValueChangedEvent } from "../types"; +import "./ha-generic-picker"; +import type { PickerComboBoxItem } from "./ha-picker-combo-box"; + +const SEARCH_KEYS = [ + { name: "primary", weight: 10 }, + { name: "secondary", weight: 8 }, +]; const CURRENCIES = [ "AED", @@ -172,9 +177,31 @@ const curSymbol = (currency: string, locale?: string) => new Intl.NumberFormat(locale, { style: "currency", currency }) .formatToParts(1) .find((x) => x.type === "currency")?.value; + +export const getCurrencyOptions = ( + locale?: FrontendLocaleData +): PickerComboBoxItem[] => { + const language = locale?.language ?? "en"; + const currencyDisplayNames = new Intl.DisplayNames(language, { + type: "currency", + fallback: "code", + }); + + const options: PickerComboBoxItem[] = CURRENCIES.map((currency) => ({ + id: currency, + primary: `${currencyDisplayNames.of(currency)} (${curSymbol(currency, language)})`, + secondary: currency, + })); + + options.sort((a, b) => + caseInsensitiveStringCompare(a.primary, b.primary, language) + ); + return options; +}; + @customElement("ha-currency-picker") export class HaCurrencyPicker extends LitElement { - @property() public language = "en"; + @property({ attribute: false }) public hass?: HomeAssistant; @property() public value?: string; @@ -184,60 +211,62 @@ export class HaCurrencyPicker extends LitElement { @property({ type: Boolean, reflect: true }) public disabled = false; - private _getOptions = memoizeOne((language?: string) => { - const currencyDisplayNames = new Intl.DisplayNames(language, { - type: "currency", - fallback: "code", - }); - const options = CURRENCIES.map((currency) => ({ - value: currency, - label: `${ - currencyDisplayNames ? currencyDisplayNames.of(currency)! : currency - } (${curSymbol(currency, language)})`, - })); - options.sort((a, b) => - caseInsensitiveStringCompare(a.label, b.label, language) - ); - return options; - }); + private _getCurrencyOptions = memoizeOne(getCurrencyOptions); + + private _getItems = () => this._getCurrencyOptions(this.hass?.locale); + + private _getCurrencyName = (currency?: string) => + this._getItems().find((c) => c.id === currency)?.primary; + + private _valueRenderer = (value: string) => + html`${this._getCurrencyName(value) ?? value}`; protected render() { - const options = this._getOptions(this.language); + const label = + this.label ?? + (this.hass?.localize("ui.components.currency-picker.currency") || + "Currency"); return html` - - ${options.map( - (option) => html` - ${option.label} - ` - )} - + .required=${this.required} + .getItems=${this._getItems} + .searchKeys=${SEARCH_KEYS} + @value-changed=${this._changed} + hide-clear-icon + > `; } static styles = css` - ha-select { + ha-generic-picker { width: 100%; + min-width: 200px; + display: block; } `; - private _changed(ev): void { - const target = ev.target as HaSelect; - if (target.value === "" || target.value === this.value) { - return; - } - this.value = target.value; + private _changed(ev: ValueChangedEvent): void { + ev.stopPropagation(); + this.value = ev.detail.value; fireEvent(this, "value-changed", { value: this.value }); } + + private _notFoundLabel = (search: string) => { + const term = html`'${search}'`; + return this.hass + ? this.hass.localize("ui.components.currency-picker.no_match", { term }) + : html`No currencies found for ${term}`; + }; } declare global { diff --git a/src/panels/config/core/ha-config-section-general.ts b/src/panels/config/core/ha-config-section-general.ts index 87aef39a0e..a15f37c3e9 100644 --- a/src/panels/config/core/ha-config-section-general.ts +++ b/src/panels/config/core/ha-config-section-general.ts @@ -200,7 +200,7 @@ class HaConfigSectionGeneral extends LitElement {
- + >