mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-09 21:00:58 +00:00
fix(ui): align sidebar pin controls
Keep the pin with the expanded header actions and center the collapsed version link with the navigation rail.
This commit is contained in:
@@ -34,9 +34,9 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 8px;
|
gap: 4px;
|
||||||
height: 58px;
|
height: 58px;
|
||||||
padding: 0 16px 0 24px;
|
padding: 0 12px 0 16px;
|
||||||
border-bottom: 1px solid var(--ant-color-border-secondary);
|
border-bottom: 1px solid var(--ant-color-border-secondary);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
.brand-actions {
|
.brand-actions {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 2px;
|
gap: 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,26 +231,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-pin {
|
.sidebar-pin {
|
||||||
display: flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 30px;
|
||||||
height: 34px;
|
height: 30px;
|
||||||
padding: 0 16px;
|
padding: 0;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 6px;
|
border-radius: 50%;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: var(--ant-color-text-secondary);
|
color: var(--ant-color-text-secondary);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 13px;
|
flex-shrink: 0;
|
||||||
text-align: left;
|
transition: background-color 0.2s, transform 0.15s, color 0.2s;
|
||||||
transition: background-color 0.2s, color 0.2s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-pin:hover,
|
.sidebar-pin:hover,
|
||||||
.sidebar-pin:focus-visible {
|
.sidebar-pin:focus-visible {
|
||||||
background-color: color-mix(in srgb, var(--ant-color-primary) 10%, transparent);
|
background-color: color-mix(in srgb, var(--ant-color-primary) 10%, transparent);
|
||||||
color: var(--ant-color-primary);
|
color: var(--ant-color-primary);
|
||||||
|
transform: scale(1.08);
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,11 +258,6 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-layout-sider-collapsed .sidebar-pin {
|
|
||||||
justify-content: center;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sider-version {
|
.sider-version {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -278,6 +273,11 @@
|
|||||||
transition: color 0.2s;
|
transition: color 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-layout-sider-collapsed .sider-version {
|
||||||
|
justify-content: center;
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
.sider-version .anticon {
|
.sider-version .anticon {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -304,6 +304,16 @@ export default function AppSidebar() {
|
|||||||
</div>
|
</div>
|
||||||
{!railCollapsed && (
|
{!railCollapsed && (
|
||||||
<div className="brand-actions">
|
<div className="brand-actions">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="sidebar-pin"
|
||||||
|
aria-label={t(pinned ? 'menu.unpinSidebar' : 'menu.pinSidebar')}
|
||||||
|
aria-pressed={pinned}
|
||||||
|
title={t(pinned ? 'menu.unpinSidebar' : 'menu.pinSidebar')}
|
||||||
|
onClick={togglePinned}
|
||||||
|
>
|
||||||
|
{pinned ? <PushpinFilled /> : <PushpinOutlined />}
|
||||||
|
</button>
|
||||||
<DocsButton ariaLabel={t('menu.docs') || 'Documentation'} />
|
<DocsButton ariaLabel={t('menu.docs') || 'Documentation'} />
|
||||||
<DonateButton ariaLabel={t('menu.donate') || 'Donate'} />
|
<DonateButton ariaLabel={t('menu.donate') || 'Donate'} />
|
||||||
<ThemeCycleButton
|
<ThemeCycleButton
|
||||||
@@ -335,17 +345,6 @@ export default function AppSidebar() {
|
|||||||
onClick={onMenuClick}
|
onClick={onMenuClick}
|
||||||
/>
|
/>
|
||||||
<div className="sider-footer">
|
<div className="sider-footer">
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="sidebar-pin"
|
|
||||||
aria-label={t(pinned ? 'menu.unpinSidebar' : 'menu.pinSidebar')}
|
|
||||||
aria-pressed={pinned}
|
|
||||||
title={t(pinned ? 'menu.unpinSidebar' : 'menu.pinSidebar')}
|
|
||||||
onClick={togglePinned}
|
|
||||||
>
|
|
||||||
{pinned ? <PushpinFilled /> : <PushpinOutlined />}
|
|
||||||
{!railCollapsed && <span>{t(pinned ? 'menu.unpinSidebar' : 'menu.pinSidebar')}</span>}
|
|
||||||
</button>
|
|
||||||
<VersionBadge version={panelVersion} collapsed={railCollapsed} />
|
<VersionBadge version={panelVersion} collapsed={railCollapsed} />
|
||||||
</div>
|
</div>
|
||||||
</Layout.Sider>
|
</Layout.Sider>
|
||||||
|
|||||||
@@ -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 first = renderSidebar();
|
||||||
const sidebar = first.container.querySelector('.ant-layout-sider');
|
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);
|
expect(sidebar?.classList.contains('ant-layout-sider-collapsed')).toBe(true);
|
||||||
|
|
||||||
fireEvent.click(screen.getByRole('button', { name: 'Pin sidebar' }));
|
fireEvent.mouseEnter(sidebarRoot!);
|
||||||
fireEvent.mouseLeave(first.container.querySelector('.ant-sidebar')!);
|
|
||||||
|
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(sidebar?.classList.contains('ant-layout-sider-collapsed')).toBe(false);
|
||||||
expect(localStorage.getItem('sidebar-pinned')).toBe('true');
|
expect(localStorage.getItem('sidebar-pinned')).toBe('true');
|
||||||
|
|||||||
Reference in New Issue
Block a user