nili/ui
All components

Sidebar

Overview
23 exports7 variant axes37 props4 files
import { Sidebar, SidebarCard, SidebarDot, SidebarFooter, SidebarGroup, SidebarHeader } from '@nili/ui';

This is the library’s own overview page, rendered live. Switch the language or the theme in the header and it follows.

The panel

Header, groups of items, and a footer. It collapses itself: leave collapsed off and the panel keeps its own state, and a SidebarTrigger anywhere inside folds it. A sidebar that needs the app to write a useState before it can fold is one most apps ship unfoldable.

import {
  Sidebar, SidebarHeader, SidebarGroup, SidebarItem,
  SidebarFooter, SidebarUser, SidebarTrigger, Icon,
} from "@nili/ui"
import { RiHome5Line, RiFolderLine } from "@remixicon/react"

export function Example() {
  return (
    <Sidebar label="Main">
      <SidebarHeader
        logo={<PlaceholderLogo company="apex-financial" size="sm" label="" />}
        title="Apex Financial"
        subtitle="Pro plan"
        action={<SidebarTrigger />}
        collapsedAction={<SidebarTrigger />}
      />

      <SidebarGroup label="Main">
        <SidebarItem icon={<Icon icon={RiHome5Line} />} href="#">Home</SidebarItem>
        <SidebarItem icon={<Icon icon={RiFolderLine} />} href="#" active>
          Projects
        </SidebarItem>
      </SidebarGroup>

      <SidebarFooter>
        <SidebarUser
          avatar={<Avatar size="sm" name="Ada Lovelace" tone="blue" />}
          name="Ada Lovelace"
          email="ada@nili.design"
        />
      </SidebarFooter>
    </Sidebar>
  )
}

The rail

Expanded and collapsed are one component: every row is the same row with its label faded to zero width, so a row added to one is added to both. The labels stay in the DOM rather than unmounting — a rail of unlabelled icons is the layout that needs its accessible names most.

controlled — collapsed
import { Sidebar } from "@nili/ui"

export function Example() {
  const [collapsed, setCollapsed] = useState(true)

  return (
    <Sidebar
      collapsed={collapsed}
      onCollapsedChange={setCollapsed}
      label="Main"
    >
      …
    </Sidebar>
  )
}