From b2fe23310862fe46479bb72511232bf21243cbdf Mon Sep 17 00:00:00 2001 From: PathGao Date: Thu, 30 Jul 2026 14:46:43 +0800 Subject: [PATCH] fix(ui): align sidebar pin controls Keep the pin with the expanded header actions and center the collapsed version link with the navigation rail. --- frontend/src/layouts/AppSidebar.css | 34 +++++++++++++------------- frontend/src/layouts/AppSidebar.tsx | 21 ++++++++-------- frontend/src/test/app-sidebar.test.tsx | 12 ++++++--- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/frontend/src/layouts/AppSidebar.css b/frontend/src/layouts/AppSidebar.css index 0376aec34..914c4afd0 100644 --- a/frontend/src/layouts/AppSidebar.css +++ b/frontend/src/layouts/AppSidebar.css @@ -34,9 +34,9 @@ display: flex; align-items: center; justify-content: space-between; - gap: 8px; + gap: 4px; height: 58px; - padding: 0 16px 0 24px; + padding: 0 12px 0 16px; border-bottom: 1px solid var(--ant-color-border-secondary); user-select: none; white-space: nowrap; @@ -53,7 +53,7 @@ .brand-actions { display: inline-flex; align-items: center; - gap: 2px; + gap: 0; flex-shrink: 0; } @@ -231,26 +231,26 @@ } .sidebar-pin { - display: flex; + display: inline-flex; align-items: center; - gap: 10px; - width: 100%; - height: 34px; - padding: 0 16px; + justify-content: center; + width: 30px; + height: 30px; + padding: 0; border: none; - border-radius: 6px; + border-radius: 50%; background: transparent; color: var(--ant-color-text-secondary); cursor: pointer; - font-size: 13px; - text-align: left; - transition: background-color 0.2s, color 0.2s; + flex-shrink: 0; + transition: background-color 0.2s, transform 0.15s, color 0.2s; } .sidebar-pin:hover, .sidebar-pin:focus-visible { background-color: color-mix(in srgb, var(--ant-color-primary) 10%, transparent); color: var(--ant-color-primary); + transform: scale(1.08); outline: none; } @@ -258,11 +258,6 @@ font-size: 16px; } -.ant-layout-sider-collapsed .sidebar-pin { - justify-content: center; - padding: 0; -} - .sider-version { display: flex; align-items: center; @@ -278,6 +273,11 @@ transition: color 0.2s; } +.ant-layout-sider-collapsed .sider-version { + justify-content: center; + padding: 8px 0; +} + .sider-version .anticon { font-size: 16px; } diff --git a/frontend/src/layouts/AppSidebar.tsx b/frontend/src/layouts/AppSidebar.tsx index b4af01295..9a2965c4f 100644 --- a/frontend/src/layouts/AppSidebar.tsx +++ b/frontend/src/layouts/AppSidebar.tsx @@ -304,6 +304,16 @@ export default function AppSidebar() { {!railCollapsed && (
+
-
diff --git a/frontend/src/test/app-sidebar.test.tsx b/frontend/src/test/app-sidebar.test.tsx index a50c66b6d..2bcd82cac 100644 --- a/frontend/src/test/app-sidebar.test.tsx +++ b/frontend/src/test/app-sidebar.test.tsx @@ -21,14 +21,20 @@ function renderSidebar() { ); } -test('keeps the sidebar expanded after pinning it and restores the choice', () => { +test('keeps the sidebar expanded after pinning it from the header and restores the choice', () => { const first = renderSidebar(); const sidebar = first.container.querySelector('.ant-layout-sider'); + const sidebarRoot = first.container.querySelector('.ant-sidebar'); expect(sidebar?.classList.contains('ant-layout-sider-collapsed')).toBe(true); - fireEvent.click(screen.getByRole('button', { name: 'Pin sidebar' })); - fireEvent.mouseLeave(first.container.querySelector('.ant-sidebar')!); + fireEvent.mouseEnter(sidebarRoot!); + + const pinButton = screen.getByRole('button', { name: 'Pin sidebar' }); + expect(pinButton.closest('.brand-actions')).not.toBeNull(); + + fireEvent.click(pinButton); + fireEvent.mouseLeave(sidebarRoot!); expect(sidebar?.classList.contains('ant-layout-sider-collapsed')).toBe(false); expect(localStorage.getItem('sidebar-pinned')).toBe('true');