Skip to content

Commit

Permalink
allow custom value inside translations
Browse files Browse the repository at this point in the history
  • Loading branch information
Haberkamp committed Oct 9, 2024
1 parent 344fb72 commit cd4ebd8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 6 deletions.
30 changes: 30 additions & 0 deletions packages/component-library/src/composables/useI18n.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,34 @@ describe("useI18n", () => {

expect(screen.getByText("path.to.translation")).toBeInTheDocument();
});

it("translates the snippet with custom values", () => {
render({
setup() {
const { t } = useI18n({
messages: { en: { greeting: "Hello, {name}!" } },
});

return { t };
},
template: "{{ t('greeting', { name: 'World' }) }}",
});

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

it("keeps the custom value syntax when no custom value is provided", () => {
render({
setup() {
const { t } = useI18n({
messages: { en: { greeting: "Hello, {name}!" } },
});

return { t };
},
template: "{{ t('greeting') }}",
});

expect(screen.getByText("Hello, {name}!")).toBeInTheDocument();
});
});
20 changes: 14 additions & 6 deletions packages/component-library/src/composables/useI18n.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { provide, inject } from "vue";

function get(obj: Record<string, unknown>, path: string) {
function get(obj: Record<string, unknown>, path: string): string | undefined {
if (typeof obj !== "object" || obj === null) return undefined;

const keys = path.split(".");
Expand All @@ -13,6 +13,7 @@ function get(obj: Record<string, unknown>, path: string) {
result = result[key];
}

// @ts-ignore
return result;
}

Expand All @@ -38,15 +39,22 @@ export function provideI18n(locale: string = "en") {
provide(i18nInjectionKey, state);
}

const CUSTOM_VALUE_REGEX = /{([^}]*)}/g;

export function useI18n({ messages }: Options) {
const i18n = inject(i18nInjectionKey, defaultI18nState);

function translate(path: string): string {
const translation = get(messages, `${i18n.locale}.${path}`);
if (translation) return translation.toString();
function translate(path: string, customValues: Record<string, string | number> = {}): string {
const translation =
get(messages, `${i18n.locale}.${path}`) || get(messages, `${i18n.defaultLocale}.${path}`);

if (!translation) return path;

const fallback = get(messages, `${i18n.defaultLocale}.${path}`);
return fallback ? fallback.toString() : path;
return translation.replace(CUSTOM_VALUE_REGEX, (match: string, key: string) => {
return Object.prototype.hasOwnProperty.call(customValues, key)
? customValues[key].toString()
: match;
});
}

return { t: translate };
Expand Down

0 comments on commit cd4ebd8

Please sign in to comment.