diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index a9bcda91037..1c920006dcc 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -83,6 +83,7 @@ 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"; @@ -175,6 +176,7 @@ 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"; @@ -983,7 +985,7 @@ export namespace Components { "status": Status; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity": MutableValidityState; @@ -1347,7 +1349,7 @@ export namespace Components { "validationMessage": string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity": MutableValidityState; @@ -2282,7 +2284,7 @@ export namespace Components { "validationMessage": string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity": MutableValidityState; @@ -2405,7 +2407,7 @@ export namespace Components { "validationMessage": string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity": MutableValidityState; @@ -2600,7 +2602,7 @@ export namespace Components { "validationMessage": string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity": MutableValidityState; @@ -2741,7 +2743,7 @@ export namespace Components { "validationMessage": string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity": MutableValidityState; @@ -2841,7 +2843,7 @@ export namespace Components { "validationMessage": string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity": MutableValidityState; @@ -2929,7 +2931,7 @@ export namespace Components { "validationMessage": string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity": MutableValidityState; @@ -4225,7 +4227,7 @@ export namespace Components { "validationMessage": string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity": MutableValidityState; @@ -4320,7 +4322,7 @@ export namespace Components { "validationMessage": string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity": MutableValidityState; @@ -5230,7 +5232,7 @@ export namespace Components { "placeholder": string; /** * When `true`, the component's `value` can be read, but cannot be modified. - * @readonly + * @readonly * @mdn [readOnly](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly) */ "readOnly": boolean; @@ -5274,7 +5276,7 @@ export namespace Components { "validationMessage": string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity": MutableValidityState; @@ -8795,7 +8797,7 @@ declare namespace LocalJSX { "status"?: Status; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity"?: MutableValidityState; @@ -9188,7 +9190,7 @@ declare namespace LocalJSX { "validationMessage"?: string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity"?: MutableValidityState; @@ -10164,7 +10166,7 @@ declare namespace LocalJSX { "validationMessage"?: string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity"?: MutableValidityState; @@ -10298,7 +10300,7 @@ declare namespace LocalJSX { "validationMessage"?: string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity"?: MutableValidityState; @@ -10495,7 +10497,7 @@ declare namespace LocalJSX { "validationMessage"?: string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity"?: MutableValidityState; @@ -10641,7 +10643,7 @@ declare namespace LocalJSX { "validationMessage"?: string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity"?: MutableValidityState; @@ -10752,7 +10754,7 @@ declare namespace LocalJSX { "validationMessage"?: string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity"?: MutableValidityState; @@ -10859,7 +10861,7 @@ declare namespace LocalJSX { "validationMessage"?: string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity"?: MutableValidityState; @@ -12218,7 +12220,7 @@ declare namespace LocalJSX { "validationMessage"?: string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity"?: MutableValidityState; @@ -12317,7 +12319,7 @@ declare namespace LocalJSX { "validationMessage"?: string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity"?: MutableValidityState; @@ -13264,7 +13266,7 @@ declare namespace LocalJSX { "placeholder"?: string; /** * When `true`, the component's `value` can be read, but cannot be modified. - * @readonly + * @readonly * @mdn [readOnly](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly) */ "readOnly"?: boolean; @@ -13300,7 +13302,7 @@ declare namespace LocalJSX { "validationMessage"?: string; /** * The current validation state of the component. - * @readonly + * @readonly * @mdn [ValidityState](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) */ "validity"?: MutableValidityState; diff --git a/packages/calcite-components/src/components/time-picker/time-picker.e2e.ts b/packages/calcite-components/src/components/time-picker/time-picker.e2e.ts index da138405bce..c166db1756a 100644 --- a/packages/calcite-components/src/components/time-picker/time-picker.e2e.ts +++ b/packages/calcite-components/src/components/time-picker/time-picker.e2e.ts @@ -1168,6 +1168,15 @@ describe("calcite-time-picker", () => { const meridiemStart = await page.find(`calcite-time-picker >>> .${CSS.meridiemStart}`); expect(meridiemStart).toBeTruthy(); }); + + it("meridiem is to the left of the time for korean locale", async () => { + const page = await newE2EPage({ + html: ``, + }); + + const meridiemStart = await page.find(`calcite-time-picker >>> .${CSS.meridiemStart}`); + expect(meridiemStart).toBeTruthy(); + }); }); describe("translation support", () => { diff --git a/packages/calcite-components/src/components/time-picker/time-picker.stories.ts b/packages/calcite-components/src/components/time-picker/time-picker.stories.ts index 3c5968ebbf7..8af9d670f01 100644 --- a/packages/calcite-components/src/components/time-picker/time-picker.stories.ts +++ b/packages/calcite-components/src/components/time-picker/time-picker.stories.ts @@ -61,3 +61,8 @@ export const simple = (args: TimePickerStoryArgs): string => html` > `; + +export const koreanLocale_TestOnly = (): string => html` + + +`; diff --git a/packages/calcite-components/src/components/time-picker/time-picker.tsx b/packages/calcite-components/src/components/time-picker/time-picker.tsx index ee7e644915e..3851409dd9d 100644 --- a/packages/calcite-components/src/components/time-picker/time-picker.tsx +++ b/packages/calcite-components/src/components/time-picker/time-picker.tsx @@ -33,7 +33,7 @@ import { getLocalizedDecimalSeparator, getLocalizedTimePartSuffix, getMeridiem, - getTimeParts, + getMeridiemOrder, HourCycle, isValidTime, localizeTimePart, @@ -752,8 +752,6 @@ export class TimePicker if (localizedMeridiem) { this.localizedMeridiem = localizedMeridiem; this.meridiem = getMeridiem(this.hour); - const formatParts = getTimeParts({ value, locale, numberingSystem }); - this.meridiemOrder = this.getMeridiemOrder(formatParts); } } else { this.hour = null; @@ -871,18 +869,6 @@ export class TimePicker this.showFractionalSecond = decimalPlaces(this.step) > 0; } - private getMeridiemOrder(formatParts: Intl.DateTimeFormatPart[]): number { - const locale = this.effectiveLocale; - const isRTLKind = locale === "ar" || locale === "he"; - if (formatParts && !isRTLKind) { - const index = formatParts.findIndex((parts: { type: string; value: string }) => { - return parts.value === this.localizedMeridiem; - }); - return index; - } - return 0; - } - private updateLocale() { updateMessages(this, this.effectiveLocale); this.hourCycle = getLocaleHourCycle(this.effectiveLocale, this.numberingSystem); @@ -890,6 +876,7 @@ export class TimePicker this.effectiveLocale, this.numberingSystem, ); + this.meridiemOrder = getMeridiemOrder(this.effectiveLocale); this.setValue(this.sanitizeValue(this.value)); } @@ -904,13 +891,6 @@ export class TimePicker this.updateLocale(); connectMessages(this); this.toggleSecond(); - this.meridiemOrder = this.getMeridiemOrder( - getTimeParts({ - value: "0:00:00", - locale: this.effectiveLocale, - numberingSystem: this.numberingSystem, - }), - ); } async componentWillLoad(): Promise { diff --git a/packages/calcite-components/src/demos/input-time-picker.html b/packages/calcite-components/src/demos/input-time-picker.html index b098a9221c7..50918a41ffa 100644 --- a/packages/calcite-components/src/demos/input-time-picker.html +++ b/packages/calcite-components/src/demos/input-time-picker.html @@ -61,7 +61,7 @@

24-Hour Locales

const currentDate = new Date(); const currentTime = `${currentDate.getHours()}:${currentDate.getMinutes()}:${currentDate.getSeconds()}`; - locales.forEach(({ locale, name, numberingSystem, hourCycle }) => { + locales.forEach(({ locale, name, numberingSystem, hourCycle, dir }) => { let labelEl = document.createElement("calcite-label"); let inputTimePickerEl = document.createElement("calcite-input-time-picker"); @@ -69,6 +69,9 @@

24-Hour Locales

if (numberingSystem) { inputTimePickerEl.setAttribute("numbering-system", numberingSystem); } + if (dir) { + inputTimePickerEl.setAttribute("dir", dir); + } inputTimePickerEl.setAttribute("value", "10:00:00"); labelEl.append(document.createTextNode(`${name} (${locale})`)); labelEl.append(inputTimePickerEl); @@ -88,6 +91,9 @@

24-Hour Locales

if (numberingSystem) { inputTimePickerEl.setAttribute("numbering-system", numberingSystem); } + if (dir) { + inputTimePickerEl.setAttribute("dir", dir); + } inputTimePickerEl.setAttribute("step", 1); inputTimePickerEl.setAttribute("value", "10:00"); labelEl.append(document.createTextNode(`${name} (${locale}) (seconds)`)); @@ -107,6 +113,9 @@

24-Hour Locales

if (numberingSystem) { inputTimePickerEl.setAttribute("numbering-system", numberingSystem); } + if (dir) { + inputTimePickerEl.setAttribute("dir", dir); + } inputTimePickerEl.setAttribute("step", 0.001); inputTimePickerEl.setAttribute("value", "10:00:00.001"); labelEl.append(document.createTextNode(`${name} (${locale}) (milliseconds)`)); diff --git a/packages/calcite-components/src/utils/time.spec.ts b/packages/calcite-components/src/utils/time.spec.ts index 03acc940165..698d6d515d9 100644 --- a/packages/calcite-components/src/utils/time.spec.ts +++ b/packages/calcite-components/src/utils/time.spec.ts @@ -1,4 +1,11 @@ -import { formatTimePart, isValidTime, localizeTimeStringToParts, parseTimeString, toISOTimeString } from "./time"; +import { + formatTimePart, + getMeridiemOrder, + isValidTime, + localizeTimeStringToParts, + parseTimeString, + toISOTimeString, +} from "./time"; describe("formatTimePart", () => { it("returns decimals less than 1 with leading and trailing zeros to match the provided length", () => { @@ -26,6 +33,27 @@ describe("formatTimePart", () => { }); }); +describe("getMeridiemOrder", () => { + it("returns 0 for arabic lang", () => { + expect(getMeridiemOrder("ar")).toEqual(0); + }); + it("returns 0 for chinese (hong kong) lang", () => { + expect(getMeridiemOrder("zh-HK")).toEqual(0); + }); + it("returns 0 for hebrew lang", () => { + expect(getMeridiemOrder("he")).toEqual(0); + }); + it("returns 0 for korean lang", () => { + expect(getMeridiemOrder("ko")).toEqual(0); + }); + it("returns non-zero for ltr langs", () => { + expect(getMeridiemOrder("el")).not.toEqual(0); + expect(getMeridiemOrder("en")).not.toEqual(0); + expect(getMeridiemOrder("es")).not.toEqual(0); + expect(getMeridiemOrder("hi")).not.toEqual(0); + }); +}); + describe("isValidTime", () => { it("returns true when time string contains fractional seconds", () => { expect(isValidTime("12:30:45.0")).toBe(true); diff --git a/packages/calcite-components/src/utils/time.ts b/packages/calcite-components/src/utils/time.ts index db5f5d3626c..d6d33bb789a 100644 --- a/packages/calcite-components/src/utils/time.ts +++ b/packages/calcite-components/src/utils/time.ts @@ -167,6 +167,19 @@ export function getMeridiem(hour: string): Meridiem { return hourAsNumber >= 0 && hourAsNumber <= 11 ? "AM" : "PM"; } +export function getMeridiemOrder(locale: string): number { + const isRtl = locale === "ar" || locale === "he"; + if (isRtl) { + return 0; + } + const timeParts = getTimeParts({ + value: "00:00:00", + locale, + numberingSystem: "latn", + }); + return timeParts.findIndex((value) => value.type === "dayPeriod"); +} + export function isValidTime(value: string): boolean { if (!value || value.startsWith(":") || value.endsWith(":")) { return false;