tilfluktsrom/pwa/src/i18n/i18n.ts
Ole-Morten Duesund 6ba35add2f Legg til TalkBack-støtte og nordindikator på kompasset
Tilgjengelegheit (Android + PWA):
- Semantiske landemerke (header, main, aside, role=dialog)
- aria-live-regionar for statusoppdateringar og lasteoverlegg
- Fokusindikatorar (:focus-visible) og prefers-reduced-motion
- Auka trykkmål til 48dp (infoknapp, oppdater, del, widget)
- contentDescription på kart, kompass og framdriftsindikator
- aria-current og role=listitem på tilfluktsromliste
- Fokusfangst og fokusgjenoppretting i lasteoverlegg
- Ikkje-farge-indikator (▶) for valt tilfluktsrom
- Dynamisk lang-attributt basert på oppdaga språk
- Lokaliserte aria-label (en/nb/nn)

Nordindikator:
- DirectionArrowView teiknar diskret «N»-markør på omkrinsen
- Roterer uavhengig av hovudpila for kompasskalibrering
- Berre på stor kompassvisning, ikkje minipila

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 14:02:32 +01:00

50 lines
1.3 KiB
TypeScript

/**
* Minimal i18n system: detects locale from navigator.languages,
* provides t(key, ...args) for string lookup with %d/%s substitution.
*/
import { en } from './en';
import { nb } from './nb';
import { nn } from './nn';
const locales: Record<string, Record<string, string>> = { en, nb, nn };
let currentLocale = 'en';
/** Detect and set locale from browser preferences, update document lang. */
export function initLocale(): void {
const langs = navigator.languages ?? [navigator.language];
for (const lang of langs) {
const code = lang.toLowerCase().split('-')[0];
if (code in locales) {
currentLocale = code;
break;
}
// nb and nn both start with "n" — also match "no" as Bokmål
if (code === 'no') {
currentLocale = 'nb';
break;
}
}
document.documentElement.lang = currentLocale;
}
/** Get current locale code. */
export function getLocale(): string {
return currentLocale;
}
/**
* Translate a string key, substituting %d and %s with provided arguments.
* Falls back to English, then to the raw key.
*/
export function t(key: string, ...args: (string | number)[]): string {
let str = locales[currentLocale]?.[key] ?? locales.en[key] ?? key;
// Replace %d and %s placeholders sequentially
for (const arg of args) {
str = str.replace(/%[ds]/, String(arg));
}
return str;
}