Replace onboarding inputs with default inputs (#16514)

This commit is contained in:
Bram Kragten 2023-05-12 13:15:28 +02:00 committed by GitHub
parent 75f080ee85
commit aa063d0a3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 751 additions and 648 deletions

View File

@ -1,286 +0,0 @@
import memoizeOne from "memoize-one";
import { caseInsensitiveStringCompare } from "../common/string/compare";
export const COUNTRIES = [
"AD",
"AE",
"AF",
"AG",
"AI",
"AL",
"AM",
"AO",
"AQ",
"AR",
"AS",
"AT",
"AU",
"AW",
"AX",
"AZ",
"BA",
"BB",
"BD",
"BE",
"BF",
"BG",
"BH",
"BI",
"BJ",
"BL",
"BM",
"BN",
"BO",
"BQ",
"BR",
"BS",
"BT",
"BV",
"BW",
"BY",
"BZ",
"CA",
"CC",
"CD",
"CF",
"CG",
"CH",
"CI",
"CK",
"CL",
"CM",
"CN",
"CO",
"CR",
"CU",
"CV",
"CW",
"CX",
"CY",
"CZ",
"DE",
"DJ",
"DK",
"DM",
"DO",
"DZ",
"EC",
"EE",
"EG",
"EH",
"ER",
"ES",
"ET",
"FI",
"FJ",
"FK",
"FM",
"FO",
"FR",
"GA",
"GB",
"GD",
"GE",
"GF",
"GG",
"GH",
"GI",
"GL",
"GM",
"GN",
"GP",
"GQ",
"GR",
"GS",
"GT",
"GU",
"GW",
"GY",
"HK",
"HM",
"HN",
"HR",
"HT",
"HU",
"ID",
"IE",
"IL",
"IM",
"IN",
"IO",
"IQ",
"IR",
"IS",
"IT",
"JE",
"JM",
"JO",
"JP",
"KE",
"KG",
"KH",
"KI",
"KM",
"KN",
"KP",
"KR",
"KW",
"KY",
"KZ",
"LA",
"LB",
"LC",
"LI",
"LK",
"LR",
"LS",
"LT",
"LU",
"LV",
"LY",
"MA",
"MC",
"MD",
"ME",
"MF",
"MG",
"MH",
"MK",
"ML",
"MM",
"MN",
"MO",
"MP",
"MQ",
"MR",
"MS",
"MT",
"MU",
"MV",
"MW",
"MX",
"MY",
"MZ",
"NA",
"NC",
"NE",
"NF",
"NG",
"NI",
"NL",
"NO",
"NP",
"NR",
"NU",
"NZ",
"OM",
"PA",
"PE",
"PF",
"PG",
"PH",
"PK",
"PL",
"PM",
"PN",
"PR",
"PS",
"PT",
"PW",
"PY",
"QA",
"RE",
"RO",
"RS",
"RU",
"RW",
"SA",
"SB",
"SC",
"SD",
"SE",
"SG",
"SH",
"SI",
"SJ",
"SK",
"SL",
"SM",
"SN",
"SO",
"SR",
"SS",
"ST",
"SV",
"SX",
"SY",
"SZ",
"TC",
"TD",
"TF",
"TG",
"TH",
"TJ",
"TK",
"TL",
"TM",
"TN",
"TO",
"TR",
"TT",
"TV",
"TW",
"TZ",
"UA",
"UG",
"UM",
"US",
"UY",
"UZ",
"VA",
"VC",
"VE",
"VG",
"VI",
"VN",
"VU",
"WF",
"WS",
"YE",
"YT",
"ZA",
"ZM",
"ZW",
];
export const getCountryOptions = memoizeOne((language?: string) => {
const countryDisplayNames =
Intl && "DisplayNames" in Intl
? new Intl.DisplayNames(language, {
type: "region",
fallback: "code",
})
: undefined;
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;
});
export const createCountryListEl = (language?: string) => {
const list = document.createElement("datalist");
list.id = "countries";
const options = getCountryOptions(language);
for (const country of options) {
const option = document.createElement("option");
option.value = country.value;
option.innerText = country.label;
list.appendChild(option);
}
return list;
};

View File

@ -1,192 +0,0 @@
import memoizeOne from "memoize-one";
import { caseInsensitiveStringCompare } from "../common/string/compare";
export const CURRENCIES = [
"AED",
"AFN",
"ALL",
"AMD",
"ANG",
"AOA",
"ARS",
"AUD",
"AWG",
"AZN",
"BAM",
"BBD",
"BDT",
"BGN",
"BHD",
"BIF",
"BMD",
"BND",
"BOB",
"BRL",
"BSD",
"BTN",
"BWP",
"BYN",
"BYR",
"BZD",
"CAD",
"CDF",
"CHF",
"CLP",
"CNY",
"COP",
"CRC",
"CUP",
"CVE",
"CZK",
"DJF",
"DKK",
"DOP",
"DZD",
"EGP",
"ERN",
"ETB",
"EUR",
"FJD",
"FKP",
"GBP",
"GEL",
"GHS",
"GIP",
"GMD",
"GNF",
"GTQ",
"GYD",
"HKD",
"HNL",
"HRK",
"HTG",
"HUF",
"IDR",
"ILS",
"INR",
"IQD",
"IRR",
"ISK",
"JMD",
"JOD",
"JPY",
"KES",
"KGS",
"KHR",
"KMF",
"KPW",
"KRW",
"KWD",
"KYD",
"KZT",
"LAK",
"LBP",
"LKR",
"LRD",
"LSL",
"LTL",
"LYD",
"MAD",
"MDL",
"MGA",
"MKD",
"MMK",
"MNT",
"MOP",
"MRO",
"MUR",
"MVR",
"MWK",
"MXN",
"MYR",
"MZN",
"NAD",
"NGN",
"NIO",
"NOK",
"NPR",
"NZD",
"OMR",
"PAB",
"PEN",
"PGK",
"PHP",
"PKR",
"PLN",
"PYG",
"QAR",
"RON",
"RSD",
"RUB",
"RWF",
"SAR",
"SBD",
"SCR",
"SDG",
"SEK",
"SGD",
"SHP",
"SLL",
"SOS",
"SRD",
"SSP",
"STD",
"SYP",
"SZL",
"THB",
"TJS",
"TMT",
"TND",
"TOP",
"TRY",
"TTD",
"TWD",
"TZS",
"UAH",
"UGX",
"USD",
"UYU",
"UZS",
"VEF",
"VND",
"VUV",
"WST",
"XAF",
"XCD",
"XOF",
"XPF",
"YER",
"ZAR",
"ZMW",
"ZWL",
];
export const getCurrencyOptions = memoizeOne((language?: string) => {
const currencyDisplayNames =
Intl && "DisplayNames" in Intl
? new Intl.DisplayNames(language, {
type: "currency",
fallback: "code",
})
: undefined;
const options = CURRENCIES.map((currency) => ({
value: currency,
label: currencyDisplayNames ? currencyDisplayNames.of(currency)! : currency,
}));
options.sort((a, b) =>
caseInsensitiveStringCompare(a.label, b.label, language)
);
return options;
});
export const createCurrencyListEl = (language: string) => {
const list = document.createElement("datalist");
list.id = "currencies";
for (const currency of getCurrencyOptions(language)) {
const option = document.createElement("option");
option.value = currency.value;
option.innerText = currency.label;
list.appendChild(option);
}
return list;
};

View File

@ -0,0 +1,340 @@
import { css, CSSResultGroup, 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 "../resources/intl-polyfill";
import "./ha-list-item";
import "./ha-select";
import type { HaSelect } from "./ha-select";
const COUNTRIES = [
"AD",
"AE",
"AF",
"AG",
"AI",
"AL",
"AM",
"AO",
"AQ",
"AR",
"AS",
"AT",
"AU",
"AW",
"AX",
"AZ",
"BA",
"BB",
"BD",
"BE",
"BF",
"BG",
"BH",
"BI",
"BJ",
"BL",
"BM",
"BN",
"BO",
"BQ",
"BR",
"BS",
"BT",
"BV",
"BW",
"BY",
"BZ",
"CA",
"CC",
"CD",
"CF",
"CG",
"CH",
"CI",
"CK",
"CL",
"CM",
"CN",
"CO",
"CR",
"CU",
"CV",
"CW",
"CX",
"CY",
"CZ",
"DE",
"DJ",
"DK",
"DM",
"DO",
"DZ",
"EC",
"EE",
"EG",
"EH",
"ER",
"ES",
"ET",
"FI",
"FJ",
"FK",
"FM",
"FO",
"FR",
"GA",
"GB",
"GD",
"GE",
"GF",
"GG",
"GH",
"GI",
"GL",
"GM",
"GN",
"GP",
"GQ",
"GR",
"GS",
"GT",
"GU",
"GW",
"GY",
"HK",
"HM",
"HN",
"HR",
"HT",
"HU",
"ID",
"IE",
"IL",
"IM",
"IN",
"IO",
"IQ",
"IR",
"IS",
"IT",
"JE",
"JM",
"JO",
"JP",
"KE",
"KG",
"KH",
"KI",
"KM",
"KN",
"KP",
"KR",
"KW",
"KY",
"KZ",
"LA",
"LB",
"LC",
"LI",
"LK",
"LR",
"LS",
"LT",
"LU",
"LV",
"LY",
"MA",
"MC",
"MD",
"ME",
"MF",
"MG",
"MH",
"MK",
"ML",
"MM",
"MN",
"MO",
"MP",
"MQ",
"MR",
"MS",
"MT",
"MU",
"MV",
"MW",
"MX",
"MY",
"MZ",
"NA",
"NC",
"NE",
"NF",
"NG",
"NI",
"NL",
"NO",
"NP",
"NR",
"NU",
"NZ",
"OM",
"PA",
"PE",
"PF",
"PG",
"PH",
"PK",
"PL",
"PM",
"PN",
"PR",
"PS",
"PT",
"PW",
"PY",
"QA",
"RE",
"RO",
"RS",
"RU",
"RW",
"SA",
"SB",
"SC",
"SD",
"SE",
"SG",
"SH",
"SI",
"SJ",
"SK",
"SL",
"SM",
"SN",
"SO",
"SR",
"SS",
"ST",
"SV",
"SX",
"SY",
"SZ",
"TC",
"TD",
"TF",
"TG",
"TH",
"TJ",
"TK",
"TL",
"TM",
"TN",
"TO",
"TR",
"TT",
"TV",
"TW",
"TZ",
"UA",
"UG",
"UM",
"US",
"UY",
"UZ",
"VA",
"VC",
"VE",
"VG",
"VI",
"VN",
"VU",
"WF",
"WS",
"YE",
"YT",
"ZA",
"ZM",
"ZW",
];
@customElement("ha-country-picker")
export class HaCountryPicker extends LitElement {
@property() public language = "en";
@property() public value?: string;
@property() public label?: 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;
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;
});
protected render() {
const options = this._getOptions(this.language);
return html`
<ha-select
.label=${this.label}
.value=${this.value}
.required=${this.required}
.disabled=${this.disabled}
@selected=${this._changed}
@closed=${stopPropagation}
fixedMenuPosition
naturalMenuWidth
>
${options.map(
(option) => html`
<ha-list-item .value=${option.value}>${option.label}</ha-list-item>
`
)}
</ha-select>
`;
}
static get styles(): CSSResultGroup {
return css`
ha-select {
width: 100%;
}
`;
}
private _changed(ev): void {
const target = ev.target as HaSelect;
if (target.value === "" || target.value === this.value) {
return;
}
this.value = target.value;
fireEvent(this, "value-changed", { value: this.value });
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-country-picker": HaCountryPicker;
}
}

