257 lines
4.0 KiB
TypeScript
257 lines
4.0 KiB
TypeScript
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;
|
|
}
|
|
}
|