Skip to content

Commit

Permalink
fix(time-picker): render meridiem first for korean locale (#9842)
Browse files Browse the repository at this point in the history
**Related Issue:** #9720

## Summary

This PR fixes an issue where a starting time value past noon was not
displaying the meridiem first in the `calcite-time-picker`.
  • Loading branch information
eriklharper authored and github-actions[bot] committed Jul 30, 2024
1 parent df7da4b commit 897f924
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 48 deletions.
50 changes: 26 additions & 24 deletions packages/calcite-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: `<calcite-time-picker lang="ko"></calcite-time-picker>`,
});

const meridiemStart = await page.find(`calcite-time-picker >>> .${CSS.meridiemStart}`);
expect(meridiemStart).toBeTruthy();
});
});

describe("translation support", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,8 @@ export const simple = (args: TimePickerStoryArgs): string => html`
>
</calcite-time-picker>
`;

export const koreanLocale_TestOnly = (): string => html`
<calcite-time-picker lang="ko" value="10:37" step="1"> </calcite-time-picker>
<calcite-time-picker lang="ko" value="14:37" step="1"> </calcite-time-picker>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
getLocalizedDecimalSeparator,
getLocalizedTimePartSuffix,
getMeridiem,
getTimeParts,
getMeridiemOrder,
HourCycle,
isValidTime,
localizeTimePart,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -871,25 +869,14 @@ 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);
this.localizedDecimalSeparator = getLocalizedDecimalSeparator(
this.effectiveLocale,
this.numberingSystem,
);
this.meridiemOrder = getMeridiemOrder(this.effectiveLocale);
this.setValue(this.sanitizeValue(this.value));
}

Expand All @@ -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<void> {
Expand Down
11 changes: 10 additions & 1 deletion packages/calcite-components/src/demos/input-time-picker.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,17 @@ <h3>24-Hour Locales</h3>
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");

inputTimePickerEl.setAttribute("lang", locale);
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);
Expand All @@ -88,6 +91,9 @@ <h3>24-Hour Locales</h3>
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)`));
Expand All @@ -107,6 +113,9 @@ <h3>24-Hour Locales</h3>
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)`));
Expand Down
30 changes: 29 additions & 1 deletion packages/calcite-components/src/utils/time.spec.ts
Original file line number Diff line number Diff line change
@@ -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", () => {
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 897f924

Please sign in to comment.