From 805fe1268adb94143bd2fec10f6910f98dbdbae0 Mon Sep 17 00:00:00 2001 From: Matt Driscoll Date: Tue, 6 Aug 2024 14:06:02 -0700 Subject: [PATCH 1/2] fix(input-date-picker): fix selection for the "bs" and "it-CH" locales. #9387 --- .../calcite-components/src/components.d.ts | 100 ++++++++++++++++++ .../input-date-picker.e2e.ts | 36 +++++++ .../input-date-picker.stories.ts | 18 ++++ .../input-date-picker/input-date-picker.tsx | 32 +++--- .../src/utils/locale.spec.ts | 22 ++++ .../calcite-components/src/utils/locale.ts | 17 +++ 6 files changed, 213 insertions(+), 12 deletions(-) diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index 7ea17af005e..ec69dc49efc 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -9,93 +9,193 @@ import { Alignment, Appearance, CollapseDirection, FlipContext, IconType, Kind, import { RequestedItem } from "./components/accordion/interfaces"; import { IconNameOrString } from "./components/icon/interfaces"; import { RequestedItem as RequestedItem1 } from "./components/accordion-item/interfaces"; +import { ActionMessages } from "./components/action/assets/action/t9n"; import { FlipPlacement, LogicalPlacement, MenuPlacement, OverlayPositioning, ReferenceElement } from "./utils/floating-ui"; +import { ActionBarMessages } from "./components/action-bar/assets/action-bar/t9n"; import { Columns } from "./components/action-group/interfaces"; +import { ActionGroupMessages } from "./components/action-group/assets/action-group/t9n"; +import { ActionPadMessages } from "./components/action-pad/assets/action-pad/t9n"; import { AlertDuration, Sync } from "./components/alert/interfaces"; import { NumberingSystem } from "./utils/locale"; +import { AlertMessages } from "./components/alert/assets/alert/t9n"; import { HeadingLevel } from "./components/functional/Heading"; +import { BlockMessages } from "./components/block/assets/block/t9n"; import { BlockSectionToggleDisplay } from "./components/block-section/interfaces"; +import { BlockSectionMessages } from "./components/block-section/assets/block-section/t9n"; import { ButtonAlignment, DropdownIconType } from "./components/button/interfaces"; +import { ButtonMessages } from "./components/button/assets/button/t9n"; +import { CardMessages } from "./components/card/assets/card/t9n"; import { ArrowType, AutoplayType } from "./components/carousel/interfaces"; +import { CarouselMessages } from "./components/carousel/assets/carousel/t9n"; import { MutableValidityState } from "./utils/form"; +import { ChipMessages } from "./components/chip/assets/chip/t9n"; import { ColorValue, InternalColor } from "./components/color-picker/interfaces"; import { Format } from "./components/color-picker/utils"; +import { ColorPickerMessages } from "./components/color-picker/assets/color-picker/t9n"; import { ComboboxChildElement, SelectionDisplay } from "./components/combobox/interfaces"; +import { ComboboxMessages } from "./components/combobox/assets/combobox/t9n"; +import { DatePickerMessages } from "./components/date-picker/assets/date-picker/t9n"; import { DateLocaleData } from "./components/date-picker/utils"; import { HoverRange } from "./utils/date"; +import { DialogMessages } from "./components/dialog/assets/dialog/t9n"; import { OverlayPositioning as OverlayPositioning1 } from "./components"; import { DialogPlacement } from "./components/dialog/interfaces"; import { RequestedItem as RequestedItem2 } from "./components/dropdown-group/interfaces"; import { ItemKeyboardEvent } from "./components/dropdown/interfaces"; +import { FilterMessages } from "./components/filter/assets/filter/t9n"; import { FlowItemLikeElement } from "./components/flow/interfaces"; +import { FlowItemMessages } from "./components/flow-item/assets/flow-item/t9n"; import { ColorStop, DataSeries } from "./components/graph/interfaces"; +import { HandleMessages } from "./components/handle/assets/handle/t9n"; import { HandleChange, HandleNudge } from "./components/handle/interfaces"; +import { InlineEditableMessages } from "./components/inline-editable/assets/inline-editable/t9n"; import { InputPlacement } from "./components/input/interfaces"; +import { InputMessages } from "./components/input/assets/input/t9n"; +import { InputDatePickerMessages } from "./components/input-date-picker/assets/input-date-picker/t9n"; +import { InputNumberMessages } from "./components/input-number/assets/input-number/t9n"; +import { InputTextMessages } from "./components/input-text/assets/input-text/t9n"; +import { InputTimePickerMessages } from "./components/input-time-picker/assets/input-time-picker/t9n"; +import { TimePickerMessages } from "./components/time-picker/assets/time-picker/t9n"; +import { InputTimeZoneMessages } from "./components/input-time-zone/assets/input-time-zone/t9n"; import { OffsetStyle, TimeZoneMode } from "./components/input-time-zone/interfaces"; import { ListDragDetail } from "./components/list/interfaces"; import { ItemData } from "./components/list-item/interfaces"; +import { ListMessages } from "./components/list/assets/list/t9n"; import { SelectionAppearance } from "./components/list/resources"; +import { ListItemMessages } from "./components/list-item/assets/list-item/t9n"; +import { MenuMessages } from "./components/menu/assets/menu/t9n"; +import { MenuItemMessages } from "./components/menu-item/assets/menu-item/t9n"; import { MenuItemCustomEvent } from "./components/menu-item/interfaces"; import { MeterFillType, MeterLabelType } from "./components/meter/interfaces"; +import { ModalMessages } from "./components/modal/assets/modal/t9n"; +import { NoticeMessages } from "./components/notice/assets/notice/t9n"; +import { PaginationMessages } from "./components/pagination/assets/pagination/t9n"; +import { PanelMessages } from "./components/panel/assets/panel/t9n"; import { ItemData as ItemData1, ListFocusId } from "./components/pick-list/shared-list-logic"; import { ICON_TYPES } from "./components/pick-list/resources"; +import { PickListItemMessages } from "./components/pick-list-item/assets/pick-list-item/t9n"; +import { PopoverMessages } from "./components/popover/assets/popover/t9n"; +import { RatingMessages } from "./components/rating/assets/rating/t9n"; +import { ScrimMessages } from "./components/scrim/assets/scrim/t9n"; import { DisplayMode } from "./components/sheet/interfaces"; import { DisplayMode as DisplayMode1 } from "./components/shell-panel/interfaces"; +import { ShellPanelMessages } from "./components/shell-panel/assets/shell-panel/t9n"; import { DragDetail } from "./utils/sortableComponent"; import { StepperItemChangeEventDetail, StepperItemEventDetail, StepperItemKeyEventDetail, StepperLayout } from "./components/stepper/interfaces"; +import { StepperMessages } from "./components/stepper/assets/stepper/t9n"; +import { StepperItemMessages } from "./components/stepper-item/assets/stepper-item/t9n"; import { TabID, TabLayout, TabPosition } from "./components/tabs/interfaces"; +import { TabNavMessages } from "./components/tab-nav/assets/tab-nav/t9n"; import { Element } from "@stencil/core"; import { TabChangeEventDetail, TabCloseEventDetail } from "./components/tab/interfaces"; +import { TabTitleMessages } from "./components/tab-title/assets/tab-title/t9n"; import { RowType, TableInteractionMode, TableLayout, TableRowFocusEvent, TableSelectionDisplay } from "./components/table/interfaces"; +import { TableMessages } from "./components/table/assets/table/t9n"; +import { TableCellMessages } from "./components/table-cell/assets/table-cell/t9n"; +import { TableHeaderMessages } from "./components/table-header/assets/table-header/t9n"; +import { TextAreaMessages } from "./components/text-area/assets/text-area/t9n"; import { TileSelectType } from "./components/tile-select/interfaces"; import { TileSelectGroupLayout } from "./components/tile-select-group/interfaces"; +import { TipMessages } from "./components/tip/assets/tip/t9n"; +import { TipManagerMessages } from "./components/tip-manager/assets/tip-manager/t9n"; import { TreeItemSelectDetail } from "./components/tree-item/interfaces"; +import { ValueListMessages } from "./components/value-list/assets/value-list/t9n"; import { ListItemAndHandle } from "./components/value-list-item/interfaces"; export { Alignment, Appearance, CollapseDirection, FlipContext, IconType, Kind, Layout, LogicalFlowPosition, Position, Scale, SelectionAppearance as SelectionAppearance1, SelectionMode, Status, Width } from "./components/interfaces"; export { RequestedItem } from "./components/accordion/interfaces"; export { IconNameOrString } from "./components/icon/interfaces"; export { RequestedItem as RequestedItem1 } from "./components/accordion-item/interfaces"; +export { ActionMessages } from "./components/action/assets/action/t9n"; export { FlipPlacement, LogicalPlacement, MenuPlacement, OverlayPositioning, ReferenceElement } from "./utils/floating-ui"; +export { ActionBarMessages } from "./components/action-bar/assets/action-bar/t9n"; export { Columns } from "./components/action-group/interfaces"; +export { ActionGroupMessages } from "./components/action-group/assets/action-group/t9n"; +export { ActionPadMessages } from "./components/action-pad/assets/action-pad/t9n"; export { AlertDuration, Sync } from "./components/alert/interfaces"; export { NumberingSystem } from "./utils/locale"; +export { AlertMessages } from "./components/alert/assets/alert/t9n"; export { HeadingLevel } from "./components/functional/Heading"; +export { BlockMessages } from "./components/block/assets/block/t9n"; export { BlockSectionToggleDisplay } from "./components/block-section/interfaces"; +export { BlockSectionMessages } from "./components/block-section/assets/block-section/t9n"; export { ButtonAlignment, DropdownIconType } from "./components/button/interfaces"; +export { ButtonMessages } from "./components/button/assets/button/t9n"; +export { CardMessages } from "./components/card/assets/card/t9n"; export { ArrowType, AutoplayType } from "./components/carousel/interfaces"; +export { CarouselMessages } from "./components/carousel/assets/carousel/t9n"; export { MutableValidityState } from "./utils/form"; +export { ChipMessages } from "./components/chip/assets/chip/t9n"; export { ColorValue, InternalColor } from "./components/color-picker/interfaces"; export { Format } from "./components/color-picker/utils"; +export { ColorPickerMessages } from "./components/color-picker/assets/color-picker/t9n"; export { ComboboxChildElement, SelectionDisplay } from "./components/combobox/interfaces"; +export { ComboboxMessages } from "./components/combobox/assets/combobox/t9n"; +export { DatePickerMessages } from "./components/date-picker/assets/date-picker/t9n"; export { DateLocaleData } from "./components/date-picker/utils"; export { HoverRange } from "./utils/date"; +export { DialogMessages } from "./components/dialog/assets/dialog/t9n"; export { OverlayPositioning as OverlayPositioning1 } from "./components"; export { DialogPlacement } from "./components/dialog/interfaces"; export { RequestedItem as RequestedItem2 } from "./components/dropdown-group/interfaces"; export { ItemKeyboardEvent } from "./components/dropdown/interfaces"; +export { FilterMessages } from "./components/filter/assets/filter/t9n"; export { FlowItemLikeElement } from "./components/flow/interfaces"; +export { FlowItemMessages } from "./components/flow-item/assets/flow-item/t9n"; export { ColorStop, DataSeries } from "./components/graph/interfaces"; +export { HandleMessages } from "./components/handle/assets/handle/t9n"; export { HandleChange, HandleNudge } from "./components/handle/interfaces"; +export { InlineEditableMessages } from "./components/inline-editable/assets/inline-editable/t9n"; export { InputPlacement } from "./components/input/interfaces"; +export { InputMessages } from "./components/input/assets/input/t9n"; +export { InputDatePickerMessages } from "./components/input-date-picker/assets/input-date-picker/t9n"; +export { InputNumberMessages } from "./components/input-number/assets/input-number/t9n"; +export { InputTextMessages } from "./components/input-text/assets/input-text/t9n"; +export { InputTimePickerMessages } from "./components/input-time-picker/assets/input-time-picker/t9n"; +export { TimePickerMessages } from "./components/time-picker/assets/time-picker/t9n"; +export { InputTimeZoneMessages } from "./components/input-time-zone/assets/input-time-zone/t9n"; export { OffsetStyle, TimeZoneMode } from "./components/input-time-zone/interfaces"; export { ListDragDetail } from "./components/list/interfaces"; export { ItemData } from "./components/list-item/interfaces"; +export { ListMessages } from "./components/list/assets/list/t9n"; export { SelectionAppearance } from "./components/list/resources"; +export { ListItemMessages } from "./components/list-item/assets/list-item/t9n"; +export { MenuMessages } from "./components/menu/assets/menu/t9n"; +export { MenuItemMessages } from "./components/menu-item/assets/menu-item/t9n"; export { MenuItemCustomEvent } from "./components/menu-item/interfaces"; export { MeterFillType, MeterLabelType } from "./components/meter/interfaces"; +export { ModalMessages } from "./components/modal/assets/modal/t9n"; +export { NoticeMessages } from "./components/notice/assets/notice/t9n"; +export { PaginationMessages } from "./components/pagination/assets/pagination/t9n"; +export { PanelMessages } from "./components/panel/assets/panel/t9n"; export { ItemData as ItemData1, ListFocusId } from "./components/pick-list/shared-list-logic"; export { ICON_TYPES } from "./components/pick-list/resources"; +export { PickListItemMessages } from "./components/pick-list-item/assets/pick-list-item/t9n"; +export { PopoverMessages } from "./components/popover/assets/popover/t9n"; +export { RatingMessages } from "./components/rating/assets/rating/t9n"; +export { ScrimMessages } from "./components/scrim/assets/scrim/t9n"; export { DisplayMode } from "./components/sheet/interfaces"; export { DisplayMode as DisplayMode1 } from "./components/shell-panel/interfaces"; +export { ShellPanelMessages } from "./components/shell-panel/assets/shell-panel/t9n"; export { DragDetail } from "./utils/sortableComponent"; export { StepperItemChangeEventDetail, StepperItemEventDetail, StepperItemKeyEventDetail, StepperLayout } from "./components/stepper/interfaces"; +export { StepperMessages } from "./components/stepper/assets/stepper/t9n"; +export { StepperItemMessages } from "./components/stepper-item/assets/stepper-item/t9n"; export { TabID, TabLayout, TabPosition } from "./components/tabs/interfaces"; +export { TabNavMessages } from "./components/tab-nav/assets/tab-nav/t9n"; export { Element } from "@stencil/core"; export { TabChangeEventDetail, TabCloseEventDetail } from "./components/tab/interfaces"; +export { TabTitleMessages } from "./components/tab-title/assets/tab-title/t9n"; export { RowType, TableInteractionMode, TableLayout, TableRowFocusEvent, TableSelectionDisplay } from "./components/table/interfaces"; +export { TableMessages } from "./components/table/assets/table/t9n"; +export { TableCellMessages } from "./components/table-cell/assets/table-cell/t9n"; +export { TableHeaderMessages } from "./components/table-header/assets/table-header/t9n"; +export { TextAreaMessages } from "./components/text-area/assets/text-area/t9n"; export { TileSelectType } from "./components/tile-select/interfaces"; export { TileSelectGroupLayout } from "./components/tile-select-group/interfaces"; +export { TipMessages } from "./components/tip/assets/tip/t9n"; +export { TipManagerMessages } from "./components/tip-manager/assets/tip-manager/t9n"; export { TreeItemSelectDetail } from "./components/tree-item/interfaces"; +export { ValueListMessages } from "./components/value-list/assets/value-list/t9n"; export { ListItemAndHandle } from "./components/value-list-item/interfaces"; export namespace Components { interface CalciteAccordion { diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts index f0f5b005765..00a24850ac3 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.e2e.ts @@ -707,6 +707,42 @@ describe("calcite-input-date-picker", () => { expect(await inputDatePicker.getProperty("value")).toBe("2023-05-01"); }); + + it("parses/formats bosnian calendar locales when date is selected", async () => { + const page = await newE2EPage(); + await page.setContent(``); + const inputDatePicker = await page.find("calcite-input-date-picker"); + const calciteInputDatePickerOpenEvent = page.waitForEvent("calciteInputDatePickerOpen"); + + await inputDatePicker.click(); + await calciteInputDatePickerOpenEvent; + + await selectDayInMonth(page, 1); + await inputDatePicker.callMethod("blur"); + + expect(await inputDatePicker.getProperty("value")).toBe("2023-05-01"); + + const inputText = await page.find("calcite-input-date-picker >>> calcite-input-text"); + expect(await inputText.getProperty("value")).toBe("01.05.2023."); + }); + + it("parses/formats italian (Switzerland) calendar locales when date is selected", async () => { + const page = await newE2EPage(); + await page.setContent(``); + const inputDatePicker = await page.find("calcite-input-date-picker"); + const calciteInputDatePickerOpenEvent = page.waitForEvent("calciteInputDatePickerOpen"); + + await inputDatePicker.click(); + await calciteInputDatePickerOpenEvent; + + await selectDayInMonth(page, 1); + await inputDatePicker.callMethod("blur"); + + expect(await inputDatePicker.getProperty("value")).toBe("2023-05-01"); + + const inputText = await page.find("calcite-input-date-picker >>> calcite-input-text"); + expect(await inputText.getProperty("value")).toBe("1.5.2023"); + }); }); describe("clicking in the calendar popup", () => { diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts index 45968206cee..9045bc9a854 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts @@ -247,3 +247,21 @@ export const Focus = (): string => Focus.parameters = { chromatic: { delay: 2000 }, }; + +export const bsLocale = (): string => html` +
+ +`; + +export const itCHLocale = (): string => html` +
+ +`; diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index 5009fcd90a1..d4b0d951c86 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -65,6 +65,7 @@ import { LocalizedComponent, NumberingSystem, numberStringFormatter, + getDateFormatSupportedLocale, } from "../../utils/locale"; import { onToggleOpenCloseComponent, OpenCloseComponent } from "../../utils/openCloseComponent"; import { DatePickerMessages } from "../date-picker/assets/date-picker/t9n"; @@ -738,6 +739,8 @@ export class InputDatePicker defaultValue: InputDatePicker["value"]; + dateTimeFormat: Intl.DateTimeFormat; + @State() datePickerActiveDate: Date; @State() defaultMessages: InputDatePickerMessages; @@ -750,6 +753,21 @@ export class InputDatePicker this.loadLocaleData(); } + @Watch("effectiveLocale") + @Watch("numberingSystem") + handleDateTimeFormatChange(): void { + const formattingOptions: Intl.DateTimeFormatOptions = { + // we explicitly set numberingSystem to prevent the browser-inferred value + // see https://github.com/Esri/calcite-design-system/issues/3079#issuecomment-1168964195 for more info + numberingSystem: getSupportedNumberingSystem(this.numberingSystem), + }; + + this.dateTimeFormat = new Intl.DateTimeFormat( + getDateFormatSupportedLocale(this.effectiveLocale), + formattingOptions, + ); + } + @State() focusedInput: "start" | "end" = "start"; @State() private localeData: DateLocaleData; @@ -1066,18 +1084,8 @@ export class InputDatePicker ) : null; - const formattingOptions = { - // we explicitly set numberingSystem to prevent the browser-inferred value - // see https://github.com/Esri/calcite-design-system/issues/3079#issuecomment-1168964195 for more info - numberingSystem: getSupportedNumberingSystem(this.numberingSystem), - }; - - const localizedDate = date && date.toLocaleDateString(this.effectiveLocale, formattingOptions); - const localizedEndDate = - endDate && endDate.toLocaleDateString(this.effectiveLocale, formattingOptions); - - this.setInputValue(localizedDate ?? "", "start"); - this.setInputValue((this.range && localizedEndDate) ?? "", "end"); + this.setInputValue((date && this.dateTimeFormat.format(date)) ?? "", "start"); + this.setInputValue((this.range && endDate && this.dateTimeFormat.format(endDate)) ?? "", "end"); } private setInputValue = (newValue: string, input: "start" | "end" = "start"): void => { diff --git a/packages/calcite-components/src/utils/locale.spec.ts b/packages/calcite-components/src/utils/locale.spec.ts index 58cd0b4a197..10dee8bb579 100644 --- a/packages/calcite-components/src/utils/locale.spec.ts +++ b/packages/calcite-components/src/utils/locale.spec.ts @@ -2,6 +2,7 @@ import { dateTimeFormatCache, defaultLocale, defaultNumberingSystem, + getDateFormatSupportedLocale, getDateTimeFormat, getSupportedLocale, locales, @@ -230,3 +231,24 @@ describe("getSupportedLocale", () => { }); }); }); + +describe("getDateFormatSupportedLocale", () => { + function assertAllContexts(locale: string, expectedLocale: string): void { + expect(getDateFormatSupportedLocale(locale)).toBe(expectedLocale); + expect(getDateFormatSupportedLocale(locale)).toBe(expectedLocale); + } + + describe("locale mappings", () => { + it("maps `it-CH` to `de-CH`", () => { + assertAllContexts("it-CH", "de-CH"); + }); + + it("maps `bs` to `bs-Cyrl`", () => { + assertAllContexts("bs", "bs-Cyrl"); + }); + + it("maps `en` to `en`", () => { + expect(getDateFormatSupportedLocale("en")).toBe("en"); + }); + }); +}); diff --git a/packages/calcite-components/src/utils/locale.ts b/packages/calcite-components/src/utils/locale.ts index 85d2b2ce0ff..f32ac0992ad 100644 --- a/packages/calcite-components/src/utils/locale.ts +++ b/packages/calcite-components/src/utils/locale.ts @@ -175,6 +175,23 @@ export function getSupportedLocale(locale: string, context: "cldr" | "t9n" = "cl return locale; } +/** + * Gets the locale that best matches the context for date formatting. + * + * @param locale – the BCP 47 locale code + * @returns {string} a BCP 47 locale code + */ +export function getDateFormatSupportedLocale(locale: string): string { + switch (locale) { + case "it-CH": + return "de-CH"; + case "bs": + return "bs-Cyrl"; + default: + return locale; + } +} + /** * This interface is for components that need to determine locale from the lang attribute. */ From d89ad71209849fa5df08f3a010728a85bd01417f Mon Sep 17 00:00:00 2001 From: Matt Driscoll Date: Wed, 7 Aug 2024 13:37:53 -0700 Subject: [PATCH 2/2] review fixes --- .../input-date-picker.stories.ts | 17 +++-------------- .../input-date-picker/input-date-picker.tsx | 2 +- .../calcite-components/src/utils/locale.spec.ts | 7 +++---- packages/calcite-components/src/utils/locale.ts | 4 ++++ 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts b/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts index 9045bc9a854..f553601868f 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.stories.ts @@ -248,20 +248,9 @@ Focus.parameters = { chromatic: { delay: 2000 }, }; -export const bsLocale = (): string => html` +export const localeFormatting = (): string => html`
- -`; - -export const itCHLocale = (): string => html` -
- +
`; diff --git a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx index d4b0d951c86..e8a0c7da93f 100644 --- a/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx +++ b/packages/calcite-components/src/components/input-date-picker/input-date-picker.tsx @@ -739,7 +739,7 @@ export class InputDatePicker defaultValue: InputDatePicker["value"]; - dateTimeFormat: Intl.DateTimeFormat; + private dateTimeFormat: Intl.DateTimeFormat; @State() datePickerActiveDate: Date; diff --git a/packages/calcite-components/src/utils/locale.spec.ts b/packages/calcite-components/src/utils/locale.spec.ts index 10dee8bb579..558b762d2dc 100644 --- a/packages/calcite-components/src/utils/locale.spec.ts +++ b/packages/calcite-components/src/utils/locale.spec.ts @@ -233,18 +233,17 @@ describe("getSupportedLocale", () => { }); describe("getDateFormatSupportedLocale", () => { - function assertAllContexts(locale: string, expectedLocale: string): void { - expect(getDateFormatSupportedLocale(locale)).toBe(expectedLocale); + function assertLocaleMapping(locale: string, expectedLocale: string): void { expect(getDateFormatSupportedLocale(locale)).toBe(expectedLocale); } describe("locale mappings", () => { it("maps `it-CH` to `de-CH`", () => { - assertAllContexts("it-CH", "de-CH"); + assertLocaleMapping("it-CH", "de-CH"); }); it("maps `bs` to `bs-Cyrl`", () => { - assertAllContexts("bs", "bs-Cyrl"); + assertLocaleMapping("bs", "bs-Cyrl"); }); it("maps `en` to `en`", () => { diff --git a/packages/calcite-components/src/utils/locale.ts b/packages/calcite-components/src/utils/locale.ts index f32ac0992ad..6429655fc58 100644 --- a/packages/calcite-components/src/utils/locale.ts +++ b/packages/calcite-components/src/utils/locale.ts @@ -178,6 +178,10 @@ export function getSupportedLocale(locale: string, context: "cldr" | "t9n" = "cl /** * Gets the locale that best matches the context for date formatting. * + * Intl date formatting has some quirks with certain locales. This handles those quirks by mapping a locale to another for date formatting. + * + * See https://github.com/Esri/calcite-design-system/issues/9387 + * * @param locale – the BCP 47 locale code * @returns {string} a BCP 47 locale code */