Drawer

A draggable, dismissible panel that slides in from any edge of the screen.

Default

tsx

import {
  Button,
  CloseButton,
  Drawer,
  DrawerTrigger,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerClose,
  DrawerBody,
  DrawerDescription,
} from "@hummingbirdui/react";

export default function DrawerDefault() {
  return (
    <Drawer>
      <DrawerTrigger asChild>
        <Button variant="outline">Open drawer</Button>
      </DrawerTrigger>
      <DrawerContent>
        <DrawerHeader>
          <DrawerTitle>Drawer title</DrawerTitle>
          <DrawerClose asChild>
            <CloseButton />
          </DrawerClose>
        </DrawerHeader>
        <DrawerBody>
          <DrawerDescription>
            Drag it down, click the backdrop, press Escape, or use the close
            button to dismiss it.
          </DrawerDescription>
        </DrawerBody>
      </DrawerContent>
    </Drawer>
  );
}

Direction

Passing direction ("top" | "right" | "bottom" | "left") to Drawer sets the edge the panel slides from.

tsx

import {
  Button,
  CloseButton,
  Drawer,
  DrawerTrigger,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerClose,
  DrawerBody,
  DrawerDescription,
} from "@hummingbirdui/react";

const directions = ["top", "right", "bottom", "left"] as const;

export default function DrawerDirection() {
  return (
    <div className="flex flex-wrap gap-2 justify-center">
      {directions.map((direction) => (
        <Drawer key={direction} direction={direction}>
          <DrawerTrigger asChild>
            <Button variant="outline" className="capitalize">
              {direction}
            </Button>
          </DrawerTrigger>
          <DrawerContent>
            <DrawerHeader>
              <DrawerTitle className="capitalize">
                {direction} drawer
              </DrawerTitle>
              <DrawerClose asChild>
                <CloseButton />
              </DrawerClose>
            </DrawerHeader>
            <DrawerBody>
              <DrawerDescription>
                Slides in from the {direction} edge.
              </DrawerDescription>
            </DrawerBody>
          </DrawerContent>
        </Drawer>
      ))}
    </div>
  );
}

Without overlay

Setting overlay={false} on DrawerContent renders the panel without the backdrop.

tsx

import {
  Button,
  CloseButton,
  Drawer,
  DrawerTrigger,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerClose,
  DrawerBody,
  DrawerDescription,
} from "@hummingbirdui/react";

export default function DrawerWithoutOverlay() {
  return (
    <Drawer direction="right">
      <DrawerTrigger asChild>
        <Button variant="outline">Open without overlay</Button>
      </DrawerTrigger>
      <DrawerContent overlay={false}>
        <DrawerHeader>
          <DrawerTitle>No backdrop</DrawerTitle>
          <DrawerClose asChild>
            <CloseButton />
          </DrawerClose>
        </DrawerHeader>
        <DrawerBody>
          <DrawerDescription>
            Setting <code>overlay=&#123;false&#125;</code> hides the backdrop so
            the page behind stays visible.
          </DrawerDescription>
        </DrawerBody>
      </DrawerContent>
    </Drawer>
  );
}

Scrollable body

DrawerBody grows to fill the panel and scrolls its own overflow while the header stays pinned.

tsx

import {
  Button,
  CloseButton,
  Drawer,
  DrawerTrigger,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerClose,
  DrawerBody,
} from "@hummingbirdui/react";

export default function DrawerScrollable() {
  return (
    <Drawer direction="right">
      <DrawerTrigger asChild>
        <Button variant="outline">Open long drawer</Button>
      </DrawerTrigger>
      <DrawerContent>
        <DrawerHeader>
          <DrawerTitle>Terms of service</DrawerTitle>
          <DrawerClose asChild>
            <CloseButton />
          </DrawerClose>
        </DrawerHeader>
        <DrawerBody>
          <p>Scroll to read all of the content below.</p>
          <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum
            nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi.
            Nulla quis sem at nibh elementum imperdiet.
          </p>
          <p>
            Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue
            semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla.
          </p>
          <p>
            Class aptent taciti sociosqu ad litora torquent per conubia nostra,
            per inceptos himenaeos. Curabitur sodales ligula in libero.
          </p>
          <p>
            Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh.
            Aenean quam. In scelerisque sem at dolor. Maecenas mattis.
          </p>
        </DrawerBody>
      </DrawerContent>
    </Drawer>
  );
}

API Reference

Drawer is built on Vaul. For detailed usage guidelines, see the Vaul documentation.

DrawerContent

PropTypeDefaultDescription
overlaybooleantrueRenders the backdrop behind the panel.
classNamestringAdditional classes merged with the generated classes.

Styling

Hummingbird React drawer is styled entirely through Hummingbird's utility classes and CSS variables.

  • See the full list of available drawer classes in the Class overview.
  • Visit the CSS Variables documentation to explore all available variables.