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
|
|
@ -9,6 +9,7 @@
|
|||
import KeyboardSettings from './settings/KeyboardSettings.svelte';
|
||||
import RemoteMachinesSettings from './settings/RemoteMachinesSettings.svelte';
|
||||
import DiagnosticsTab from './settings/DiagnosticsTab.svelte';
|
||||
import { t } from './i18n.svelte.ts';
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
|
|
@ -25,19 +26,23 @@
|
|||
icon: string;
|
||||
}
|
||||
|
||||
const CATEGORIES: Category[] = [
|
||||
{ id: 'appearance', label: 'Appearance', icon: '🎨' },
|
||||
{ id: 'agents', label: 'Agents', icon: '🤖' },
|
||||
{ id: 'security', label: 'Security', icon: '🔒' },
|
||||
{ id: 'projects', label: 'Projects', icon: '📁' },
|
||||
{ id: 'orchestration', label: 'Orchestration', icon: '⚙' },
|
||||
{ id: 'machines', label: 'Machines', icon: '🖥' },
|
||||
{ id: 'keyboard', label: 'Keyboard', icon: '⌨' },
|
||||
{ id: 'advanced', label: 'Advanced', icon: '🔧' },
|
||||
{ id: 'marketplace', label: 'Marketplace', icon: '🛒' },
|
||||
{ id: 'diagnostics', label: 'Diagnostics', icon: '📊' },
|
||||
const CATEGORY_DEFS: Array<{ id: CategoryId; icon: string; key: string }> = [
|
||||
{ id: 'appearance', icon: '🎨', key: 'settings.appearance' },
|
||||
{ id: 'agents', icon: '🤖', key: 'settings.agents' },
|
||||
{ id: 'security', icon: '🔒', key: 'settings.security' },
|
||||
{ id: 'projects', icon: '📁', key: 'settings.projects' },
|
||||
{ id: 'orchestration', icon: '⚙', key: 'settings.orchestration' },
|
||||
{ id: 'machines', icon: '🖥', key: 'settings.machines' },
|
||||
{ id: 'keyboard', icon: '⌨', key: 'settings.keyboard' },
|
||||
{ id: 'advanced', icon: '🔧', key: 'settings.advanced' },
|
||||
{ id: 'marketplace', icon: '🛒', key: 'settings.marketplace' },
|
||||
{ id: 'diagnostics', icon: '📊', key: 'settings.diagnostics' },
|
||||
];
|
||||
|
||||
let CATEGORIES = $derived<Category[]>(
|
||||
CATEGORY_DEFS.map(d => ({ id: d.id, label: t(d.key as any), icon: d.icon }))
|
||||
);
|
||||
|
||||
let activeCategory = $state<CategoryId>('appearance');
|
||||
|
||||
function handleBackdropClick(e: MouseEvent) {
|
||||
|
|
@ -66,8 +71,8 @@
|
|||
|
||||
<!-- Header -->
|
||||
<header class="drawer-header">
|
||||
<h2 class="drawer-title">Settings</h2>
|
||||
<button class="drawer-close" onclick={onClose} aria-label="Close settings">×</button>
|
||||
<h2 class="drawer-title">{t('settings.title')}</h2>
|
||||
<button class="drawer-close" onclick={onClose} aria-label={t('settings.close')}>×</button>
|
||||
</header>
|
||||
|
||||
<!-- Body: sidebar + content -->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue