From 4c94ac5dda3baff051f727de616152c9c24060a9 Mon Sep 17 00:00:00 2001 From: G Johansson Date: Thu, 12 Oct 2023 16:47:28 +0200 Subject: [PATCH] CountrySelector (#18035) --- src/components/ha-country-picker.ts | 60 +++++++++++++------ .../ha-form/compute-initial-ha-form-data.ts | 4 ++ .../ha-selector/ha-selector-country.ts | 49 +++++++++++++++ src/components/ha-selector/ha-selector.ts | 1 + src/data/selector.ts | 8 +++ src/translations/en.json | 3 + 6 files changed, 107 insertions(+), 18 deletions(-) create mode 100644 src/components/ha-selector/ha-selector-country.ts diff --git a/src/components/ha-country-picker.ts b/src/components/ha-country-picker.ts index 5fff71bdfa0c..fea293a2b43a 100644 --- a/src/components/ha-country-picker.ts +++ b/src/components/ha-country-picker.ts @@ -269,37 +269,61 @@ export class HaCountryPicker extends LitElement { @property() public label?: string; + @property() public countries?: string[]; + + @property() public helper?: string; + @property({ type: Boolean }) public required = false; @property({ type: Boolean, reflect: true }) public disabled = false; - private _getOptions = memoizeOne((language?: string) => { - const countryDisplayNames = - Intl && "DisplayNames" in Intl - ? new Intl.DisplayNames(language, { - type: "region", - fallback: "code", - }) - : undefined; + @property({ type: Boolean }) public noSort = false; - const options = COUNTRIES.map((country) => ({ - value: country, - label: countryDisplayNames ? countryDisplayNames.of(country)! : country, - })); - options.sort((a, b) => - caseInsensitiveStringCompare(a.label, b.label, language) - ); - return options; - }); + private _getOptions = memoizeOne( + (language?: string, countries?: string[]) => { + let options: { label: string; value: string }[] = []; + const countryDisplayNames = + Intl && "DisplayNames" in Intl + ? new Intl.DisplayNames(language, { + type: "region", + fallback: "code", + }) + : undefined; + + if (countries) { + options = countries.map((country) => ({ + value: country, + label: countryDisplayNames + ? countryDisplayNames.of(country)! + : country, + })); + } else { + options = COUNTRIES.map((country) => ({ + value: country, + label: countryDisplayNames + ? countryDisplayNames.of(country)! + : country, + })); + } + + if (!this.noSort) { + options.sort((a, b) => + caseInsensitiveStringCompare(a.label, b.label, language) + ); + } + return options; + } + ); protected render() { - const options = this._getOptions(this.language); + const options = this._getOptions(this.language, this.countries); return html` + `; + } + + static styles = css` + ha-country-picker { + width: 100%; + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "ha-selector-country": HaCountrySelector; + } +} diff --git a/src/components/ha-selector/ha-selector.ts b/src/components/ha-selector/ha-selector.ts index 9c831c0a10c6..a69fab215789 100644 --- a/src/components/ha-selector/ha-selector.ts +++ b/src/components/ha-selector/ha-selector.ts @@ -21,6 +21,7 @@ const LOAD_ELEMENTS = { config_entry: () => import("./ha-selector-config-entry"), conversation_agent: () => import("./ha-selector-conversation-agent"), constant: () => import("./ha-selector-constant"), + country: () => import("./ha-selector-country"), date: () => import("./ha-selector-date"), datetime: () => import("./ha-selector-datetime"), device: () => import("./ha-selector-device"), diff --git a/src/data/selector.ts b/src/data/selector.ts index fe4b940a9fe2..a84c7a75b3f3 100644 --- a/src/data/selector.ts +++ b/src/data/selector.ts @@ -23,6 +23,7 @@ export type Selector = | ConversationAgentSelector | ConfigEntrySelector | ConstantSelector + | CountrySelector | DateSelector | DateTimeSelector | DeviceSelector @@ -124,6 +125,13 @@ export interface ConstantSelector { } | null; } +export interface CountrySelector { + country: { + countries: string[]; + no_sort?: boolean; + } | null; +} + export interface DateSelector { // eslint-disable-next-line @typescript-eslint/ban-types date: {} | null; diff --git a/src/translations/en.json b/src/translations/en.json index 5cc06e6afc5c..aa5862f09855 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -418,6 +418,9 @@ "conversation_agent": "Conversation agent", "none": "None" }, + "country-picker": { + "country": "Country" + }, "pipeline-picker": { "pipeline": "Assistant", "preferred": "Preferred assistant ({preferred})",