Files
houseplan-card/src/i18n.ts
T
Matysh 12cd8a1af3 feat: add complete German localization
Add Deutsch across all card surfaces and backend flows, backed by the language registry introduced in #62. German loads as a fingerprint-checked page-shared locale chunk so EN/RU remain synchronous and the initial View budget stays intact. Root render gates prevent mixed-language flashes, retry once, and fail open to English. Extend parity, runtime, bundle, browser and visual coverage, plus contributor and user documentation.

Issue: #348
User-Visible: yes
2026-08-28 11:58:46 +03:00

44 lines
1.5 KiB
TypeScript

/**
* Card UI localization. Shipped languages live in the typed registry; see the
* translation contribution flow in CONTRIBUTING.md. The language is resolved
* from the card config or, by default, from the HA user profile. Unknown
* languages fall back to English synchronously.
*/
import { subst } from './logic';
import {
FALLBACK_DICTIONARY,
FALLBACK_LANGUAGE_CODE,
LANGUAGE_REGISTRY,
dictionaryFor,
resolveLanguageCode,
type Lang,
} from './i18n/registry';
type Key = keyof typeof FALLBACK_DICTIONARY;
export type { Lang } from './i18n/registry';
/** Resolve the UI language: explicit config option wins, then the HA profile. */
export function langOf(hass: any, configLang?: string | null): Lang {
return resolveLanguageCode(
configLang,
hass?.locale?.language || hass?.language,
LANGUAGE_REGISTRY.map(({ code }) => code),
FALLBACK_LANGUAGE_CODE,
);
}
/** Translate a key with optional {placeholder} substitution. */
export function t(lang: Lang, key: Key, vars?: Record<string, string | number>): string {
const dictionary = dictionaryFor(lang);
return subst(dictionary[key] ?? FALLBACK_DICTIONARY[key] ?? key, vars);
}
/** Whether a localized value exists and contains useful text after fallback. */
export function hasTranslation(lang: Lang, key: string): boolean {
const value = dictionaryFor(lang)[key] ?? FALLBACK_DICTIONARY[key];
return typeof value === 'string' && value.trim().length > 0;
}
export type { Key as I18nKey };