feat(client): adopt the locale seat in theme, sidebar, question, and model

Each package ships its zh/en dictionaries as satisfies-typed pairs (zh is
the key-set source of truth; en is checked complete against it), merges its
namespace into LocaleNamespaceMap, and declares locale: NS at register —
components read the framework-injected typed t seat instead of a
hand-carried inject member. Overlapping verbatim words (retry, submit,
submitting) drop out of package dictionaries in favor of the shared common
vocabulary; the question composer stores validation feedback as dictionary
keys so shown feedback follows a locale switch.
This commit is contained in:
imccyu
2026-07-30 01:04:58 +08:00
parent c317fbc489
commit 2c5114c060
11 changed files with 58 additions and 44 deletions
@@ -11,6 +11,7 @@ import {
} from '@deepseek-ai/dsh-client-ui-primitives'
import type { PropsLocale, PropsRuntime, PropsStore } from '@deepseek-ai/dsh-client-ui-slots'
import type { ThemePreference } from './index.ts'
import type { ThemeKey } from './locales.ts'
import type {} from './settings-contract.ts'
import type { createAppearanceRowStore } from './settings-store.ts'
import css from './AppearanceRow.module.css'
@@ -27,7 +28,7 @@ export type AppearanceRowComponentProps =
& PropsLocale<'settings.theme'> & AppearanceRowInjected
/** Cube order and icons (figma 501:30015-30017: Light, Dark, System). */
const CUBES: readonly { id: ThemePreference; labelKey: 'appearance.light' | 'appearance.dark' | 'appearance.system'; Icon: typeof IconLightOutline16 }[] = [
const CUBES: readonly { id: ThemePreference; labelKey: ThemeKey; Icon: typeof IconLightOutline16 }[] = [
{ id: 'light', labelKey: 'appearance.light', Icon: IconLightOutline16 },
{ id: 'dark', labelKey: 'appearance.dark', Icon: IconDarkOutline16 },
{ id: 'system', labelKey: 'appearance.system', Icon: IconFollowsystemOutline16 },
+4 -15
View File
@@ -14,9 +14,11 @@ import type {} from '@deepseek-ai/dsh-client-locale/client'
import type { AppearanceRowInjected } from './AppearanceRow.tsx'
import { AppearanceRow } from './AppearanceRow.tsx'
import { createAppearanceRowStore } from './settings-store.ts'
import { en, zh, type ThemeKey } from './locales.ts'
export type { AppearanceRowComponentProps, AppearanceRowInjected } from './AppearanceRow.tsx'
export type { AppearanceRowState } from './settings-store.ts'
export type { ThemeKey } from './locales.ts'
/** Namespace owning this feature's settings-row copy. */
export const SETTINGS_NS = 'settings.theme'
@@ -24,7 +26,7 @@ export const SETTINGS_NS = 'settings.theme'
declare module '@deepseek-ai/dsh-client-ui-slots' {
interface LocaleNamespaceMap {
/** The Appearance settings row's copy. */
'settings.theme': 'appearance.title' | 'appearance.light' | 'appearance.dark' | 'appearance.system'
'settings.theme': ThemeKey
}
}
@@ -235,20 +237,7 @@ export function apply(ctx: ClientContext): void {
const theme = new ThemeService(ctx)
ctx.provide('theme', theme)
ctx.effect(() => ctx.locale.register(SETTINGS_NS, {
zh: {
'appearance.title': '外观',
'appearance.light': '浅色',
'appearance.dark': '深色',
'appearance.system': '跟随系统',
},
en: {
'appearance.title': 'Appearance',
'appearance.light': 'Light',
'appearance.dark': 'Dark',
'appearance.system': 'System',
},
}), 'ui-theme: settings row dictionaries')
ctx.effect(() => ctx.locale.register(SETTINGS_NS, { zh, en }), 'ui-theme: settings row dictionaries')
const store = createAppearanceRowStore()
let bound: BoundActions<typeof store> | undefined
@@ -0,0 +1,20 @@
/** `settings.theme` namespace dictionaries (the Appearance row's copy). */
/** Simplified Chinese dictionary (the key-set source of truth). */
export const zh = {
'appearance.title': '外观',
'appearance.light': '浅色',
'appearance.dark': '深色',
'appearance.system': '跟随系统',
} satisfies Record<string, string>
/** The settings.theme namespace key union. */
export type ThemeKey = keyof typeof zh
/** English dictionary, checked complete against the zh key set. */
export const en = {
'appearance.title': 'Appearance',
'appearance.light': 'Light',
'appearance.dark': 'Dark',
'appearance.system': 'System',
} satisfies Record<ThemeKey, string>