Files
fotospiel-app/resources/js/guest/i18n/useTranslation.ts

50 lines
1.5 KiB
TypeScript

import React from 'react';
import { translate, DEFAULT_LOCALE, type LocaleCode } from './messages';
import { useLocale } from './LocaleContext';
type ReplacementValues = Record<string, string | number>;
export type TranslateFn = {
(key: string): string;
(key: string, fallback: string): string;
(key: string, replacements: ReplacementValues): string;
(key: string, replacements: ReplacementValues, fallback: string): string;
};
function resolveTranslation(locale: LocaleCode, key: string, fallback?: string): string {
return translate(locale, key) ?? translate(DEFAULT_LOCALE, key) ?? fallback ?? key;
}
function applyReplacements(value: string, replacements?: ReplacementValues): string {
if (!replacements) {
return value;
}
return Object.entries(replacements).reduce((acc, [token, replacement]) => {
const pattern = new RegExp(`\\{${token}\\}`, 'g');
return acc.replace(pattern, String(replacement));
}, value);
}
export function useTranslation() {
const { locale } = useLocale();
const t = React.useCallback<TranslateFn>((key: string, arg2?: ReplacementValues | string, arg3?: string) => {
let replacements: ReplacementValues | undefined;
let fallback: string | undefined;
if (typeof arg2 === 'string' || arg2 === undefined) {
fallback = arg2 ?? arg3;
} else {
replacements = arg2;
fallback = arg3;
}
const raw = resolveTranslation(locale, key, fallback);
return applyReplacements(raw, replacements);
}, [locale]);
return React.useMemo(() => ({ t, locale }), [t, locale]);
}