From 49818ed4d86e77806440bd7938b703cc38ed2ef5 Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Fri, 17 Apr 2026 00:30:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BE=A7=E8=BE=B9=E6=A0=8F=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E4=BA=AE=E8=89=B2=E4=B8=BB=E9=A2=98=EF=BC=8C=E6=9A=97?= =?UTF-8?q?=E9=BB=91=E4=B8=BB=E9=A2=98=E4=B8=8B=E8=B7=9F=E9=9A=8F=E5=88=87?= =?UTF-8?q?=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/e2e/sidebar.spec.ts | 17 +++------- .../__tests__/components/AppLayout.test.tsx | 32 +++++++++++++++++++ frontend/src/components/AppLayout/index.tsx | 6 ++-- openspec/specs/theme-system/spec.md | 24 ++++++++++++++ openspec/specs/theme-toggle/spec.md | 9 +++++- 5 files changed, 72 insertions(+), 16 deletions(-) diff --git a/frontend/e2e/sidebar.spec.ts b/frontend/e2e/sidebar.spec.ts index b1bf52d..c335039 100644 --- a/frontend/e2e/sidebar.spec.ts +++ b/frontend/e2e/sidebar.spec.ts @@ -46,20 +46,11 @@ test.describe('侧边栏导航', () => { await expect(collapsedSider).toBeVisible(); }); - test('应显示主题切换按钮', async ({ page }) => { + test('默认应显示亮色侧边栏', async ({ page }) => { const sider = page.locator('.ant-layout-sider'); - const themeButton = sider.getByRole('button').filter({ has: page.getByRole('img', { name: 'moon' }) }); - await expect(themeButton).toBeVisible(); - }); + await expect(sider).toBeVisible(); - test('应能通过主题切换按钮切换主题', async ({ page }) => { - const sider = page.locator('.ant-layout-sider'); - const themeButton = sider.getByRole('button').filter({ has: page.getByRole('img', { name: 'moon' }) }); - - await themeButton.click(); - await page.waitForTimeout(300); - - const lightButton = sider.getByRole('button').filter({ has: page.getByRole('img', { name: 'sun' }) }); - await expect(lightButton).toBeVisible(); + const menu = page.locator('.ant-menu-light'); + await expect(menu).toBeVisible(); }); }); diff --git a/frontend/src/__tests__/components/AppLayout.test.tsx b/frontend/src/__tests__/components/AppLayout.test.tsx index a0501a0..566f084 100644 --- a/frontend/src/__tests__/components/AppLayout.test.tsx +++ b/frontend/src/__tests__/components/AppLayout.test.tsx @@ -72,4 +72,36 @@ describe('AppLayout', () => { const header = container.querySelector('.ant-layout-header') as HTMLElement; expect(header.style.background).toBe('#141414'); }); + + it('uses light menu theme in default mode', async () => { + const { useTheme } = await import('@/contexts/ThemeContext'); + vi.mocked(useTheme).mockReturnValue({ + effectiveThemeId: 'default', + themeId: 'default', + followSystem: false, + systemIsDark: false, + setThemeId: vi.fn(), + setFollowSystem: vi.fn(), + }); + + const { container } = renderWithRouter(); + expect(container.querySelector('.ant-menu-light')).toBeInTheDocument(); + expect(container.querySelector('.ant-menu-dark')).not.toBeInTheDocument(); + }); + + it('uses dark menu theme in dark mode', async () => { + const { useTheme } = await import('@/contexts/ThemeContext'); + vi.mocked(useTheme).mockReturnValue({ + effectiveThemeId: 'dark', + themeId: 'dark', + followSystem: false, + systemIsDark: false, + setThemeId: vi.fn(), + setFollowSystem: vi.fn(), + }); + + const { container } = renderWithRouter(); + expect(container.querySelector('.ant-menu-dark')).toBeInTheDocument(); + expect(container.querySelector('.ant-menu-light')).not.toBeInTheDocument(); + }); }); diff --git a/frontend/src/components/AppLayout/index.tsx b/frontend/src/components/AppLayout/index.tsx index e867cb1..0222f6b 100644 --- a/frontend/src/components/AppLayout/index.tsx +++ b/frontend/src/components/AppLayout/index.tsx @@ -15,6 +15,7 @@ export function AppLayout() { const location = useLocation(); const navigate = useNavigate(); const { effectiveThemeId } = useTheme(); + const isDark = effectiveThemeId === 'dark'; const [collapsed, setCollapsed] = useState(false); const getPageTitle = () => { @@ -31,6 +32,7 @@ export function AppLayout() { collapsed={collapsed} onCollapse={setCollapsed} breakpoint="lg" + theme={isDark ? 'dark' : 'light'} style={{ overflow: 'hidden', height: '100vh', @@ -47,7 +49,7 @@ export function AppLayout() { display: 'flex', alignItems: 'center', justifyContent: 'center', - color: '#fff', + color: isDark ? '#fff' : 'rgba(0, 0, 0, 0.88)', fontSize: collapsed ? '1rem' : '1.25rem', fontWeight: 600, transition: 'all 0.2s', @@ -57,7 +59,7 @@ export function AppLayout() { {collapsed ? 'AI' : 'AI Gateway'}