View File

@ -0,0 +1,256 @@
import { css, CSSResultGroup, 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 "../resources/intl-polyfill";
import "./ha-list-item";
import "./ha-select";
import type { HaSelect } from "./ha-select";
const CURRENCIES = [
"AED",
"AFN",
"ALL",
"AMD",
"ANG",
"AOA",
"ARS",
"AUD",
"AWG",
"AZN",
"BAM",
"BBD",
"BDT",
"BGN",
"BHD",
"BIF",
"BMD",
"BND",
"BOB",
"BRL",
"BSD",
"BTN",
"BWP",
"BYN",
"BYR",
"BZD",
"CAD",
"CDF",
"CHF",
"CLP",
"CNY",
"COP",
"CRC",
"CUP",
"CVE",
"CZK",
"DJF",
"DKK",
"DOP",
"DZD",
"EGP",
"ERN",
"ETB",
"EUR",
"FJD",
"FKP",
"GBP",
"GEL",
"GHS",
"GIP",
"GMD",
"GNF",
"GTQ",
"GYD",
"HKD",
"HNL",
"HRK",
"HTG",
"HUF",
"IDR",
"ILS",
"INR",
"IQD",
"IRR",
"ISK",
"JMD",
"JOD",
"JPY",
"KES",
"KGS",
"KHR",
"KMF",
"KPW",
"KRW",
"KWD",
"KYD",
"KZT",
"LAK",
"LBP",
"LKR",
"LRD",
"LSL",
"LTL",
"LYD",
"MAD",
"MDL",
"MGA",
"MKD",
"MMK",
"MNT",
"MOP",
"MRO",
"MUR",
"MVR",
"MWK",
"MXN",
"MYR",
"MZN",
"NAD",
"NGN",
"NIO",
"NOK",
"NPR",
"NZD",
"OMR",
"PAB",
"PEN",
"PGK",
"PHP",
"PKR",
"PLN",
"PYG",
"QAR",
"RON",
"RSD",
"RUB",
"RWF",
"SAR",
"SBD",
"SCR",
"SDG",
"SEK",
"SGD",
"SHP",
"SLL",
"SOS",
"SRD",
"SSP",
"STD",
"SYP",
"SZL",
"THB",
"TJS",
"TMT",
"TND",
"TOP",
"TRY",
"TTD",
"TWD",
"TZS",
"UAH",
"UGX",
"USD",
"UYU",
"UZS",
"VEF",
"VND",
"VUV",
"WST",
"XAF",
"XCD",
"XOF",
"XPF",
"YER",
"ZAR",
"ZMW",
"ZWL",
];
const curSymbol = (currency: string, locale?: string) =>
Intl && "NumberFormat" in Intl
? new Intl.NumberFormat(locale, { style: "currency", currency })
.formatToParts(1)
.find((x) => x.type === "currency")?.value
: currency;
@customElement("ha-currency-picker")
export class HaCurrencyPicker extends LitElement {
@property() public language = "en";
@property() public value?: string;
@property() public label?: string;
@property({ type: Boolean }) public required = false;
@property({ type: Boolean, reflect: true }) public disabled = false;
private _getOptions = memoizeOne((language?: string) => {
const currencyDisplayNames =
Intl && "DisplayNames" in Intl
? new Intl.DisplayNames(language, {
type: "currency",
fallback: "code",
})
: undefined;
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;
});
protected render() {
const options = this._getOptions(this.language);
return html`
<ha-select
.label=${this.label}
.value=${this.value}
.required=${this.required}
.disabled=${this.disabled}
@selected=${this._changed}
@closed=${stopPropagation}
fixedMenuPosition
naturalMenuWidth
>
${options.map(
(option) => html`
<ha-list-item .value=${option.value}>${option.label}</ha-list-item>
`
)}
</ha-select>
`;
}
static get styles(): CSSResultGroup {
return css`
ha-select {
width: 100%;
}
`;
}
private _changed(ev): void {
const target = ev.target as HaSelect;
if (target.value === "" || target.value === this.value) {
return;
}
this.value = target.value;
fireEvent(this, "value-changed", { value: this.value });
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-currency-picker": HaCurrencyPicker;
}
}

View File

@ -6,6 +6,7 @@ import { stopPropagation } from "../common/dom/stop_propagation";
import { formatLanguageCode } from "../common/language/format_language";
import { caseInsensitiveStringCompare } from "../common/string/compare";
import { FrontendLocaleData } from "../data/translation";
import "../resources/intl-polyfill";
import { HomeAssistant } from "../types";
import "./ha-list-item";
import "./ha-select";

View File

@ -0,0 +1,62 @@
import timezones from "google-timezones-json";
import { css, CSSResultGroup, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { fireEvent } from "../common/dom/fire_event";
import { stopPropagation } from "../common/dom/stop_propagation";
import "./ha-list-item";
import "./ha-select";
import type { HaSelect } from "./ha-select";
@customElement("ha-timezone-picker")
export class HaTimeZonePicker extends LitElement {
@property() public value?: string;
@property() public label?: string;
@property({ type: Boolean }) public required = false;
@property({ type: Boolean, reflect: true }) public disabled = false;
protected render() {
return html`
<ha-select
.label=${this.label}
.value=${this.value}
.required=${this.required}
.disabled=${this.disabled}
@selected=${this._changed}
@closed=${stopPropagation}
fixedMenuPosition
naturalMenuWidth
>
${Object.entries(timezones).map(
([key, value]) =>
html`<ha-list-item value=${key}>${value}</ha-list-item>`
)}
</ha-select>
`;
}
static get styles(): CSSResultGroup {
return css`
ha-select {
width: 100%;
}
`;
}
private _changed(ev): void {
const target = ev.target as HaSelect;
if (target.value === "" || target.value === this.value) {
return;
}
this.value = target.value;
fireEvent(this, "value-changed", { value: this.value });
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-timezone-picker": HaTimeZonePicker;
}
}

View File

@ -1,8 +0,0 @@
export const SYMBOL_TO_ISO = {
$: "USD",
"€": "EUR",
"¥": "JPY",
"£": "GBP",
"₽": "RUB",
"₹": "INR",
};

View File

@ -11,29 +11,28 @@ import { customElement, property, query, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { fireEvent } from "../common/dom/fire_event";
import type { LocalizeFunc } from "../common/translations/localize";
import { createCountryListEl } from "../components/country-datalist";
import { createCurrencyListEl } from "../components/currency-datalist";
import "../components/ha-alert";
import "../components/ha-country-picker";
import "../components/ha-currency-picker";
import "../components/ha-formfield";
import "../components/ha-language-picker";
import "../components/ha-radio";
import type { HaRadio } from "../components/ha-radio";
import "../components/ha-textfield";
import type { HaTextField } from "../components/ha-textfield";
import { createLanguageListEl } from "../components/language-datalist";
import "../components/ha-timezone-picker";
import "../components/map/ha-locations-editor";
import type {
HaLocationsEditor,
MarkerLocation,
} from "../components/map/ha-locations-editor";
import { createTimezoneListEl } from "../components/timezone-datalist";
import {
ConfigUpdateValues,
detectCoreConfig,
saveCoreConfig,
} from "../data/core";
import { SYMBOL_TO_ISO } from "../data/currency";
import { onboardCoreConfigStep } from "../data/onboarding";
import type { ValueChangedEvent, HomeAssistant } from "../types";
import type { HomeAssistant, ValueChangedEvent } from "../types";
import { getLocalLanguage } from "../util/common-translation";
const amsterdam: [number, number] = [52.3731339, 4.8903147];
@ -58,9 +57,11 @@ class OnboardingCoreConfig extends LitElement {
@state() private _currency?: ConfigUpdateValues["currency"];
@state() private _timeZone?: string;
@state() private _timeZone? =
Intl.DateTimeFormat?.().resolvedOptions?.().timeZone;
@state() private _language?: ConfigUpdateValues["language"];
@state() private _language: ConfigUpdateValues["language"] =
getLocalLanguage();
@state() private _country?: ConfigUpdateValues["country"];
@ -127,45 +128,50 @@ class OnboardingCoreConfig extends LitElement {
</div>
<div class="row">
<ha-textfield
<ha-country-picker
class="flex"
.language=${this.hass.locale.language}
.label=${
this.hass.localize(
"ui.panel.config.core.section.core.core_config.country"
) || "Country"
}
name="country"
required
.disabled=${this._working}
.value=${this._countryValue}
@change=${this._handleChange}
></ha-textfield>
<ha-textfield
name="country"
required
.disabled=${this._working}
.value=${this._countryValue}
@value-changed=${this._handleValueChanged}
>
</ha-country-picker>
<ha-language-picker
class="flex"
.label=${
this.hass.localize(
"ui.panel.config.core.section.core.core_config.language"
) || "Language"
}
.hass=${this.hass}
nativeName
.label=${this.hass.localize(
"ui.panel.config.core.section.core.core_config.language"
)}
name="language"
required
.disabled=${this._working}
.value=${this._languageValue}
@change=${this._handleChange}
></ha-textfield>
.disabled=${this._working}
@value-changed=${this._handleValueChanged}
>
</ha-language-picker>
</div>
<div class="row">
<ha-textfield
class="flex"
.label=${this.hass.localize(
"ui.panel.config.core.section.core.core_config.time_zone"
)}
name="timeZone"
.disabled=${this._working}
.value=${this._timeZoneValue}
@change=${this._handleChange}
></ha-textfield>
<ha-timezone-picker
class="flex"
.label=${this.hass.localize(
"ui.panel.config.core.section.core.core_config.time_zone"
)}
name="timeZone"
.disabled=${this._working}
.value=${this._timeZoneValue}
@value-changed=${this._handleValueChanged}
>
</ha-timezone-picker>
<ha-textfield
class="flex"
@ -244,17 +250,18 @@ class OnboardingCoreConfig extends LitElement {
)}</a
>
</div>
<ha-textfield
class="flex"
.label=${this.hass.localize(
"ui.panel.config.core.section.core.core_config.currency"
)}
name="currency"
.disabled=${this._working}
.value=${this._currencyValue}
@change=${this._handleChange}
></ha-textfield>
<ha-currency-picker
class="flex"
.label=${this.hass.localize(
"ui.panel.config.core.section.core.core_config.currency"
)}
name="currency"
.disabled=${this._working}
.value=${this._currencyValue}
@value-changed=${this._handleValueChanged}
>
</ha-currency-picker
>
</div>
</div>
@ -279,45 +286,6 @@ class OnboardingCoreConfig extends LitElement {
this._save(ev);
}
});
const tzInput = this.renderRoot.querySelector(
"[name=timeZone]"
) as HaTextField;
tzInput.updateComplete.then(() => {
tzInput.renderRoot.appendChild(createTimezoneListEl());
tzInput.formElement.setAttribute("list", "timezones");
});
const curInput = this.renderRoot.querySelector(
"[name=currency]"
) as HaTextField;
curInput.updateComplete.then(() => {
curInput.renderRoot.appendChild(
createCurrencyListEl(this.hass.locale.language)
);
curInput.formElement.setAttribute("list", "currencies");
});
const countryInput = this.renderRoot.querySelector(
"[name=country]"
) as HaTextField;
countryInput.updateComplete.then(() => {
countryInput.renderRoot.appendChild(
createCountryListEl(this.hass.locale.language)
);
countryInput.formElement.setAttribute("list", "countries");
});
const langInput = this.renderRoot.querySelector(
"[name=language]"
) as HaTextField;
langInput.updateComplete.then(() => {
langInput.renderRoot.appendChild(createLanguageListEl(this.hass));
langInput.renderRoot
.querySelector("#label")
?.classList.add("mdc-floating-label--required");
langInput.formElement.setAttribute("list", "languages");
});
}
private get _nameValue() {
@ -367,18 +335,14 @@ class OnboardingCoreConfig extends LitElement {
]
);
private _handleValueChanged(ev) {
const target = ev.currentTarget;
this[`_${target.getAttribute("name")}`] = ev.detail.value;
}
private _handleChange(ev: ValueChangedEvent<string>) {
const target = ev.currentTarget as HaTextField;
let value = target.value;
if (target.name === "currency" && value) {
if (value in SYMBOL_TO_ISO) {
value = SYMBOL_TO_ISO[value];
}
}
this[`_${target.name}`] = value;
this[`_${target.name}`] = target.value;
}
private _locationChanged(ev) {
@ -465,6 +429,7 @@ class OnboardingCoreConfig extends LitElement {
flex-direction: row;
margin: 0 -8px;
align-items: center;
--ha-select-min-width: 100px;
}
.secondary {

View File

@ -1,5 +1,4 @@
import "@material/mwc-list/mwc-list-item";
import timezones from "google-timezones-json";
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
@ -8,12 +7,12 @@ import { stopPropagation } from "../../../common/dom/stop_propagation";
import { navigate } from "../../../common/navigate";
import "../../../components/buttons/ha-progress-button";
import type { HaProgressButton } from "../../../components/buttons/ha-progress-button";
import { getCountryOptions } from "../../../components/country-datalist";
import { getCurrencyOptions } from "../../../components/currency-datalist";
import "../../../components/ha-alert";
import "../../../components/ha-card";
import "../../../components/ha-checkbox";
import type { HaCheckbox } from "../../../components/ha-checkbox";
import "../../../components/ha-country-picker";
import "../../../components/ha-currency-picker";
import "../../../components/ha-formfield";
import "../../../components/ha-language-picker";
import "../../../components/ha-radio";
@ -21,10 +20,10 @@ import type { HaRadio } from "../../../components/ha-radio";
import "../../../components/ha-select";
import "../../../components/ha-settings-row";
import "../../../components/ha-textfield";
import "../../../components/ha-timezone-picker";
import "../../../components/map/ha-locations-editor";
import type { MarkerLocation } from "../../../components/map/ha-locations-editor";
import { ConfigUpdateValues, saveCoreConfig } from "../../../data/core";
import { SYMBOL_TO_ISO } from "../../../data/currency";
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
import "../../../layouts/hass-subpage";
import { haStyle } from "../../../resources/styles";
@ -94,25 +93,16 @@ class HaConfigSectionGeneral extends LitElement {
.value=${this._name}
@change=${this._handleChange}
></ha-textfield>
<ha-select
<ha-timezone-picker
.label=${this.hass.localize(
"ui.panel.config.core.section.core.core_config.time_zone"
)}
name="timeZone"
fixedMenuPosition
naturalMenuWidth
.disabled=${disabled}
.value=${this._timeZone}
@closed=${stopPropagation}
@change=${this._handleChange}
@value-changed=${this._handleValueChanged}
>
${Object.keys(timezones).map(
(tz) =>
html`<mwc-list-item value=${tz}
>${timezones[tz]}</mwc-list-item
>`
)}
</ha-select>
</ha-timezone-picker>
<ha-textfield
.label=${this.hass.localize(
"ui.panel.config.core.section.core.core_config.elevation"
@ -205,25 +195,17 @@ class HaConfigSectionGeneral extends LitElement {
: ""}
</div>
<div>
<ha-select
<ha-currency-picker
.language=${this.hass.locale.language}
.label=${this.hass.localize(
"ui.panel.config.core.section.core.core_config.currency"
)}
name="currency"
fixedMenuPosition
naturalMenuWidth
.disabled=${disabled}
.value=${this._currency}
@closed=${stopPropagation}
@change=${this._handleChange}
>
${getCurrencyOptions(this.hass.locale.language).map(
({ value, label }) =>
html`<mwc-list-item .value=${value}>
${label}
</mwc-list-item>`
)}</ha-select
@value-changed=${this._handleValueChanged}
>
</ha-currency-picker>
<a
href="https://en.wikipedia.org/wiki/ISO_4217#Active_codes"
target="_blank"
@ -234,25 +216,17 @@ class HaConfigSectionGeneral extends LitElement {
)}</a
>
</div>
<ha-select
<ha-country-picker
.hass=${this.hass}
.label=${this.hass.localize(
"ui.panel.config.core.section.core.core_config.country"
)}
name="country"
fixedMenuPosition
naturalMenuWidth
.disabled=${disabled}
.value=${this._country}
@closed=${stopPropagation}
@change=${this._handleChange}
>
${getCountryOptions(this.hass.locale.language).map(
({ value, label }) =>
html`<mwc-list-item .value=${value}>
${label}
</mwc-list-item>`
)}</ha-select
>
@value-changed=${this._handleValueChanged}
></ha-country-picker>
<ha-language-picker
.hass=${this.hass}
nativeName
@ -263,7 +237,7 @@ class HaConfigSectionGeneral extends LitElement {
.value=${this._language}
.disabled=${disabled}
@closed=${stopPropagation}
@value-changed=${this._handleLanguageChange}
@value-changed=${this._handleValueChanged}
>
</ha-language-picker>
</div>
@ -319,26 +293,22 @@ class HaConfigSectionGeneral extends LitElement {
this._country = this.hass.config.country;
this._language = this.hass.config.language;
this._elevation = this.hass.config.elevation;
this._timeZone = this.hass.config.time_zone || "Etc/GMT";
this._timeZone =
this.hass.config.time_zone ||
Intl.DateTimeFormat?.().resolvedOptions?.().timeZone ||
"Etc/GMT";
this._name = this.hass.config.location_name;
this._updateUnits = true;
}
private _handleLanguageChange(ev) {
this._language = ev.detail.value;
private _handleValueChanged(ev) {
const target = ev.currentTarget;
this[`_${target.name}`] = ev.detail.value;
}
private _handleChange(ev) {
const target = ev.currentTarget;
let value = target.value;
if (target.name === "currency" && value) {
if (value in SYMBOL_TO_ISO) {
value = SYMBOL_TO_ISO[value];
}
}
this[`_${target.name}`] = value;
this[`_${target.name}`] = target.value;
}
private _unitSystemChanged(ev: CustomEvent) {

View File

@ -1,8 +1,8 @@
import { shouldPolyfill as shouldPolyfillDateTime } from "@formatjs/intl-datetimeformat/lib/should-polyfill";
import { shouldPolyfill as shouldPolyfillDisplayName } from "@formatjs/intl-displaynames/lib/should-polyfill";
import { shouldPolyfill as shouldPolyfillLocale } from "@formatjs/intl-locale/lib/should-polyfill";
import { shouldPolyfill as shouldPolyfillPluralRules } from "@formatjs/intl-pluralrules/lib/should-polyfill";
import { shouldPolyfill as shouldPolyfillRelativeTime } from "@formatjs/intl-relativetimeformat/lib/should-polyfill";
import { shouldPolyfill as shouldPolyfillDateTime } from "@formatjs/intl-datetimeformat/should-polyfill";
import { shouldPolyfill as shouldPolyfillDisplayName } from "@formatjs/intl-displaynames/should-polyfill";
import { shouldPolyfill as shouldPolyfillLocale } from "@formatjs/intl-locale/should-polyfill";
import { shouldPolyfill as shouldPolyfillPluralRules } from "@formatjs/intl-pluralrules/should-polyfill";
import { shouldPolyfill as shouldPolyfillRelativeTime } from "@formatjs/intl-relativetimeformat/should-polyfill";
import { getLocalLanguage } from "../util/common-translation";
import { polyfillLocaleData } from "./locale-data-polyfill";
@ -14,11 +14,7 @@ const polyfillIntl = async () => {
await import("@formatjs/intl-locale/polyfill-force");
}
if (shouldPolyfillPluralRules(locale)) {
polyfills.push(
import("@formatjs/intl-pluralrules/polyfill-force").then(
() => import("@formatjs/intl-pluralrules/locale-data/en")
)
);
polyfills.push(import("@formatjs/intl-pluralrules/polyfill-force"));
}
if (shouldPolyfillRelativeTime(locale)) {
polyfills.push(import("@formatjs/intl-relativetimeformat/polyfill-force"));
@ -31,11 +27,10 @@ const polyfillIntl = async () => {
);
}
if (shouldPolyfillDisplayName(locale)) {
polyfills.push(
import("@formatjs/intl-displaynames/polyfill-force").then(
() => import("@formatjs/intl-displaynames/locale-data/en")
)
);
polyfills.push(import("@formatjs/intl-displaynames/polyfill-force"));
}
if (polyfills.length === 0) {
return;
}
await Promise.all(polyfills).then(() =>
// Load the default language