GitHub
Core
Glass
Brutal
Humanist

Side Navigation

SideNavigation provides a persistent sidebar navigation with collapsible states, grouped sections, nested items, badges, bottom-pinned items, logo slot, and a feature promotion card.

Side Navigation Playground

Side Navigation Playground
Preview
Code

dashboard

Controls
Variant:
Primary
Neutral
Collapsed:
Logo:
Feature Card:

Installation

You can add the side navigation component to your project manually:

1

Install the following dependencies:

npm install class-variance-authority clsx tailwind-merge @phosphor-icons/react @react-aria/focus @react-aria/interactions @react-aria/progress react-aria-components
2

Copy and paste the following code into your project.

Loading source code...
3

Update the import paths to match your project setup.

Update the import aliases (e.g. @/components, @/utils) in the copied files to match your project's path configuration.

Basic Usage

import { useState } from 'react';
import { SideNavigation } from '@versaui/ui/components/SideNavigation';
import { HouseIcon, ChartBarIcon, GearIcon } from '@phosphor-icons/react';

const sections = [
  {
    header: 'Main',
    items: [
      { id: 'dashboard', label: 'Dashboard', icon: <HouseIcon /> },
      { id: 'reports', label: 'Reports', icon: <ChartBarIcon /> },
    ]
  }
];

function App() {
  const [selectedId, setSelectedId] = useState('dashboard');

  return (
    <SideNavigation
      sections={sections}
      selectedId={selectedId}
      onSelect={(id) => setSelectedId(id)}
    />
  );
}

Sections and Headers

Group navigation items into labeled sections:

const sections = [
  {
    header: 'Main',
    items: [
      { id: 'dashboard', label: 'Dashboard', icon: <HouseIcon /> },
      { id: 'projects', label: 'Projects', icon: <FilesIcon /> },
    ]
  },
  {
    header: 'Analysis',
    items: [
      { id: 'reports', label: 'Reports', icon: <ChartBarIcon /> },
      { id: 'goals', label: 'Goals', icon: <TargetIcon /> },
    ]
  }
];

Nested Items

Menu items can have expandable children:

{
  id: 'team',
  label: 'Team',
  icon: <UsersIcon />,
  children: [
    { id: 'members', label: 'Members', badge: 4 },
    { id: 'roles', label: 'Roles' },
    { id: 'permissions', label: 'Permissions' },
  ]
}

Badges

Show notification counts on items:

{ id: 'projects', label: 'Projects', icon: <FilesIcon />, badge: 12 }

Bottom Items

Pin items like Settings and Support to the bottom:

const bottomItems = [
  { id: 'settings', label: 'Settings', icon: <GearIcon /> },
  { id: 'help', label: 'Support', icon: <LifebuoyIcon /> },
];

<SideNavigation
  sections={sections}
  bottomItems={bottomItems}
/>

Collapsed State

Toggle between full and icon-only modes:

const [collapsed, setCollapsed] = useState(false);

<SideNavigation
  collapsed={collapsed}
  onCollapsedChange={setCollapsed}
  sections={sections}
/>

Neutral Variant

Use the neutral style for a softer selected state with Material surface instead of brand fill:

<SideNavigation
  variant="neutral"
  sections={sections}
  selectedId={selectedId}
  onSelect={(id) => setSelectedId(id)}
/>

Provide expanded and collapsed logo variants:

<SideNavigation
  logo={<img src="/logo-full.svg" height={24} />}
  collapsedLogo={<img src="/logo-icon.svg" height={24} />}
  sections={sections}
/>

Feature Card

Built-in promotion card with usage indicator:

<SideNavigation
  showFeatureCard
  featureCardTitle="Upgrade to Pro"
  featureCardDescription="Get unlimited projects and priority support"
  featureCardButtonText="Upgrade Now"
  onFeatureCardClick={() => openUpgradeModal()}
  usageTitle="You're almost out of Projects"
  usageStatus="4/5 Projects"
  usagePercentage={80}
  sections={sections}
/>

Accessibility

  • Uses <nav> element with aria-label for semantic navigation
  • Keyboard navigation through all items
  • aria-current="page" on the active item
  • Collapsible sections use aria-expanded and aria-controls
  • Focus management for nested item expansion
interface MenuItem {
  id: string;
  label: string;
  icon: ReactNode;
  badge?: number;
  disabled?: boolean;
  href?: string;
  children?: { id: string; label: string; badge?: number; disabled?: boolean; href?: string }[];
}
interface MenuSection {
  header?: string;
  items: MenuItem[];
}

SideNavigation Props

PropTypeDefaultDescription
sectionsMenuSection[][]Array of navigation sections with headers and items.
bottomItemsMenuItem[][]Items pinned to the bottom of the sidebar.
selectedIdstring''Currently active item ID.
onSelect(id: string) => voidCalled when an item is selected.
collapsedbooleanfalseWhether nav is collapsed to icons only.
onCollapsedChange(collapsed: boolean) => voidCalled when collapsed state changes.
variant'primary' | 'neutral''primary'Style variant for navigation items. Neutral uses Material surface for selected state.
showLogobooleantrueShow logo at the top.
logoReactNodeCustom expanded logo element.
collapsedLogoReactNodeCustom collapsed logo element.
logoBrandLogoBrand'versa-ui'Built-in brand logo preset.
showFeatureCardbooleantrueShow feature promotion card.
featureCardTitlestring'Upgrade to Pro'Feature card title.
featureCardDescriptionstringFeature card description.
featureCardButtonTextstring'Upgrade Now'Feature card button text.
onFeatureCardClick() => voidFeature card button click handler.
usageTitlestringUsage indicator title.
usageStatusstringUsage indicator status text.
usagePercentagenumber80Usage progress bar percentage.
heightnumber | string'100%'Sidebar height.
classNamestring''Additional CSS classes.

On this page