🌓 feat(ui): add auto theme mode, refactor ThemeToggle, optimize header theme handling

- Feature: Introduce 'auto' theme mode
  - Detect system preference via matchMedia('(prefers-color-scheme: dark)')
  - Add useActualTheme context to expose the effective theme ('light'|'dark')
  - Persist selected mode in localStorage ('theme-mode') with 'auto' as default
  - Apply/remove `dark` class on <html> and sync `theme-mode` on <body>
  - Broadcast effective theme to iframes

- UI: Redesign ThemeToggle with Dropdown items and custom highlight
  - Replace non-existent IconMonitor with IconRefresh
  - Use Dropdown.Menu + Dropdown.Item with built-in icon prop
  - Selected state uses custom background highlight; hover state preserved
  - Remove checkmark; selection relies on background styling
  - Current button icon reflects selected mode

- Performance: reduce re-renders and unnecessary effects
  - Memoize theme options and current button icon (useMemo)
  - Simplify handleThemeToggle to accept only explicit modes ('light'|'dark'|'auto')
  - Minimize useEffect dependencies; remove unrelated deps

- Header: streamline useHeaderBar
  - Use useActualTheme for iframe theme messaging
  - Remove unused statusDispatch
  - Remove isNewYear from theme effect dependencies

- Home: send effective theme (useActualTheme) to external content iframes

- i18n: add/enhance theme-related copy in locales (en/zh)

- Chore: minor code cleanup and consistency
  - Improve readability and maintainability
  - Lint clean; no functional regressions
This commit is contained in:
t0ng7u
2025-08-23 03:02:35 +08:00
parent 9674065465
commit 30fc4d3082
7 changed files with 173 additions and 47 deletions

View File

@@ -19,7 +19,7 @@ For commercial licensing, please contact support@quantumnous.com
import React from 'react';
import { Button, Dropdown } from '@douyinfe/semi-ui';
import { IconLanguage } from '@douyinfe/semi-icons';
import { Languages } from 'lucide-react';
import { CN, GB } from 'country-flag-icons/react/3x2';
const LanguageSelector = ({ currentLang, onLanguageChange, t }) => {
@@ -46,7 +46,7 @@ const LanguageSelector = ({ currentLang, onLanguageChange, t }) => {
}
>
<Button
icon={<IconLanguage className="text-lg" />}
icon={<Languages size={18} />}
aria-label={t('切换语言')}
theme="borderless"
type="tertiary"