Files
doormile_crm/src/layout/MainLayout/Sidebar.jsx

170 lines
7.5 KiB
JavaScript

import { useLocation } from 'react-router-dom';
import { SideNav, SideNavSection, SideNavItem } from '@astryxdesign/core/SideNav';
import { Text } from '@astryxdesign/core/Text';
import navItems from '@/menu/navItems';
// ==============================|| DOORMILE - SIDE NAV ||============================== //
// Thin wrapper around Astryx's SideNav template: sections + items driven by navItems.
// Branding lives in the TopNav logo only — a second logo here (above the nav items)
// duplicated it, so this stays icon+label only. Collapse state is controlled from
// MainLayout so the TopNav logo can track it (round mark collapsed, full wordmark
// expanded).
export default function Sidebar({ isCollapsed, onCollapsedChange }) {
const location = useLocation();
const isActive = (url) => !!url && location.pathname.startsWith(url);
return (
<>
<SideNav
className="doormile-side-nav"
collapsible={{ isCollapsed, onCollapsedChange, buttonLabel: 'Collapse navigation' }}
style={{
// White + a right border/shadow matches the TopNav's chrome so the
// top and side nav read as one unified surface instead of two
// mismatched panels (TopNav is white with a bottom border already).
backgroundColor: '#ffffff',
borderRight: '1px solid rgba(5, 54, 89, 0.08)',
boxShadow: '1px 0 3px rgba(15, 23, 42, 0.03)',
paddingBlock: '12px',
paddingInline: '8px',
boxSizing: 'border-box',
// Astryx's collapsed-rail width reads var(--spacing-12) (48px default),
// which feels cramped for our icons. Overriding the token on this
// element only widens the collapsed rail without touching the same
// token's unrelated uses elsewhere (e.g. AppShell's mobile top bar).
'--spacing-12': '72px'
}}
>
{navItems.map((grp) => (
<SideNavSection key={grp.group} title={grp.group}>
{grp.items.map((item) => (
<SideNavItem
key={item.id}
label={item.title}
icon={item.icon}
href={item.url}
isSelected={isActive(item.url)}
/>
))}
</SideNavSection>
))}
</SideNav>
<style>{`
/* Astryx packs items 2px apart by default, which reads as one
merged block on hover instead of distinct rows. The items
wrapper has no stable class of its own, but it's always the
section's second/last child div, right after the header. */
.doormile-side-nav .astryx-side-nav-section > div:last-child {
gap: 6px !important;
}
/* Collapsed nav items are the only ones Astryx renders with an
aria-label on the item element itself (expanded rows show the
label as visible text instead), so it doubles as a stable hook
for "collapsed only" styling without touching the expanded rail. */
.doormile-side-nav .astryx-side-nav-item[aria-label] {
width: 40px;
height: 40px;
margin-inline: auto;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.15s ease;
}
.doormile-side-nav .astryx-side-nav-item[aria-label] .astryx-icon {
width: 18px !important;
height: 18px !important;
}
.doormile-side-nav .astryx-side-nav-item[aria-label]:hover {
background-color: rgba(10, 19, 23, 0.08) !important;
}
.doormile-side-nav .astryx-side-nav-item[aria-label]:focus-visible {
outline: 2px solid rgba(10, 19, 23, 0.4);
outline-offset: 2px;
}
.doormile-side-nav .astryx-side-nav-item[aria-label][data-selected='selected'] {
background-color: rgba(10, 19, 23, 0.12) !important;
}
.doormile-side-nav .astryx-side-nav-item[aria-label][data-selected='selected'] .astryx-icon {
color: #0A1317 !important;
}
/* Expanded rows: rounded hover/selected states with a left accent
bar on the active item, instead of the default flat highlight.
The accent bar is always present (via ::before) but only faded
in on selection, so clicking a link fades it in smoothly instead
of the bar snapping into place flush against the row edges.
Row sizing mirrors doormile_console's NavItem pattern (py: 1,
i.e. 8px top/bottom padding on the button itself) instead of a
fixed-height row: the highlight is painted directly on the item's
own (now-padded) background, so it naturally gets breathing room
above and below rather than filling a cramped fixed-height box
edge to edge. */
.doormile-side-nav .astryx-side-nav-item:not([aria-label]) {
position: relative;
margin-inline: 2px;
height: auto;
padding-block: 12px !important;
transition: background-color 0.15s ease, transform 0.15s ease;
}
.doormile-side-nav .astryx-side-nav-item:not([aria-label])::before {
content: '';
position: absolute;
left: -2px;
top: 12px;
bottom: 12px;
width: 3px;
border-radius: 3px;
background-color: #0A1317;
opacity: 0;
transition: opacity 0.15s ease;
}
.doormile-side-nav .astryx-side-nav-item:not([aria-label]):hover {
background-color: rgba(10, 19, 23, 0.05) !important;
transform: translateX(2px);
}
.doormile-side-nav .astryx-side-nav-item:not([aria-label]):focus-visible {
outline: 2px solid rgba(10, 19, 23, 0.4);
outline-offset: 2px;
}
.doormile-side-nav .astryx-side-nav-item:not([aria-label])[data-selected='selected'] {
background-color: rgba(10, 19, 23, 0.08) !important;
}
.doormile-side-nav .astryx-side-nav-item:not([aria-label])[data-selected='selected']::before {
opacity: 1;
}
.doormile-side-nav .astryx-side-nav-item:not([aria-label])[data-selected='selected'] .astryx-icon {
color: #0A1317 !important;
}
/* Astryx's sticky-bottom footer wrapper (the toggle button's direct
parent, always the nav's last direct child) drops its top padding
to 0 in the collapsed state while keeping 8px on the bottom, so
the arrow sits flush against the top of its box instead of
centered in the rail's height. Restore matching padding on both
sides so it centers correctly. */
.doormile-side-nav > div:last-child {
padding-block: 8px !important;
}
/* Collapse/expand toggle (the "<" / ">" chevron button). Give it a
clean circular hover, centered on the same axis as the nav icons
above it (the rail's own 8px inline padding already keeps it clear
of the sidebar's edge, so no extra offset is needed here). */
.doormile-side-nav button[aria-label*="sidebar"],
.doormile-side-nav button[aria-label*="navigation"] {
border-radius: 50% !important;
transition: background-color 0.15s ease !important;
}
.doormile-side-nav button[aria-label*="sidebar"]:hover,
.doormile-side-nav button[aria-label*="navigation"]:hover {
background-color: rgba(10, 19, 23, 0.08) !important;
}
`}</style>
</>
);
}