Skip to content

NavRail

Purpose

NavRail provides tab-like navigation with:

  • Animated selection indicator
  • Icon + label layout
  • Router integration
  • Responsive variants (horizontal, vertical, responsive)

When to use

Use NavRail for:

  • Secondary navigation within a page
  • Tab-like content switching
  • Settings section navigation
  • Filter/view mode toggles

Basic usage

tsx
import NavRail from '@/shared/ui/components/navigation/NavRail'
import { LayoutGrid, List, Calendar } from 'lucide-react'

const items = [
  { id: 'grid', icon: <LayoutGrid className="size-4" />, label: 'Grid' },
  { id: 'list', icon: <List className="size-4" />, label: 'List' },
  { id: 'calendar', icon: <Calendar className="size-4" />, label: 'Calendar' },
]

export function ViewToggle() {
  const [view, setView] = useState('grid')

  return (
    <NavRail
      items={items}
      value={view}
      onChange={setView}
      variant="horizontal"
      ariaLabel="View options"
    />
  )
}

With routing

tsx
const navItems = [
  { id: 'overview', to: '/dashboard', icon: <Home />, label: 'Overview' },
  { id: 'analytics', to: '/dashboard/analytics', icon: <BarChart />, label: 'Analytics' },
  { id: 'reports', to: '/dashboard/reports', icon: <FileText />, label: 'Reports' },
]

<NavRail items={navItems} ariaLabel="Dashboard navigation" />

Props

PropTypeDefaultDescription
itemsNavRailItem[]RequiredNavigation items
valuestring-Controlled active item
defaultValuestring-Initial active item
onChange(id: string) => void-Selection change handler
variant'horizontal' | 'vertical' | 'responsive''horizontal'Layout variant
mobileContent'icons' | 'icons-text''icons-text'Mobile display mode
animation'bounce' | 'none''bounce'Selection animation
size'sm' | 'md' | 'lg''md'Size variant
breakpoint'md' | 'lg' | 'xl' | '2xl''md'Responsive breakpoint
ariaLabelstring-Navigation aria-label
classNamestring-Container class
PropertyTypeRequiredDescription
idstringYesUnique identifier
iconReactNodeYesItem icon
labelstringYesItem label
tostringNoRoute path
badgenumber | ReactNodeNoBadge indicator
disabledbooleanNoDisable item

Notes

  • Uses Framer Motion for smooth indicator animation
  • Automatically syncs with React Router when items have to prop
  • Labels can be hidden on mobile with mobileContent="icons"
  • Supports keyboard navigation