feat(ui): let users pin the sidebar

Restore a persistent expanded-sidebar choice while preserving the compact hover rail as the default.
This commit is contained in:
PathGao
2026-07-30 14:39:55 +08:00
parent c377dca27c
commit 5373786faa
16 changed files with 153 additions and 14 deletions
+43
View File
@@ -0,0 +1,43 @@
import { fireEvent, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router';
import { afterEach, expect, test, vi } from 'vitest';
import AppSidebar from '@/layouts/AppSidebar';
import { renderWithProviders } from './test-utils';
vi.mock('@/api/queries/useAllSettings', () => ({
useAllSettings: () => ({ allSetting: {} }),
}));
afterEach(() => {
localStorage.clear();
});
function renderSidebar() {
return renderWithProviders(
<MemoryRouter>
<AppSidebar />
</MemoryRouter>,
);
}
test('keeps the sidebar expanded after pinning it and restores the choice', () => {
const first = renderSidebar();
const sidebar = first.container.querySelector('.ant-layout-sider');
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')!);
expect(sidebar?.classList.contains('ant-layout-sider-collapsed')).toBe(false);
expect(localStorage.getItem('sidebar-pinned')).toBe('true');
first.unmount();
const second = renderSidebar();
const restoredSidebar = second.container.querySelector('.ant-layout-sider');
expect(restoredSidebar?.classList.contains('ant-layout-sider-collapsed')).toBe(false);
expect(screen.getByRole('button', { name: 'Unpin sidebar' })).not.toBeNull();
});