CountrySelector (#18035)

This commit is contained in:
G Johansson 2023-10-12 16:47:28 +02:00 committed by GitHub
parent 6d1e923b83
commit 4c94ac5dda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 107 additions and 18 deletions

View File

@ -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`
<ha-select
.label=${this.label}
.value=${this.value}
.required=${this.required}
.helper=${this.helper}
.disabled=${this.disabled}
@selected=${this._changed}
@closed=${stopPropagation}

View File

@ -66,6 +66,10 @@ export const computeInitialHaFormData = (
typeof firstOption === "string" ? firstOption : firstOption.value;
data[field.name] = selector.select.multiple ? [val] : val;
}
} else if ("country" in selector) {
if (selector.country?.countries?.length) {
data[field.name] = selector.country.countries[0];
}
} else if ("duration" in selector) {
data[field.name] = {
hours: 0,

View File

@ -0,0 +1,49 @@
import { css, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { CountrySelector } from "../../data/selector";
import { HomeAssistant } from "../../types";
import "../ha-country-picker";
@customElement("ha-selector-country")
export class HaCountrySelector extends LitElement {
@property() public hass!: HomeAssistant;
@property() public selector!: CountrySelector;
@property() public value?: any;
@property() public label?: string;
@property() public helper?: string;
@property({ type: Boolean }) public disabled = false;
@property({ type: Boolean }) public required = true;
protected render() {
return html`
<ha-country-picker
.hass=${this.hass}
.value=${this.value}
.label=${this.label}
.helper=${this.helper}
.countries=${this.selector.country?.countries}
.noSort=${this.selector.country?.no_sort}
.disabled=${this.disabled}
.required=${this.required}
></ha-country-picker>
`;
}
static styles = css`
ha-country-picker {
width: 100%;
}
`;
}
declare global {
interface HTMLElementTagNameMap {
"ha-selector-country": HaCountrySelector;
}
}

View File

@ -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"),

View File

@ -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;

View File

@ -418,6 +418,9 @@
"conversation_agent": "Conversation agent",
"none": "None"
},
"country-picker": {
"country": "Country"
},
"pipeline-picker": {
"pipeline": "Assistant",
"preferred": "Preferred assistant ({preferred})",