mirror of
https://github.com/stablyai/orca.git
synced 2026-10-19 16:03:26 +00:00
Move language setting to primary interface section
Language is a first-class presentation preference alongside Theme and Zoom, so it shouldn't be buried in the Advanced disclosure. Advanced now contains only platform-chrome controls.
This commit is contained in:
@@ -66,13 +66,14 @@ export function AppearanceInterfaceSection({
|
||||
const titlebarEntry = getTitlebarEntries()[0]
|
||||
const typographyEntry = getTypographyEntries()[0]
|
||||
const zoomEntry = getZoomEntries()[0]
|
||||
// Language is primary (with Theme/Zoom/Font); Advanced is platform chrome only.
|
||||
const advancedEntries = [
|
||||
...(SHOW_UI_LANGUAGE_SETTING ? getLanguageEntries() : []),
|
||||
...getTitlebarEntries(),
|
||||
...getSystemTrayEntries({ showSystemTray: isDesktopWindows }),
|
||||
...getMenuBarIconEntries({ showMenuBarIcon: isDesktopMac })
|
||||
]
|
||||
const showAdvanced = !isSearching || matchesSettingsSearch(searchQuery, advancedEntries)
|
||||
const languageTitle = translate('settings.appearance.language.title', 'Language')
|
||||
|
||||
return (
|
||||
<div className="divide-y divide-border/40">
|
||||
@@ -111,6 +112,36 @@ export function AppearanceInterfaceSection({
|
||||
/>
|
||||
</SearchableSetting>
|
||||
|
||||
{SHOW_UI_LANGUAGE_SETTING ? (
|
||||
<SearchableSetting
|
||||
title={languageTitle}
|
||||
description={languageEntry?.description}
|
||||
keywords={languageEntry?.keywords ?? []}
|
||||
forceVisible={forceVisiblePrimary}
|
||||
>
|
||||
<SettingsRow
|
||||
label={languageTitle}
|
||||
control={
|
||||
<Select
|
||||
value={settings.uiLanguage}
|
||||
onValueChange={(value) => updateSettings({ uiLanguage: value as UiLanguage })}
|
||||
>
|
||||
<SelectTrigger size="sm" className="min-w-[220px]" aria-label={languageTitle}>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{UI_LANGUAGE_CHOICES.map((choice) => (
|
||||
<SelectItem key={choice.value} value={choice.value}>
|
||||
{getUiLanguageChoiceLabel(choice, translate)}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
}
|
||||
/>
|
||||
</SearchableSetting>
|
||||
) : null}
|
||||
|
||||
<SearchableSetting
|
||||
title={translate('auto.components.settings.AppearancePane.5e6d7aba8d', 'UI Zoom')}
|
||||
description={zoomEntry?.description}
|
||||
@@ -161,39 +192,6 @@ export function AppearanceInterfaceSection({
|
||||
{showAdvanced ? (
|
||||
<AppearanceAdvancedDisclosure showTopBorder={false}>
|
||||
<div className="divide-y divide-border/40">
|
||||
{SHOW_UI_LANGUAGE_SETTING ? (
|
||||
<SearchableSetting
|
||||
title={translate('settings.appearance.language.title', 'Language')}
|
||||
description={languageEntry?.description}
|
||||
keywords={languageEntry?.keywords ?? []}
|
||||
>
|
||||
<SettingsRow
|
||||
label={translate('settings.appearance.language.title', 'Language')}
|
||||
control={
|
||||
<Select
|
||||
value={settings.uiLanguage}
|
||||
onValueChange={(value) => updateSettings({ uiLanguage: value as UiLanguage })}
|
||||
>
|
||||
<SelectTrigger
|
||||
size="sm"
|
||||
className="min-w-[220px]"
|
||||
aria-label={translate('settings.appearance.language.title', 'Language')}
|
||||
>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{UI_LANGUAGE_CHOICES.map((choice) => (
|
||||
<SelectItem key={choice.value} value={choice.value}>
|
||||
{getUiLanguageChoiceLabel(choice, translate)}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
}
|
||||
/>
|
||||
</SearchableSetting>
|
||||
) : null}
|
||||
|
||||
<SearchableSetting
|
||||
title={translate(
|
||||
'auto.components.settings.AppearancePane.9868f39007',
|
||||
|
||||
@@ -202,6 +202,22 @@ describe('AppearancePane', () => {
|
||||
delete (window as unknown as { api?: unknown }).api
|
||||
})
|
||||
|
||||
it('shows language as a primary interface control without opening Advanced', async () => {
|
||||
// Language is a first-class presentation pref next to Theme — browsing
|
||||
// Appearance → Interface must surface it without expanding Advanced.
|
||||
mocks.state.settingsSearchQuery = ''
|
||||
const container = await renderAppearancePane(getDefaultSettings('/tmp'))
|
||||
const languageTrigger = container.querySelector<HTMLButtonElement>(
|
||||
'[data-slot="select-trigger"][aria-label="Language"]'
|
||||
)
|
||||
|
||||
expect(languageTrigger).not.toBeNull()
|
||||
// Advanced platform-chrome controls stay collapsed by default.
|
||||
expect(
|
||||
container.querySelector('button[role="switch"][aria-label="Titlebar App Name"]')
|
||||
).toBeNull()
|
||||
})
|
||||
|
||||
it('renders the language dropdown with system, english, chinese, korean, japanese, and spanish options', async () => {
|
||||
mocks.state.settingsSearchQuery = 'language'
|
||||
const updateSettings = vi.fn()
|
||||
|
||||
Reference in New Issue
Block a user