Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Left Drawer with Nested Items for React

A left Menu drawer where Products and Orders expand, and Dashboard and Analytics stay single rows.

A left panel titled Menu. Dashboard and Analytics are single rows. Products opens to All Products, Categories, and Inventory, and Orders opens to its own items.

Use it for a short two-level menu on a phone. On a desktop, keep that menu in a Sidebar. In React, Base UI opens each section on its own.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

Anatomy

Drawer anatomy: grabber, title, description, content, close

Usage

<Drawer swipeDirection="left">
  <DrawerTrigger
    render={
      <Button aria-label="Open menu" size="icon-md" variant="outline" />
    }
  >
    <MenuIcon aria-hidden="true" />
  </DrawerTrigger>
  <DrawerContent>
    <div className="flex flex-col gap-4 p-4">
      <DrawerTitle className="font-semibold text-lg">Menu</DrawerTitle>
      <nav aria-label="Main" className="flex flex-col gap-1">
        <Button className="justify-start" variant="ghost">
          Dashboard
        </Button>
        {SECTIONS.map((section) => (
          <Collapsible key={section.label}>
            <CollapsibleTrigger
              render={
                <Button
                  className="group w-full justify-between"
                  variant="ghost"
                />
              }
            >
              {section.label}
              <ChevronRightIcon
                aria-hidden="true"
                className="transition-transform group-aria-expanded:rotate-90"
                data-icon="inline-end"
              />
{/* The rest of the file is under Installation. */}

FAQ

How do Products and Orders expand?

Each is a Collapsible. Its CollapsibleTrigger is a ghost button with the label and a chevron, and its CollapsibleContent holds the sub-items, indented with ms-4.

How does the chevron turn?

The trigger has aria-expanded while its section is open, and the chevron's group-aria-expanded:rotate-90 turns it to point down.

Which items are inside?

Products holds All Products, Categories and Inventory; Orders holds All Orders, Pending and Completed. Both start closed.

Can only one section be open at a time?

Not with separate Collapsibles. Use an Accordion instead if opening one section should close the other.

How is the menu button labeled?

An outline icon button opens the drawer. Its aria-label, Open menu, is the accessible name; the icon is aria-hidden. The Button goes in the render prop of DrawerTrigger.

How does the drawer open from the left?

swipeDirection="left" on Drawer puts it on the left edge. The prop names the swipe that closes the drawer, so left docks it on the left; leave it out for a bottom drawer.

API Reference

Drawer

Sets swipeDirection="left". The rest is on the Drawer page.

Button

Sets aria-label="Open menu", size="icon-md", variant="outline", variant="ghost" and size="sm". The rest is on the Button page.

Collapsible

No extra props in this demo. The rest is on the Collapsible page.