Skip to content

Sidebar

A sidebar of navigation: the team or product name at the top, grouped links with sub-items and badges, an optional footer, and the signed-in person at the bottom. It can fold down to icons, and comes in four looks. It is only the panel; DashboardShell adds the top bar and the phone menu.

Blockv0.1.0experimentalWCAG 2.2 AAView spec

A ready-made piece, built from the library's own parts.

A block puts several components together into something you would otherwise assemble by hand. It never fetches data: you give it the data, or answer its callbacks. It is copied into your project like any component, with the parts it uses, so you can change anything.

Basic

Full screen (opens in a new tab)
Skip to main content

Dashboard

How the business is doing this week.

Key numbers

Revenue: $48,200. Up 12.5%. Up on last week.
New customers: 1,234. Down 4%. A quiet week.
Active accounts: 45,678. Up 8.1%. Retention is steady.
VisitorsDesktop and mobile, this weekArea chart of Desktop, Mobile across 7 points. Desktop is highest at 520 (Thu) and lowest at 300 (Sun).
  • Desktop
  • Mobile

Recent customers

Status
Plan
Sort by

8 customers

  • Ada Lovelaceada@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    Jan 4, 2026
  • Grace Hoppergrace@example.com · Compiler Labsactive
    Plan
    Pro
    Revenue
    $29
    Joined
    Feb 7, 2026
  • Katherine Johnsonkatherine@example.com · Orbit Systemstrial
    Plan
    Team
    Revenue
    $99
    Joined
    Mar 10, 2026
  • Alan Turingalan@example.com · Enigma Worksoverdue
    Plan
    Enterprise
    Revenue
    $499
    Joined
    Apr 13, 2026
  • Margaret Hamiltonmargaret@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    May 16, 2026

Showing 1 to 5 of 8

Inset

Full screen (opens in a new tab)
Skip to main content

Dashboard

How the business is doing this week.

Key numbers

Revenue: $48,200. Up 12.5%. Up on last week.
New customers: 1,234. Down 4%. A quiet week.
Active accounts: 45,678. Up 8.1%. Retention is steady.
VisitorsDesktop and mobile, this weekArea chart of Desktop, Mobile across 7 points. Desktop is highest at 520 (Thu) and lowest at 300 (Sun).
  • Desktop
  • Mobile

Recent customers

Status
Plan
Sort by

8 customers

  • Ada Lovelaceada@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    Jan 4, 2026
  • Grace Hoppergrace@example.com · Compiler Labsactive
    Plan
    Pro
    Revenue
    $29
    Joined
    Feb 7, 2026
  • Katherine Johnsonkatherine@example.com · Orbit Systemstrial
    Plan
    Team
    Revenue
    $99
    Joined
    Mar 10, 2026
  • Alan Turingalan@example.com · Enigma Worksoverdue
    Plan
    Enterprise
    Revenue
    $499
    Joined
    Apr 13, 2026
  • Margaret Hamiltonmargaret@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    May 16, 2026

Showing 1 to 5 of 8

Floating

Full screen (opens in a new tab)
Skip to main content

Dashboard

How the business is doing this week.

Key numbers

Revenue: $48,200. Up 12.5%. Up on last week.
New customers: 1,234. Down 4%. A quiet week.
Active accounts: 45,678. Up 8.1%. Retention is steady.
VisitorsDesktop and mobile, this weekArea chart of Desktop, Mobile across 7 points. Desktop is highest at 520 (Thu) and lowest at 300 (Sun).
  • Desktop
  • Mobile

Recent customers

Status
Plan
Sort by

8 customers

  • Ada Lovelaceada@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    Jan 4, 2026
  • Grace Hoppergrace@example.com · Compiler Labsactive
    Plan
    Pro
    Revenue
    $29
    Joined
    Feb 7, 2026
  • Katherine Johnsonkatherine@example.com · Orbit Systemstrial
    Plan
    Team
    Revenue
    $99
    Joined
    Mar 10, 2026
  • Alan Turingalan@example.com · Enigma Worksoverdue
    Plan
    Enterprise
    Revenue
    $499
    Joined
    Apr 13, 2026
  • Margaret Hamiltonmargaret@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    May 16, 2026

