import { ReactNode } from 'react';
import { LanguageCode } from '../../../data/languages';
export type TranslationText = {
[key in LanguageCode | string]?: string;
};
export interface UseTranslationOptions {
defaultLanguage?: string;
currentLanguage?: string;
}
export type TranslationParams = {
[key: string]: string | number | ((children: ReactNode) => ReactNode);
};
export interface TranslateFunction {
(text: TranslationText | string | undefined, fallback?: string): string;
(text: TranslationText | string | undefined, fallback: string | undefined, params: undefined, languageCode: string): string;
(text: TranslationText | string | undefined, fallback?: string, params?: TranslationParams, languageCode?: string): string | ReactNode;
}
export interface UseTranslationResult {
/**
* Translate function that handles multi-language text objects
* @param text - The text to translate (can be a string or MultiLangText object)
* @param fallback - Optional fallback text if translation is not found
* @param params - Optional parameters for string interpolation (e.g., {count: 10} for 'User has {count} points') or tag wrapping with functions (e.g., {i: (val) => {val}} for 'text')
* @param languageCode - Optional language code to override the current locale
* @returns The translated string or ReactNode (when using function params for tag wrapping)
*/
t: TranslateFunction;
/**
* Current locale code (e.g., 'en', 'fr', 'es')
*/
locale: string;
}
/**
* Hook for translating multi-language text objects
*
* @example
* ```tsx
* const { t, locale } = useTranslation({ defaultLanguage: 'en' });
*
* const multiLangText = {
* en: 'Hello',
* fr: 'Bonjour',
* es: 'Hola'
* };
*
* // Translates to current locale
* const translated = t(multiLangText);
*
* // With fallback
* const withFallback = t(multiLangText, 'Default text');
*
* // With params interpolation
* const withParams = t('User has {count} points', '', { count: 10 });
* // Result: 'User has 10 points'
*
* // Escaped brackets are treated as literal text
* const escaped = t('Use \\{count\\} as placeholder', '', { count: 10 });
* // Result: 'Use {count} as placeholder'
*
* // With function params for tag wrapping
* const withTags = t('This is formatted', '', {
* i: (value) => {value}
* });
* // Result: ReactNode with formatted
*
* // Escaped tags are treated as literal text
* const escapedTags = t('This is \\not formatted\\', '', {
* i: (value) => {value}
* });
* // Result: 'This is not formatted'
*
* // Mix of placeholders and tags
* const mixed = t('User {name} has {count} points', '', {
* name: 'John',
* count: 10,
* b: (value) => {value}
* });
* // Result: ReactNode with 'User John has 10 points'
*
* // Override locale
* const inFrench = t(multiLangText, '', undefined, 'fr');
* ```
*/
export declare const useTranslation: (options?: UseTranslationOptions) => UseTranslationResult;