feat(electrobun): i18n system — @formatjs/intl + Svelte 5 runes + 3 locales
- i18n.svelte.ts: store with $state locale + createIntl(), t() function, formatDate/Number/RelativeTime, getDir() for RTL, async setLocale() - i18n.types.ts: TranslationKey union (codegen from en.json) - locales/en.json: 200+ strings in ICU MessageFormat - locales/pl.json: full Polish translation - locales/ar.json: partial Arabic (validates 6-form plural + RTL) - scripts/i18n-types.ts: codegen script for type-safe keys - 6 components wired: StatusBar, AgentPane, CommandPalette, SettingsDrawer, SplashScreen, ChatInput - Language selector in AppearanceSettings - App.svelte: document.dir reactive for RTL - CONTRIBUTING_I18N.md: guide for adding languages Note: currently Electrobun-only. Will extract to @agor/i18n shared package for both Tauri and Electrobun.
This commit is contained in:
parent
eee65070a8
commit
aae86a4001
16 changed files with 947 additions and 64 deletions
37
ui-electrobun/scripts/i18n-types.ts
Normal file
37
ui-electrobun/scripts/i18n-types.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env bun
|
||||
/**
|
||||
* Reads locales/en.json and generates src/mainview/i18n.types.ts
|
||||
* with a TranslationKey union type covering all keys.
|
||||
*
|
||||
* Usage: bun scripts/i18n-types.ts
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
|
||||
const ROOT = resolve(import.meta.dir, '..');
|
||||
const EN_PATH = resolve(ROOT, 'locales/en.json');
|
||||
const OUT_PATH = resolve(ROOT, 'src/mainview/i18n.types.ts');
|
||||
|
||||
const en: Record<string, string> = JSON.parse(readFileSync(EN_PATH, 'utf-8'));
|
||||
const keys = Object.keys(en).sort();
|
||||
|
||||
const lines: string[] = [
|
||||
'/**',
|
||||
' * Auto-generated by scripts/i18n-types.ts — do not edit manually.',
|
||||
' * Run: bun scripts/i18n-types.ts',
|
||||
' */',
|
||||
'',
|
||||
'export type TranslationKey =',
|
||||
];
|
||||
|
||||
keys.forEach((key, i) => {
|
||||
const prefix = i === 0 ? ' | ' : ' | ';
|
||||
const suffix = i === keys.length - 1 ? ';' : '';
|
||||
lines.push(`${prefix}'${key}'${suffix}`);
|
||||
});
|
||||
|
||||
lines.push('');
|
||||
|
||||
writeFileSync(OUT_PATH, lines.join('\n'), 'utf-8');
|
||||
console.log(`[i18n-types] Generated ${keys.length} keys -> ${OUT_PATH}`);
|
||||
Loading…
Add table
Add a link
Reference in a new issue