diff --git a/app/webpacker/controllers/flatpickr_controller.js b/app/webpacker/controllers/flatpickr_controller.js index b41786f1d1..e5222b85c8 100644 --- a/app/webpacker/controllers/flatpickr_controller.js +++ b/app/webpacker/controllers/flatpickr_controller.js @@ -1,20 +1,5 @@ // import Flatpickr import Flatpickr from "stimulus-flatpickr"; -import { ar } from "flatpickr/dist/l10n/ar"; -import { cat } from "flatpickr/dist/l10n/cat"; -import { cy } from "flatpickr/dist/l10n/cy"; -import { de } from "flatpickr/dist/l10n/de"; -import { fi } from "flatpickr/dist/l10n/fi"; -import { fr } from "flatpickr/dist/l10n/fr"; -import { it } from "flatpickr/dist/l10n/it"; -import { nl } from "flatpickr/dist/l10n/nl"; -import { pl } from "flatpickr/dist/l10n/pl"; -import { pt } from "flatpickr/dist/l10n/pt"; -import { ru } from "flatpickr/dist/l10n/ru"; -import { sv } from "flatpickr/dist/l10n/sv"; -import { tr } from "flatpickr/dist/l10n/tr"; -import { en } from "flatpickr/dist/l10n/default.js"; -import { hu } from "flatpickr/dist/l10n/hu"; import ShortcutButtonsPlugin from "shortcut-buttons-flatpickr"; import labelPlugin from "flatpickr/dist/plugins/labelPlugin/labelPlugin"; @@ -24,28 +9,11 @@ export default class extends Flatpickr { */ static values = { enableTime: Boolean, mode: String, defaultDate: String }; static targets = ["start", "end"]; - locales = { - ar: ar, - cat: cat, - cy: cy, - de: de, - fi: fi, - fr: fr, - it: it, - nl: nl, - pl: pl, - pt: pt, - ru: ru, - sv: sv, - tr: tr, - en: en, - hu: hu, - }; initialize() { const datetimepicker = this.enableTimeValue === true; const mode = this.modeValue === "range" ? "range" : "single"; - // sets your language (you can also set some global setting for all time pickers) + // configure flatpickr options (locale set dynamically in connect()) this.config = { altInput: true, altFormat: datetimepicker @@ -54,13 +22,18 @@ export default class extends Flatpickr { dateFormat: datetimepicker ? "Y-m-d H:i" : "Y-m-d", enableTime: datetimepicker, time_24hr: datetimepicker, - locale: I18n.base_locale, plugins: this.plugins(mode, datetimepicker), mode, }; } - connect() { + async connect() { + const locale = await this.importFlatpickrLocale(I18n.base_locale); + this.config = { + ...this.config, + locale, + }; + super.connect(); window.addEventListener("flatpickr:change", this.onChangeEvent); window.addEventListener("flatpickr:clear", this.clear); @@ -164,4 +137,16 @@ export default class extends Flatpickr { this.fp.setDate(moment().add(1, "days").startOf("day").format()); } } + + async importFlatpickrLocale(localeCode) { + // null tells flatpickr to fall back to its built-in english locale + if (!localeCode || localeCode === "en") return null; + + try { + const localeModule = await import(`flatpickr/dist/l10n/${localeCode}.js`); + return localeModule.default?.[localeCode] ?? null; + } catch { + return null; + } + } } diff --git a/spec/javascripts/stimulus/flatpickr_controller_test.js b/spec/javascripts/stimulus/flatpickr_controller_test.js new file mode 100644 index 0000000000..d27e132571 --- /dev/null +++ b/spec/javascripts/stimulus/flatpickr_controller_test.js @@ -0,0 +1,35 @@ +/** + * @jest-environment jsdom + */ + +import { Application } from "stimulus"; +import FlatpickrController from "../../../app/webpacker/controllers/flatpickr_controller.js"; + +describe("FlatpickrController", () => { + beforeAll(() => { + const application = Application.start(); + application.register("flatpickr", FlatpickrController); + }); + + describe("#importFlatpickrLocale", () => { + describe("returns null to trigger flatpickr fallback to english", () => { + test.each([ + ["when no base_locale is set", {}], + ["when base_locale doesn't match a Flatpickr locale", { base_locale: "invalid-locale" }], + ["when base_locale is 'en'", { base_locale: "en" }], + ])("%s", async (_description, i18n) => { + const controller = new FlatpickrController(); + const locale = await controller.importFlatpickrLocale(i18n.base_locale); + expect(locale).toBeNull(); + }); + }); + + it("returns locale object for a supported locale (fr)", async () => { + const controller = new FlatpickrController(); + const locale = await controller.importFlatpickrLocale("fr"); + expect(locale).toBeInstanceOf(Object); + expect(locale).toHaveProperty("weekAbbreviation"); + expect(locale.weekAbbreviation).toBe("Sem"); + }); + }); +});