ac1ca8d035
Per /Users/zimin/Downloads/Ordinis (4)/redesign/compact.html. TopBar breadcrumb: - Detail routes теперь показывают `← Справочники / Космические аппараты` с back-arrow prefix на parent crumb (caption text, mute). Bold title + inline mono subtitle "satellites · v1.0.0". - Catalog route: simple "Dictionaries" title. TopBar right cluster cleanup: - Removed `Docs` link — diagnostic, не critical UX, моя кноп не нужна для UI flow. - Removed `VersionBadge` (commit + tag) — был noise рядом с продакшн features. Build info всё ещё доступна в browser console / Docs. - ThemeSwitch: tri-state (Light/Dark/System icons 3×24px) заменён на 2-button `Earth | Dark` с text labels (per prototype). `system` preference остаётся в localStorage для existing users, но новый UI не выставляет. - LanguageSwitch: dual radio `RU | EN` заменён на single toggle button — показывает текущий язык как label, click переключает на следующий. Saves ~60px горизонтально, matches prototype. EditorInfoPanel order: - Action buttons (Экспорт / Time-travel / AOI) переехали из середины panel (между metadata и Relations) в bottom (после Relations) — per prototype. Info → meta → relations → actions flow. - Action order: Экспорт первым (frequent), затем Time-travel, AOI последним (rare для most dicts).
62 lines
2.3 KiB
TypeScript
62 lines
2.3 KiB
TypeScript
import { useTranslation } from 'react-i18next'
|
||
import { useTheme, type ThemePreference } from '@/stores/ThemeProvider'
|
||
import { cn } from '@/lib/utils'
|
||
|
||
/**
|
||
* Theme switch per redesign prototype — 2-button segmented control с text
|
||
* labels "Earth | Dark". Filled accent-bg на active.
|
||
*
|
||
* <p>Прошлый tri-state (Light/Dark/System icons) был noise — "system" preference
|
||
* редко используется явно, мало кто понимает Monitor icon. Простой 2-button
|
||
* `Earth / Dark` toggle — точно повторяет prototype и улучшает discoverability.
|
||
*
|
||
* <p>Internally "Earth" maps на `light` preference (Earthy palette default).
|
||
* "System" preference больше не выставляется через UI; localStorage value
|
||
* остаётся валидным (ThemeProvider может read), но новые users получают
|
||
* explicit light/dark choice.
|
||
*/
|
||
export function ThemeSwitch() {
|
||
const { t } = useTranslation()
|
||
const { preference, setPreference } = useTheme()
|
||
|
||
// Treat 'system' как 'light' для UI — переключение всё равно flatten'ит
|
||
// preference на explicit choice.
|
||
const activeId: Exclude<ThemePreference, 'system'> =
|
||
preference === 'dark' ? 'dark' : 'light'
|
||
|
||
const items: { id: Exclude<ThemePreference, 'system'>; label: string }[] = [
|
||
{ id: 'light', label: t('theme.earth', { defaultValue: 'Earth' }) },
|
||
{ id: 'dark', label: t('theme.dark', { defaultValue: 'Dark' }) },
|
||
]
|
||
|
||
return (
|
||
<div
|
||
role="radiogroup"
|
||
aria-label={t('theme.label')}
|
||
className="inline-flex items-center rounded-md border border-line bg-surface overflow-hidden"
|
||
>
|
||
{items.map((item) => {
|
||
const active = activeId === item.id
|
||
return (
|
||
<button
|
||
key={item.id}
|
||
type="button"
|
||
role="radio"
|
||
aria-checked={active}
|
||
aria-label={item.label}
|
||
onClick={() => setPreference(item.id)}
|
||
className={cn(
|
||
'h-8 px-3 text-cap font-semibold tracking-[0.14em] transition-colors',
|
||
active
|
||
? 'bg-accent text-on-accent'
|
||
: 'text-ink-2 hover:text-ink hover:bg-surface-2',
|
||
)}
|
||
>
|
||
{item.label}
|
||
</button>
|
||
)
|
||
})}
|
||
</div>
|
||
)
|
||
}
|