Skip to main content

Sidebar

Sticky sidebar with mobile overlay toggle. Supports nested items via <details>.

Preview ยท Sidebar

Codeโ€‹

<div style="border:1px solid var(--border);border-radius:var(--radius-medium);overflow:hidden;max-width:200px;min-height:260px;background:var(--card)">
<div style="padding:0.875rem 1rem;border-bottom:1px solid var(--border);font-weight:600;font-size:0.875rem">Primus Admin</div>
<nav style="padding:0.5rem">
<ul style="list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px">
<li><a href="#" style="display:block;padding:0.45rem 0.75rem;border-radius:5px;background:color-mix(in srgb,var(--primary) 10%,transparent);color:var(--primary);font-size:0.8125rem;text-decoration:none;font-weight:500" aria-current="page">Dashboard</a></li>
<li><a href="#" style="display:block;padding:0.45rem 0.75rem;border-radius:5px;color:var(--foreground);font-size:0.8125rem;text-decoration:none">Tenants</a></li>
<li><a href="#" style="display:block;padding:0.45rem 0.75rem;border-radius:5px;color:var(--foreground);font-size:0.8125rem;text-decoration:none">Users</a></li>
<li><a href="#" style="display:block;padding:0.45rem 0.75rem;border-radius:5px;color:var(--foreground);font-size:0.8125rem;text-decoration:none">Settings</a></li>
</ul>
</nav>
</div>

Propsโ€‹

PropTypeDefaultDescription
itemsSidebarItem[]requiredNavigation item list
activeIdstringโ€”ID of the currently active item
logostringโ€”URL to logo image shown at top
footerReactNodeโ€”Slot for bottom content (user avatar, etc.)
onItemClick / (onItemClick)(item: SidebarItem) => voidโ€”Fires when a nav item is clicked

TypeScript interfacesโ€‹

interface SidebarItem {
id: string; // Unique identifier โ€” matched against activeId
label: string; // Display label
href?: string; // Anchor href (plain HTML navigation)
route?: string; // Angular Router route or React Router path
target?: '_blank' | '_self'; // Link target (default: '_self')
icon?: React.ReactNode; // Optional leading icon
badge?: string | number; // Optional badge count/label
children?: SidebarItem[]; // Nested items (renders as collapsible group)
disabled?: boolean; // Greyed out, non-clickable
}

// Example
const navItems: SidebarItem[] = [
{ id: 'dashboard', label: 'Dashboard', route: '/dashboard' },
{ id: 'tenants', label: 'Tenants', route: '/tenants', badge: 3 },
{
id: 'reports', label: 'Reports',
children: [
{ id: 'reports-mrr', label: 'MRR', route: '/reports/mrr' },
{ id: 'reports-churn', label: 'Churn', route: '/reports/churn' },
],
},
{ id: 'settings', label: 'Settings', route: '/settings' },
];
Version history

See the Changelog for version history and breaking changes.