Skip to content

Commit

Permalink
Merge branch 'main' into migrate-mt-data-table-over-to-custom-built-i18n
Browse files Browse the repository at this point in the history
  • Loading branch information
Haberkamp authored Nov 4, 2024
2 parents 10a2cbf + 4917db0 commit 0efa307
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 25 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
ref="selectWrapper"
class="mt-select__selection"
tabindex="0"
@click="expand"
@click.stop="expand"
@focus="expand"
@keydown.tab="collapse"
@keydown.esc="collapse"
Expand All @@ -31,25 +31,32 @@
name="mt-select-selection"
v-bind="{ identification, error, disabled, size, expand, collapse }"
/>
<div class="mt-select__selection-indicators">
<mt-loader v-if="isLoading" class="mt-select__select-indicator" size="16px" />

<button
v-if="!disabled && showClearableButton"
class="mt-select__select-indicator-hitbox"
data-clearable-button
data-testid="select-clear-button"
@click.prevent.stop="emitClear"
@keydown.tab.stop="focusParentSelect"
>
<mt-icon
class="mt-select__select-indicator mt-select__select-indicator-clear"
name="regular-times-xxs"
/>
</button>

<mt-icon class="mt-select__select-indicator" name="solid-chevron-down-xs" />
</div>
</div>

<div class="mt-select__selection-indicators">
<mt-loader v-if="isLoading" class="mt-select__select-indicator" size="16px" />

<button
v-if="!disabled && showClearableButton"
class="mt-select__select-indicator-hitbox"
data-clearable-button
data-testid="select-clear-button"
@click.prevent.stop="emitClear"
@keydown.tab.stop="focusParentSelect"
>
<mt-icon
class="mt-select__select-indicator mt-select__select-indicator-clear"
name="regular-times-xxs"
/>
</button>

<mt-icon
class="mt-select__select-indicator"
data-testid="mt-select__select-indicator"
:class="{ 'mt-select__select-indicator-rotated': expanded }"
name="solid-chevron-down-xxs"
@click.stop="toggleExpand"
/>
</div>

<template v-if="expanded">
Expand Down Expand Up @@ -354,6 +361,11 @@ $mt-select-focus-transition: all ease-in-out 0.2s;
.mt-select__select-indicator {
flex-shrink: 0;
cursor: pointer;
transition: all 0.3s ease-in-out;
}
.mt-select__select-indicator-rotated {
transform: rotate(180deg);
}
.mt-select__select-indicator-clear {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,3 +407,26 @@ export const VisualTestEnsureCorrectMultiSelectionWrapping: MtSelectStory = {
await userEvent.click(loadMoreButton);
},
};

export const VisualTestEnsureSelectionOpensViaIndicators: MtSelectStory = {
name: "Should open selection via indicators",
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await waitUntil(() =>
document.querySelector('.mt-select-selection-list__item[title="Option B"]'),
);

// open selection via indicator
await userEvent.click(canvas.getByTestId("mt-select__select-indicator"));

// selection should open
const popover = within(
document.querySelector(".mt-popover-deprecated__wrapper") as HTMLElement,
);
await waitUntil(() => popover.getByTestId("mt-select-option--a"));

// close selection via indicator
await userEvent.click(canvas.getByTestId("mt-select__select-indicator"));
expect(document.querySelector(".mt-popover-deprecated__wrapper")).toBeNull();
},
};
60 changes: 60 additions & 0 deletions packages/component-library/src/composables/useI18n.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,64 @@ describe("useI18n", () => {

expect(screen.getByText("Hello, {name}!")).toBeInTheDocument();
});

it("translates the singular version", () => {
render({
setup() {
const { t } = useI18n({
messages: { en: { apple: "apple | apples" } },
});

return { t };
},
template: "{{ t('apple', { n: 1 }) }}",
});

expect(screen.getByText("apple")).toBeInTheDocument();
});

it("translates the pluralized version", () => {
render({
setup() {
const { t } = useI18n({
messages: { en: { apple: "apple | apples" } },
});

return { t };
},
template: "{{ t('apple', { n: 2 }) }}",
});

expect(screen.getByText("apples")).toBeInTheDocument;
});

it("translates the 'none' version", () => {
render({
setup() {
const { t } = useI18n({
messages: { en: { apple: "no apple | apple | apples" } },
});

return { t };
},
template: "{{ t('apple', { n: 0 }) }}",
});

expect(screen.getByText("no apple")).toBeInTheDocument();
});

it("translates the pluralized version with custom values", () => {
render({
setup() {
const { t } = useI18n({
messages: { en: { apple: "no apple | apple | {n} apples" } },
});

return { t };
},
template: "{{ t('apple', { n: 3 }) }}",
});

expect(screen.getByText("3 apples")).toBeInTheDocument();
});
});
35 changes: 30 additions & 5 deletions packages/component-library/src/composables/useI18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ const defaultI18nState = {

const i18nInjectionKey = Symbol("mt-i18n");

function limit(value: number, max: number) {
return Math.min(value, max);
}

export function provideI18n(locale: string = "en") {
const state = {
...defaultI18nState,
Expand All @@ -45,16 +49,37 @@ export function useI18n({ messages }: Options) {
const i18n = inject(i18nInjectionKey, defaultI18nState);

function translate(path: string, customValues: Record<string, string | number> = {}): string {
function resolveCustomKeys(translation: string) {
return translation.replace(CUSTOM_VALUE_REGEX, (match: string, key: string) => {
return Object.prototype.hasOwnProperty.call(customValues, key)
? customValues[key].toString()
: match;
});
}

const translation =
get(messages, `${i18n.locale}.${path}`) || get(messages, `${i18n.defaultLocale}.${path}`);

if (!translation) return path;

return translation.replace(CUSTOM_VALUE_REGEX, (match: string, key: string) => {
return Object.prototype.hasOwnProperty.call(customValues, key)
? customValues[key].toString()
: match;
});
const canBePluralized = /\|/.test(translation);
if (canBePluralized) {
if (typeof customValues.n !== "number")
throw new Error('The "n" key is required for pluralization');

const versions = translation.split("|");

// "no apple | apple | apples"; The first version is the zero form
const includesZeroForm = versions.length === 3;

const index = limit(includesZeroForm ? customValues.n : customValues.n - 1, 2);
const resolvedTranslation = versions.at(index);
if (!resolvedTranslation) return path;

return resolveCustomKeys(resolvedTranslation);
}

return resolveCustomKeys(translation);
}

return { t: translate };
Expand Down

0 comments on commit 0efa307

Please sign in to comment.