Internacionalización (i18n)
PreffX utiliza una única señal de idioma de nivel raíz que impulsa todas las traducciones. El idioma se almacena en el atributo <html lang="..."> y se sincroniza con la señal lang, por lo que cambiarlo actualiza automáticamente todos los diccionarios.
Leer el idioma
La utilidad lang es una señal de solo lectura que contiene el código de idioma actual:
import type { PC } from 'preffx';
export const CurrentLang: PC = (_props, { lang }) => {
return <span>Current language: {lang}</span>;
};Dentro de los bloques computed el valor se rastrea de forma reactiva:
import type { PC } from 'preffx';
export const Caption: PC = (_props, { computed, lang }) => {
const greeting = computed(() =>
lang.value === 'ru' ? 'Привет' : 'Hello'
);
return <p>{greeting}</p>;
};Cambiar el idioma
Llame a setLang para cambiar el idioma. Esta función escribe en el atributo <html lang> y, a su vez, actualiza la señal lang que utilizan todos los diccionarios.
import type { PC } from 'preffx';
export const LangSwitch: PC = (_props, { setLang }) => {
return (
<div>
<button onClick={() => setLang('en')}>EN</button>
<button onClick={() => setLang('ru')}>RU</button>
</div>
);
};Diccionarios simples
Pase un objeto plano indexado por idioma y luego seleccione el activo mediante computed:
import type { PC } from 'preffx';
const dictionary = {
en: { openProfile: 'Open profile', showStats: 'Show statistics' },
ru: { openProfile: 'Открыть профиль', showStats: 'Показать статистику' }
};
export const App: PC = (_props, { computed, lang }) => {
const captions = computed(() => dictionary[lang.value] || dictionary.en);
return (
<div>
<button>{captions.openProfile}</button>
<button>{captions.showStats}</button>
</div>
);
};Diccionarios perezosos con dict
Cuando una configuración regional es grande o se carga de forma asíncrona, utilice la utilidad dict. Esta toma un mapa de código de idioma → resolutor (síncrono o asíncrono) y devuelve un proxy cuyos campos son señales reactivas. Acceda a un campo como valor o llámelo como función.
import type { APC } from 'preffx';
const getRuDictionary = async () => {
return {
openProfile(name: string) {
return 'Открыть профиль № ' + name;
},
showStats: 'Показать статистику'
};
};
const getEnDictionary = async () => {
return {
openProfile(name: string) {
return 'Open profile № ' + name;
},
showStats: 'Show stats'
};
};
export const App: APC = async (_props, { dict, setLang }) => {
const initialDict = await getEnDictionary();
const captions = dict({ ru: getRuDictionary, en: getEnDictionary }, initialDict);
return (
<div>
<button onClick={() => setLang('en')}>EN</button>
<button onClick={() => setLang('ru')}>RU</button>
<span>
<button>{captions.openProfile('42')}</button>
<button>{captions.showStats}</button>
</span>
</div>
);
};dict(resolvers)— primer argumento:Record<lang, () => Dict | Promise<Dict>>.dict(resolvers, initial)— el segundo argumento opcional proporciona el objeto inicial que se usa antes de que se resuelva un resolutor.- El resolutor para el
langactual se vuelve a ejecutar automáticamente cuando cambia el idioma. - Los campos de función se convierten en callables que devuelven señales computadas:
captions.openProfile('42')es reactivo. - Utilice
.peek()en un campo para leerlo sin seguimiento reactivo.
Configurar el idioma inicial
El lang inicial se lee del atributo <html lang> en el momento de createRoot, o se puede configurar explícitamente:
import { createRoot } from 'preffx';
createRoot({ defaultLang: 'en' }).mount(App);Resumen de utilidades
| Opción | Tipo | Descripción |
|---|---|---|
defaultLang | string | Idioma de respaldo cuando no se define/declara |
setLang | (value) => void | Cambiar el idioma actual |
lang | ReadonlySignal | Idioma actual (reactivo) |
dict | (...) => DictProxy | Diccionarios reactivos por idioma |