Showing 1 to 5 of 8

Collapsed

Full screen (opens in a new tab)
Skip to main content

Dashboard

How the business is doing this week.

Key numbers

Revenue: $48,200. Up 12.5%. Up on last week.
New customers: 1,234. Down 4%. A quiet week.
Active accounts: 45,678. Up 8.1%. Retention is steady.
VisitorsDesktop and mobile, this weekArea chart of Desktop, Mobile across 7 points. Desktop is highest at 520 (Thu) and lowest at 300 (Sun).
  • Desktop
  • Mobile

Recent customers

Status
Plan
Sort by

8 customers

  • Ada Lovelaceada@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    Jan 4, 2026
  • Grace Hoppergrace@example.com · Compiler Labsactive
    Plan
    Pro
    Revenue
    $29
    Joined
    Feb 7, 2026
  • Katherine Johnsonkatherine@example.com · Orbit Systemstrial
    Plan
    Team
    Revenue
    $99
    Joined
    Mar 10, 2026
  • Alan Turingalan@example.com · Enigma Worksoverdue
    Plan
    Enterprise
    Revenue
    $499
    Joined
    Apr 13, 2026
  • Margaret Hamiltonmargaret@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    May 16, 2026

Showing 1 to 5 of 8

Standalone

Full screen (opens in a new tab)
LoomworksEnterprise

Free plan

In a sheet

Full screen (opens in a new tab)
Acme Cloud

Permissions

Full screen (opens in a new tab)
Acme

ClassNames

Full screen (opens in a new tab)
Acme

With submenus

Full screen (opens in a new tab)
Skip to main content

Retention

How the business is doing this week.

Key numbers

Revenue: $48,200. Up 12.5%. Up on last week.
New customers: 1,234. Down 4%. A quiet week.
Active accounts: 45,678. Up 8.1%. Retention is steady.
VisitorsDesktop and mobile, this weekArea chart of Desktop, Mobile across 7 points. Desktop is highest at 520 (Thu) and lowest at 300 (Sun).
  • Desktop
  • Mobile

Recent customers

Status
Plan
Sort by

8 customers

  • Ada Lovelaceada@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    Jan 4, 2026
  • Grace Hoppergrace@example.com · Compiler Labsactive
    Plan
    Pro
    Revenue
    $29
    Joined
    Feb 7, 2026
  • Katherine Johnsonkatherine@example.com · Orbit Systemstrial
    Plan
    Team
    Revenue
    $99
    Joined
    Mar 10, 2026
  • Alan Turingalan@example.com · Enigma Worksoverdue
    Plan
    Enterprise
    Revenue
    $499
    Joined
    Apr 13, 2026
  • Margaret Hamiltonmargaret@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    May 16, 2026

Showing 1 to 5 of 8

Icon rail

Full screen (opens in a new tab)
Skip to main content

Overview

How the business is doing this week.

Key numbers

Revenue: $48,200. Up 12.5%. Up on last week.
New customers: 1,234. Down 4%. A quiet week.
Active accounts: 45,678. Up 8.1%. Retention is steady.
VisitorsDesktop and mobile, this weekArea chart of Desktop, Mobile across 7 points. Desktop is highest at 520 (Thu) and lowest at 300 (Sun).
  • Desktop
  • Mobile

Recent customers

Status
Plan
Sort by

8 customers

  • Ada Lovelaceada@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    Jan 4, 2026
  • Grace Hoppergrace@example.com · Compiler Labsactive
    Plan
    Pro
    Revenue
    $29
    Joined
    Feb 7, 2026
  • Katherine Johnsonkatherine@example.com · Orbit Systemstrial
    Plan
    Team
    Revenue
    $99
    Joined
    Mar 10, 2026
  • Alan Turingalan@example.com · Enigma Worksoverdue
    Plan
    Enterprise
    Revenue
    $499
    Joined
    Apr 13, 2026
  • Margaret Hamiltonmargaret@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    May 16, 2026

