Component

SidebarNav

Vertical navigation sidebar with grouped items, active state, and a brand header. Pass a custom renderLink to use your router's Link component.

With groups

live editor — edit to update preview
function Demo() {
  const [active, setActive] = useState("/badge");
  const groups = [
    {
      label: "Primitives",
      items: [
        { label: "Badge", href: "/badge" },
        { label: "Button", href: "/button" },
        { label: "Card", href: "/card" },
      ],
    },
    {
      label: "Data Display",
      items: [
        { label: "Table", href: "/table" },
        { label: "Pagination", href: "/pagination" },
      ],
    },
  ];
  return (
    <div style={{ height: 360, display: "flex" }}>
      <SidebarNav
        brand={{ label: "Design System", meta: "@ann/ui" }}
        topItems={[{ label: "Overview", href: "/", active: active === "/" }]}
        groups={groups.map((g) => ({
          ...g,
          items: g.items.map((item) => ({ ...item, active: item.href === active })),
        }))}
        renderLink={(item, children, className, style) => (
          <a
            href="#"
            className={className}
            style={style}
            onClick={(e) => { e.preventDefault(); setActive(item.href); }}
          >
            {children}
          </a>
        )}
      />
    </div>
  );
}
render(<Demo />);

Props

PropTypeDefaultDescription
brand*{ label: string; meta?: string }Brand name shown in the header. meta appears above in small mono text (e.g. package name).
topItemsSidebarNavItem[]Ungrouped items shown above the groups (e.g. Overview).
groups*SidebarNavGroup[]Array of { label, items }. Each item is { label, href, active? }.
renderLink(item, children, className, style) => ReactNodeCustom link renderer. Defaults to <a>. Pass Next.js Link for client-side routing.