Tema e i18n
Las dos convenciones más fáciles de romper sin darse cuenta, porque nada falla al romperlas: un color a pelo funciona, y un texto en castellano dentro de un componente también.
Tema: nada de valores literales
Todo vive en constants/theme.ts y se importa:
import { Fonts, KawaiiPalette, Radius, Spacing } from '@/constants/theme';
| Export | Qué es |
|---|---|
KawaiiPalette |
La paleta de marca — sakura, matcha, sumi, paper… |
Colors |
Neutros claro/oscuro, reservados para cromo del sistema |
Spacing |
Escala de espaciado: half, one … six |
Radius |
sm, md, lg, pill |
Fonts |
Familias por plataforma, con display para la tipografía propia |
Hay dos paletas y no se mezclan, como dice el comentario del fichero: KawaiiPalette es la
identidad visual de las pantallas; Colors son los neutros claro/oscuro para cromo del sistema.
No escribas un
#hexni un número de espaciado en unStyleSheet. Si el valor que necesitas no está en la escala, añádelo a la escala.
La escala es deliberadamente corta —siete pasos de espaciado, cuatro radios— y eso es lo que hace
que la app se vea consistente sin que nadie lo vigile. Un padding: 13 no está mal por feo: está
mal porque el siguiente pondrá 14.
También hay dos valores de plataforma que conviene usar en vez de recalcularlos: BottomTabInset y
MaxContentWidth.
i18n: ningún texto en el componente
Tres idiomas —es, en, ca— con un JSON por idioma en i18n/locales/, y en el componente:
const { t } = useTranslation();
// ...
<Text>{t('settings.language')}</Text>
Una clave nueva se añade a los tres ficheros a la vez. Si falta en uno, cae al castellano por el
fallbackLngy nadie lo nota hasta que alguien usa la app en inglés.
Las claves se agrupan por pantalla o área (settings.*, pets.*), que es lo que permite encontrar
lo que hay que cambiar sin buscar el texto.
El idioma se resuelve antes del primer render
initI18n() lo decide en este orden: elección guardada del usuario → idioma del dispositivo →
castellano. Y se guarda en SecureStore a propósito, para que el siguiente arranque sea instantáneo
sin esperar a que /settings responda por red.
Dos cosas que se siguen de ahí:
- La función es idempotente: guarda su propia promesa, así que llamarla dos veces no reinicializa nada.
- El layout raíz no pinta hasta que resuelve, junto con las fuentes y la sesión. Así no se ve un texto cambiar de idioma a mitad del arranque.
Al cambiar el idioma
Hay que hacer las dos cosas: decírselo a i18next y persistirlo. Si solo cambias lo primero, la elección se pierde al cerrar la app; si solo lo segundo, la pantalla no se traduce hasta reiniciar.