Showing 1 to 5 of 8

Full screen (opens in a new tab)
Skip to main content

Dashboard

How the business is doing this week.

Key numbers

Revenue: $48,200. Up 12.5%. Up on last week.
New customers: 1,234. Down 4%. A quiet week.
Active accounts: 45,678. Up 8.1%. Retention is steady.
VisitorsDesktop and mobile, this weekArea chart of Desktop, Mobile across 7 points. Desktop is highest at 520 (Thu) and lowest at 300 (Sun).
  • Desktop
  • Mobile

Recent customers

Status
Plan
Sort by

8 customers

  • Ada Lovelaceada@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    Jan 4, 2026
  • Grace Hoppergrace@example.com · Compiler Labsactive
    Plan
    Pro
    Revenue
    $29
    Joined
    Feb 7, 2026
  • Katherine Johnsonkatherine@example.com · Orbit Systemstrial
    Plan
    Team
    Revenue
    $99
    Joined
    Mar 10, 2026
  • Alan Turingalan@example.com · Enigma Worksoverdue
    Plan
    Enterprise
    Revenue
    $499
    Joined
    Apr 13, 2026
  • Margaret Hamiltonmargaret@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    May 16, 2026

Showing 1 to 5 of 8

Grouped sections

Full screen (opens in a new tab)
Skip to main content

Mentions

How the business is doing this week.

Key numbers

Revenue: $48,200. Up 12.5%. Up on last week.
New customers: 1,234. Down 4%. A quiet week.
Active accounts: 45,678. Up 8.1%. Retention is steady.
VisitorsDesktop and mobile, this weekArea chart of Desktop, Mobile across 7 points. Desktop is highest at 520 (Thu) and lowest at 300 (Sun).
  • Desktop
  • Mobile

Recent customers

Status
Plan
Sort by

8 customers

  • Ada Lovelaceada@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    Jan 4, 2026
  • Grace Hoppergrace@example.com · Compiler Labsactive
    Plan
    Pro
    Revenue
    $29
    Joined
    Feb 7, 2026
  • Katherine Johnsonkatherine@example.com · Orbit Systemstrial
    Plan
    Team
    Revenue
    $99
    Joined
    Mar 10, 2026
  • Alan Turingalan@example.com · Enigma Worksoverdue
    Plan
    Enterprise
    Revenue
    $499
    Joined
    Apr 13, 2026
  • Margaret Hamiltonmargaret@example.com · Analytical Coactive
    Plan
    Free
    Revenue
    $0
    Joined
    May 16, 2026

Showing 1 to 5 of 8

Installation

npx rdloom add sidebar

Copies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes. It needs react-aria-components; add --install to install them.

Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/sidebar.json

Works, but without upgrade tracking.

Usage

import {
  BreadcrumbItem,
  Breadcrumbs,
  Button,
  Chart,
  ChartIcon,
  CreditCardIcon,
  CustomerTable,
  DashboardPage,
  DashboardShell,
  EmptyState,
  GlobeIcon,
  HomeIcon,
  InboxIcon,
  SettingsIcon,
  SparkleIcon,
  UsersIcon,
  findNavItem,
  trailOf,
  type Customer,
  type NavGroup,
} from "@rdloom/react";

    <DashboardPage
      title="Dashboard"
      description="How the business is doing this week."
      actions={
        <>
          <Button variant="secondary">Export</Button>
          <Button>New report</Button>
        </>
      }
      stats={[
        { label: "Revenue", value: "$48,200", trend: { change: 12.5 }, summary: "Up on last week" },
        { label: "New customers", value: 1234, trend: { change: -4 }, summary: "A quiet week" },
        { label: "Active accounts", value: 45678, trend: { change: 8.1 }, summary: "Retention is steady" },
      ]}
    >
      <div className="rounded-2xl border border-[var(--rd-color-border-default)] bg-[var(--rd-color-surface-default)] p-5 [box-shadow:var(--rd-elevation-raised)]">
        <Chart
          type="area"
          title="Visitors"
          description="Desktop and mobile, this week"
          height={240}
          data={{
            labels: week,
            series: [
              { name: "Desktop", values: [320, 410, 380, 520, 480, 360, 300] },
              { name: "Mobile", values: [210, 260, 300, 340, 390, 420, 380] },
            ],
          }}
        />
      </div>
      <div className="flex flex-col gap-3">
        <h2 className="text-lg font-semibold tracking-[-0.01em]">Recent customers</h2>
        <CustomerTable customers={customers} insights="none" pageSize={5} locale="en-US" />
      </div>
    </DashboardPage>
  );
}

