import React from 'react'; import { translate, DEFAULT_LOCALE, type LocaleCode } from './messages'; import { useLocale } from './LocaleContext'; type ReplacementValues = Record; 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((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]); }