UNPKG

@liturgical-calendar/components-js

Version:

Liturgical calendar components for javascript: an html select populated with liturgical calendars supported by the Liturgical Calendar API; form controls for parameters that are supported by the Liturgical Calendar API; a webcalendar; and liturgy of the d

96 lines (95 loc) 4.9 kB
import SelectInput from "./SelectInput.js"; import ApiClient from "../../ApiClient/ApiClient.js"; export default class LocaleInput extends SelectInput { static #apiLocales = null; static #apiLocalesDisplay = {}; //#regionNames = null; #languageNames = null; /** @type {HTMLOptionElement[]} */ #options = null; /** * Constructs a LocaleInput object. * * @param {string|Intl.Locale|null} locale - The locale to use for the select element. * The locale should be a valid string that can be parsed by the * Intl.getCanonicalLocales function or an instance of Intl.Locale. * If the locale string contains an underscore, the underscore will be replaced * with a hyphen. * * @throws {Error} If the locale is invalid. */ constructor(locale = null) { super(); this._domElement.name = 'locale'; this._domElement.id = 'locale'; this._labelElement.textContent = 'locale'; this._labelElement.htmlFor = this._domElement.id; if (ApiClient._metadata === null) { throw new Error('ApiClient has not yet been initialized. Please initialize with `ApiClient.init().then(() => { ... })`, and handle the LocaleInput instances within the callback.'); } if (locale === null) { throw new Error('Locale cannot be null.'); } if (false === locale instanceof Intl.Locale) { throw new Error('Invalid type for locale, must be of type `Intl.Locale` but found type: ' + typeof locale); } //this.#regionNames = new Intl.DisplayNames([locale.language], { type: 'region' }); this.#languageNames = new Intl.DisplayNames([locale.language], { type: 'language' }); if (LocaleInput.#apiLocales === null) { LocaleInput.#apiLocales = ApiClient._metadata.locales; } if (false === LocaleInput.#apiLocalesDisplay.hasOwnProperty(locale.language)) { LocaleInput.#apiLocalesDisplay[locale.language] = new Map(); LocaleInput.#apiLocales.forEach((localeVal) => { LocaleInput.#apiLocalesDisplay[locale.language].set(localeVal, this.#languageNames.of(localeVal)); }); LocaleInput.#apiLocalesDisplay[locale.language] = new Map([...LocaleInput.#apiLocalesDisplay[locale.language].entries()].sort((a, b) => a[1].localeCompare(b[1]))); } this.#options = Array.from(LocaleInput.#apiLocalesDisplay[locale.language]).map(([value, label]) => { const option = document.createElement('option'); option.value = value; option.title = value; option.textContent = label; option.selected = this._defaultValue === value; return option; }); this._domElement.replaceChildren(...this.#options); } /** * Updates the options for the calendar locales select input. * * This method takes an array of calendar locale identifiers and updates * the select input with corresponding option elements. Each option element * is created with the locale identifier as its value and display name. * * @param {string[]} calendarLocales - An array of calendar locale identifiers. * @throws {Error} If the `calendarLocales` array is empty. */ setOptionsForCalendarLocales(calendarLocales = []) { if (calendarLocales.length === 0) { console.error('`calendarLocales` parameter passed to `LocaleInput.setOptionsForCalendarLocales()` cannot be empty.'); console.error(this); throw new Error('`calendarLocales` parameter passed to `LocaleInput.setOptionsForCalendarLocales()` cannot be empty.'); } const newChildren = calendarLocales.map((calendarLocale) => { const option = document.createElement('option'); option.value = calendarLocale; option.title = calendarLocale; option.textContent = this.#languageNames.of(calendarLocale.replaceAll('_', '-')); return option; }); this._domElement.replaceChildren(...newChildren); } /** * Resets the options for this LocaleInput instance. * * This method is typically called when the user selects a new calendar. * It will reset the options to the default locales supported by the API, and * set the selected value of the input to the value of the `selectedValue` property * of the LocaleInput instance, or to "la" if no value is set. */ resetOptions() { this._domElement.replaceChildren(...this.#options); this._domElement.value = this._defaultValue !== '' ? this._defaultValue : 'la'; } }