Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(time-picker): render meridiem first for korean locale #9842

Merged
merged 5 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading