tighten nav item spacing, reduce icon size, and shrink padding

This commit is contained in:
Seth Van Niekerk 2026-06-10 18:40:31 -04:00
parent 598eaa27cf
commit e797047689
No known key found for this signature in database
GPG key ID: E86ACA677312A675
4 changed files with 45 additions and 56 deletions

View file

@ -62,14 +62,14 @@ const NavItem = ({ item, isActive, collapsed }) => {
to={item.path}
className={`navlink${isActive ? ' navlink-active' : ''}${collapsed ? ' navlink-collapsed' : ''}`}
>
{Icon && <Icon size={20} />}
{Icon && <Icon size={18} />}
{!collapsed && (
<Text size="sm" style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', flex: 1, minWidth: 0 }}>
<Text size="xs" style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', flex: 1, minWidth: 0 }}>
{item.label}
</Text>
)}
{!collapsed && item.badge && (
<Text size="sm" style={{ color: '#D4D4D8', whiteSpace: 'nowrap' }}>
<Text size="xs" style={{ color: '#D4D4D8', whiteSpace: 'nowrap' }}>
{item.badge}
</Text>
)}
@ -105,10 +105,10 @@ function NavGroup({ label, paths, location, collapsed, onSettingsClick, settings
className={`navlink${isActive ? ' navlink-active' : ''}${collapsed ? ' navlink-collapsed' : ''}`}
style={{ width: '100%' }}
>
{Icon && <Icon size={20} />}
{Icon && <Icon size={18} />}
{!collapsed && (
<>
<Text size="sm" style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', flex: 1, minWidth: 0 }}>
<Text size="xs" style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', flex: 1, minWidth: 0 }}>
{child.label}
</Text>
<ChevronRight size={14} style={{ flexShrink: 0, opacity: 0.5 }} />
@ -135,9 +135,9 @@ const BackButton = ({ label, collapsed, onClick }) => (
className={`navlink${collapsed ? ' navlink-collapsed' : ''}`}
style={{ width: '100%' }}
>
<ArrowLeft size={20} />
<ArrowLeft size={18} />
{!collapsed && (
<Text size="sm" fw={500} style={{ whiteSpace: 'nowrap' }}>
<Text size="xs" fw={500} style={{ whiteSpace: 'nowrap' }}>
{label}
</Text>
)}
@ -242,7 +242,7 @@ const Sidebar = ({ collapsed, toggleDrawer, drawerWidth, miniDrawerWidth }) => {
className={`navlink${isActive ? ' navlink-active' : ''}${collapsed ? ' navlink-collapsed' : ''}`}
style={{ width: '100%' }}
>
{Icon && <Icon size={20} />}
{Icon && <Icon size={18} />}
{!collapsed && (
<>
<Text style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', flex: 1, minWidth: 0 }}>
@ -291,29 +291,31 @@ const Sidebar = ({ collapsed, toggleDrawer, drawerWidth, miniDrawerWidth }) => {
{group.label}
</Text>
)}
{group.sections.map((section) => {
const Icon = section.icon;
return (
<Tooltip
key={section.id}
label={section.label}
position="right"
withArrow
disabled={!collapsed}
>
<UnstyledButton
onClick={() => navigate(`/settings#${section.id}`, { replace: true })}
className={`navlink${activeSettingsId === section.id ? ' navlink-active' : ''}${collapsed ? ' navlink-collapsed' : ''}`}
style={{ width: '100%' }}
<Stack gap={4}>
{group.sections.map((section) => {
const Icon = section.icon;
return (
<Tooltip
key={section.id}
label={section.label}
position="right"
withArrow
disabled={!collapsed}
>
<Icon size={20} />
{!collapsed && (
<Text size="sm" style={{ whiteSpace: 'nowrap' }}>{section.label}</Text>
)}
</UnstyledButton>
</Tooltip>
);
})}
<UnstyledButton
onClick={() => navigate(`/settings#${section.id}`, { replace: true })}
className={`navlink${activeSettingsId === section.id ? ' navlink-active' : ''}${collapsed ? ' navlink-collapsed' : ''}`}
style={{ width: '100%' }}
>
<Icon size={18} />
{!collapsed && (
<Text size="xs" style={{ whiteSpace: 'nowrap' }}>{section.label}</Text>
)}
</UnstyledButton>
</Tooltip>
);
})}
</Stack>
</Box>
))}
</Stack>
@ -387,7 +389,7 @@ const Sidebar = ({ collapsed, toggleDrawer, drawerWidth, miniDrawerWidth }) => {
environment.ip_lookup_enabled !== false &&
environment.ip_lookup_pending && (
<Box>
<Text size="sm" fw={500} mb={4}>Public IP</Text>
<Text size="xs" fw={500} mb={4}>Public IP</Text>
<Skeleton height={36} radius="sm" />
</Box>
)}
@ -398,7 +400,7 @@ const Sidebar = ({ collapsed, toggleDrawer, drawerWidth, miniDrawerWidth }) => {
environment.public_ip &&
!environment.public_ip.startsWith('Error') && (
<Box onClick={() => setIpRevealed((v) => !v)} style={{ cursor: 'pointer' }}>
<Text size="sm" fw={500} mb={4}>Public IP</Text>
<Text size="xs" fw={500} mb={4}>Public IP</Text>
<Box
style={{
display: 'flex',
@ -454,7 +456,7 @@ const Sidebar = ({ collapsed, toggleDrawer, drawerWidth, miniDrawerWidth }) => {
{authUser.first_name || authUser.username}
</UnstyledButton>
</Group>
<ActionIcon variant="transparent" color="white" size="sm">
<ActionIcon variant="transparent" color="white" size="xs">
<LogOut onClick={logout} />
</ActionIcon>
</Group>

View file

@ -4,7 +4,7 @@
flex-wrap: nowrap;
align-items: center;
gap: 12px;
padding: 8px 10px !important;
padding: 4px 8px !important;
border-radius: 6px;
background-color: transparent; /* Default background when not active */
border: 1px solid transparent;
@ -20,8 +20,8 @@
}
/* Hover effect */
.navlink:hover, .navlink-parent-active {
background-color: #2A2F34; /* Gray hover effect when not active */
.navlink:hover {
background-color: #2A2F34;
border: 1px solid #3D3D42;
}
@ -34,26 +34,11 @@
/* Collapse condition for justifyContent */
.navlink.navlink-collapsed {
justify-content: center;
padding: 8px !important;
padding: 4px !important;
}
.navlink:not(.navlink-collapsed) {
justify-content: flex-start;
}
/* Left indicator for open nav groups rendered outside buttons */
.navgroup-open {
position: relative;
overflow: visible;
}
.navgroup-open::before {
content: '';
position: absolute;
left: 0; /* avoid horizontal overflow; sits at container edge */
top: 0;
bottom: 0;
width: 2px;
background: #3BA882;
pointer-events: none;
z-index: 2;
}

View file

@ -4,6 +4,7 @@ import {
Box,
Divider,
Loader,
Paper,
Text,
} from '@mantine/core';
import { SETTINGS_GROUPS } from '../config/settingsNav';
@ -83,9 +84,9 @@ const SettingsPage = () => {
const ActiveComponent = activeSectionConfig ? COMPONENT_MAP[activeSectionConfig.id] : null;
return (
<Box p={10}>
<Box p={10} maw={900} mx="auto">
{ActiveComponent ? (
<Box>
<Paper withBorder p="md" radius="md">
<Text size="lg" fw={600} mb={6}>
{activeSectionConfig.label}
</Text>
@ -95,7 +96,7 @@ const SettingsPage = () => {
<ActiveComponent active={true} />
</Suspense>
</ErrorBoundary>
</Box>
</Paper>
) : (
<Box
style={{

View file

@ -69,6 +69,7 @@ vi.mock('@mantine/core', async () => ({
Box: ({ children }) => <div>{children}</div>,
Divider: () => <hr />,
Loader: () => <div data-testid="loader">Loading...</div>,
Paper: ({ children }) => <div>{children}</div>,
Text: ({ children }) => <span>{children}</span>,
}));