// The sidebar is the left column of the shell. Items without an href call onNavigate; with an href they are real links.
export default function SidebarBasicExample() {
  const [current, setCurrent] = useState("overview");
  const [team, setTeam] = useState(teams[0]);
  const page = findNavItem(navigation, current)!;
  const trail = trailOf(navigation, current);

  return (
    <div className="h-full w-full">
      <DashboardShell
        navigation={navigation}
        currentId={current}
        onNavigate={(item) => setCurrent(item.id)}
        team={team}
        teams={teams}
        onTeamChange={(t) => setTeam(teams.find((x) => x.id === t.id) ?? teams[0])}
        user={{ name: "Ada Lovelace", email: "ada@example.com", menu: [{ id: "profile", label: "Your profile", onSelect: () => {} }, { id: "out", label: "Sign out", onSelect: () => {}, variant: "danger" }] }}
        onSearch={() => {}}
        sidebarAppearance="bordered"
        header={
          <Breadcrumbs label="You are here">
            <BreadcrumbItem>{navigation.find((g) => g.items.some((i) => i.id === current || i.children?.some((c) => c.id === current)))?.label ?? "Platform"}</BreadcrumbItem>
            <BreadcrumbItem>{trail[trail.length - 1] ?? page.label}</BreadcrumbItem>
          </Breadcrumbs>
        }
      >
        {current === "overview" ? (
          <Overview />
        ) : (
          <DashboardPage title={page.label}>
            <EmptyState title={`${page.label} is yours to build`} description="Put any page here. The sidebar, the top bar and the way they fold on a phone are already done." />
          </DashboardPage>
        )}
      </DashboardShell>
    </div>

API Reference

Defined by the spec. Components also accept the props of the React Aria component they wrap.

PropTypeDefault
navigationrequired

The navigation as groups of items. An item may hold one level of sub-items. An item may carry a permission ("allow", "disabled", "hidden" or { state, reason }): hidden items, and groups or parents left with nothing, are not drawn or counted; disabled items stay as focusable, non-navigating entries (aria-disabled) with the reason in a tooltip.

NavGroup[]none
currentId

The id of the page you are on. It is marked as the current page (aria-current) and its parent opens.

stringnone
brand

Your logo or product name at the top. Ignored when a team is given.

nodenone
team

The organisation or workspace shown at the top, with its logo and a second line such as the plan. Replaces brand.

ShellTeamnone
teams

Other workspaces to switch to. With two or more the team becomes a menu.

ShellTeam[]none
onTeamChange

Called with the workspace the person chose.

(team: ShellTeam) => voidnone
user

The signed-in person: shown at the bottom with an account menu.

ShellUsernone
footer

Content above the account area, such as an upgrade card or a storage meter. It is hidden while the sidebar is folded.

nodenone
onSearch

Shows a search button under the name and calls this when it is pressed, e.g. to open a command palette.

() => voidnone
searchLabel

Text and accessible name of the search button.

string"Search"
label

Accessible name of the navigation.

string"Main navigation"
onNavigate

Called with the item when one is chosen. Items without an href use this to do their work.

(item: NavItem) => voidnone
renderLink

Draw items as your router's link. Return the link with the given className and children; call onClick when chosen. Without it, items with an href are plain links.

(props: { item: NavItem; className: string; children: ReactNode; isCurrent: boolean; onClick: () => void }) => ReactNodenone
onPick

Called after any item is chosen. Use it to close a sheet that holds the sidebar on a phone.

() => voidnone
isCollapsed

Controlled: whether the sidebar is folded down to icons.

booleannone
defaultCollapsed

Start folded down.

booleanfalse
onCollapsedChange

Called when the person folds or opens the sidebar. Save it if you want it remembered.

(collapsed: boolean) => voidnone
collapsible

Show the Collapse button at the bottom. Turn it off when you fold the sidebar from somewhere else, such as a top bar.

booleantrue
classNames

Class names for the parts of the sidebar, by slot name, added after the built-in ones so you can restyle one part without editing the file. Slots: root, header, team-switcher, search, nav, group, item, sub-list, footer, collapse, account.

Partial<Record<"root" | "header" | "team-switcher" | "search" | "nav" | "group" | "item" | "sub-list" | "footer" | "collapse" | "account", string>>none
appearance

bordered: a line on the inner edge. subtle: a tinted panel with no line. floating: a rounded raised card with a margin around it. inset: no line and no fill, for a sidebar that sits on a tinted page beside an inset page card (DashboardShell draws that page card).

"bordered" | "subtle" | "floating" | "inset""bordered"

Accessibility

Role navigation, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.

Keyboard

  • Tab: search button, items, Collapse button, then the account menu
  • Enter or Space: follows a link or presses an item; on an item with sub-items, opens and closes its list
  • In the account and workspace menus: arrow keys move, Enter chooses, Escape closes

Screen readers announce

  • "Main navigation, navigation", then each item; the current one reads "Customers, current page"
  • "Reports, button, collapsed" for an item with sub-items, "expanded" once opened
  • "Collapse sidebar, button, expanded"
  • "Account menu, Ada Lovelace, menu button"

What your code must do

  • The links are inside a named navigation landmark
  • The current page is marked with aria-current="page" and also shown by a tinted background, an accent-colored icon and a heavier label, never by color alone
  • An item with sub-items is a button with aria-expanded and aria-controls; the sub-list is hidden when closed
  • A badge is read after the label ("Inbox, 3") and drawn as a pill; in the folded sidebar it becomes a dot but is still read
  • The folded sidebar keeps every item's name for assistive technology and shows it in a tooltip on hover and focus; the Collapse button says what it will do (Collapse sidebar, Expand sidebar) and has aria-expanded
  • Width changes stop for visitors who prefer reduced motion
  • The account button is named with the person's name; the menu is a real menu
  • A workspace switcher is a menu button named with the current workspace; with only one workspace it is plain text

Block contract

Data
The navigation as plain data: groups of items, each with an id, label, optional href, icon, badge and sub-items.
Data states
None: it shows what it is given
Permissions
per navigation item
Events
onNavigate, onPick, onTeamChange, onSearch, onCollapsedChange
You can replace
appearance (bordered, subtle, floating); renderLink (your router's link); footer slot; --rd-sidebar-width and --rd-sidebar-rail

Guidelines

Use it when

  • An admin, billing, analytics or internal tool with several sections
  • You want only the navigation panel, inside your own layout

Avoid it when

  • You also want the top bar, the page frame and the phone menu: use DashboardShell, which is built on this
  • A marketing site or a one-page app: a top navigation bar is enough

Don't

  • Putting a second navigation landmark with the same name on the page: give each one its own label
  • Hiding the only way to a section behind the folded sidebar's tooltip: give every item an icon people can tell apart
  • More than about 7 top-level items in one group without headings
  • UI permission is not security: hiding or disabling an item only changes what people see, so the server must check access again for every request

Design tokens

The semantic tokens this component uses. Change them once and every component follows; see Design tokens.

  • --rd-color-surface-default
  • --rd-color-surface-subtle
  • --rd-color-surface-selected
  • --rd-color-surface-raised
  • --rd-color-border-default
  • --rd-color-text-default
  • --rd-color-text-muted
  • --rd-color-action-primary
  • --rd-color-focus-ring
  • --rd-radius-control
  • --rd-elevation-raised
  • --rd-size-control-sm