Menu
An inline vertical navigation menu with optional groups, dividers, indents, badges, and collapsible sections.
Renders inside a nav landmark with optional aria-label; collapsible groups expose aria-expanded/aria-controls via Collapsible; items expose aria-current for the active route.
import { Menu, MenuGroup, MenuItem, MenuDivider,} from "@arshad-shah/cynosure-react";
<Menu aria-label="Primary"> <MenuGroup label="Workspace"> <MenuItem href="/dashboard" isActive>Dashboard</MenuItem> <MenuItem href="/inbox" badge="12">Inbox</MenuItem> </MenuGroup> <MenuDivider /> <MenuGroup label="Account"> <MenuItem href="/settings">Settings</MenuItem> </MenuGroup></Menu>Menu renders a <nav> landmark. Each MenuItem is polymorphic: pass href to render an <a>, omit it for a <button>, or pass asChild to project the styling onto a router link.
Variants
Section titled “Variants”With icons and badges
Section titled “With icons and badges”MenuItem accepts an icon (leading slot), iconRight (trailing slot), and badge (a small badge rendered just before the trailing icon).
Groups and dividers
Section titled “Groups and dividers”Use MenuGroup to title a cluster of items and MenuDivider to break unrelated sections apart.
Collapsible groups
Section titled “Collapsible groups”Pass collapsible to MenuGroup (with optional defaultOpen) to show a caret that toggles the group’s visibility. Use open / onOpenChange for controlled mode.
Indent levels and active state
Section titled “Indent levels and active state”Use indent={1 | 2 | 3} to communicate hierarchy and isActive to mark the current page (sets aria-current="page" and a data flag for styling).
Disabled item
Section titled “Disabled item”Pass disabled to prevent interaction. The item exposes aria-disabled="true" and skips the href redirect.
Accessibility
Section titled “Accessibility”- The root renders as a
<nav>; passaria-labelso the landmark is named for assistive tech. - Each non-collapsible
MenuGroupcarriesrole="group"and links to its visible label viaaria-labelledby. - Collapsible groups use Cynosure’s
Collapsible(Radix-backed) so the trigger automatically getsaria-expanded/aria-controlswiring. - Active items announce themselves with
aria-current="page". - Disabled items set
aria-disabled="true"whether they render as a<button>or an<a>(thehrefis suppressed when disabled).
Recipes
Section titled “Recipes”- Pair with React Router or TanStack Router via
asChildso item styling projects onto a router-aware<Link>. - Use
badgefor unread counts or status labels — the badge renders inside aghostneutralBadge automatically. - Combine
collapsiblewithdefaultOpen={false}for rarely-used sections that should start hidden. - Indent step is
1remper level — three levels of hierarchy still read comfortably without becoming a tree.