From 54a562d68edefdce4d5ce10e10a413da0339673e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Tajes=20Vidal?= Date: Wed, 20 Nov 2024 10:22:26 +0100 Subject: [PATCH] NEXT-39641 - Add datepicker format datetime depending on the locale --- .changeset/soft-suits-jog.md | 5 +++ .../form/mt-datepicker/mt-datepicker.spec.ts | 26 ++++++++++- .../form/mt-datepicker/mt-datepicker.vue | 45 +++++++++++++++++-- 3 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 .changeset/soft-suits-jog.md diff --git a/.changeset/soft-suits-jog.md b/.changeset/soft-suits-jog.md new file mode 100644 index 000000000..2de70aa73 --- /dev/null +++ b/.changeset/soft-suits-jog.md @@ -0,0 +1,5 @@ +--- +"@shopware-ag/meteor-component-library": major +--- + +Added format to date and time in the datepicker depending on the locale. This means that the date and time are displayed in the format that is used in the locale of the user. diff --git a/packages/component-library/src/components/form/mt-datepicker/mt-datepicker.spec.ts b/packages/component-library/src/components/form/mt-datepicker/mt-datepicker.spec.ts index cc732c13d..b070afac4 100644 --- a/packages/component-library/src/components/form/mt-datepicker/mt-datepicker.spec.ts +++ b/packages/component-library/src/components/form/mt-datepicker/mt-datepicker.spec.ts @@ -36,7 +36,7 @@ describe("src/app/component/form/mt-datepicker", () => { wrapper = await createWrapper(); const flatpickrInput = wrapper.find(".flatpickr-input"); - expect(flatpickrInput.attributes().placeholder).toBe("Y-m-d"); + expect(flatpickrInput.attributes().placeholder).toBe("m/d/Y"); }); it("should show the placeholderText, when provided", async () => { @@ -237,4 +237,28 @@ describe("src/app/component/form/mt-datepicker", () => { // Skip this test because data-fns-tz is not working correctly in the test environment // expect(wrapper.emitted('update:modelValue')[0]).toStrictEqual(['2023-03-21T23:00:00.000Z']); }); + + it("should support other locales formats", async () => { + wrapper = await createWrapper({ + props: { + locale: "en-Us", + modelValue: "2023-03-27T14:00:00.000+00:00", + dateType: "datetime", + timeZone: "Europe/Berlin", + }, + }); + + expect(wrapper.find("input.form-control").element.value).toMatch(/03\/27\/2023, 4:00\s?PM/); + + wrapper = await createWrapper({ + props: { + locale: "en-Uk", + modelValue: "2023-03-27T14:00:00.000+00:00", + dateType: "datetime", + timeZone: "Europe/Berlin", + }, + }); + + expect(wrapper.find("input.form-control").element.value).toMatch(/27\/03\/2023, 16:00/); + }); }); diff --git a/packages/component-library/src/components/form/mt-datepicker/mt-datepicker.vue b/packages/component-library/src/components/form/mt-datepicker/mt-datepicker.vue index 3fd6ec829..97c7fd1df 100644 --- a/packages/component-library/src/components/form/mt-datepicker/mt-datepicker.vue +++ b/packages/component-library/src/components/form/mt-datepicker/mt-datepicker.vue @@ -284,6 +284,12 @@ export default defineComponent({ showTimeZoneHint() { return this.dateType === "datetime" && !this.hideHint; }, + + is24HourFormat() { + const formatter = new Intl.DateTimeFormat(this.locale, { hour: "numeric" }); + const intlOptions = formatter.resolvedOptions(); + return !intlOptions.hour12; + }, }, watch: { @@ -553,19 +559,32 @@ export default defineComponent({ createConfig() { let dateFormat = "Y-m-dTH:i:S"; - let altFormat = "Y-m-d H:i"; + let altFormat = this.getDateStringFormat({ + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + }); if (this.dateType === "time") { dateFormat = "H:i:S"; - altFormat = "H:i"; + altFormat = this.getDateStringFormat({ + hour: "2-digit", + minute: "2-digit", + }); } if (this.dateType === "date") { - altFormat = "Y-m-d"; + altFormat = this.getDateStringFormat({ + year: "numeric", + month: "2-digit", + day: "2-digit", + }); } this.defaultConfig = { - time_24hr: true, + time_24hr: this.is24HourFormat, locale: this.locale, dateFormat, altInput: true, @@ -573,6 +592,24 @@ export default defineComponent({ allowInput: true, }; }, + + getDateStringFormat(options: Intl.DateTimeFormatOptions) { + const formatter = new Intl.DateTimeFormat(this.locale, options); + const parts = formatter.formatToParts(new Date(2000, 0, 1, 0, 0, 0)); + const flatpickrMapping: Partial> = { + // https://flatpickr.js.org/formatting/ + year: "Y", // 4-digit year + month: "m", // 2-digit month + day: "d", // 2-digit day + hour: this.is24HourFormat ? "H" : "h", // 24-hour or 12-hour + minute: "i", // 2-digit minute + dayPeriod: "K", // AM/PM + }; + // 'literal' parts are the separators + return parts + .map((part) => (part.type === "literal" ? part.value : flatpickrMapping[part.type])) + .join(""); + }, }, });