Drawer menu

A round burger that crosses into an X and slides a full-height link panel in from the right.

Behaviour

  • The button's two lines cross into an X; a full-height panel slides in from the right and the links follow it in one after another.
  • A dot grows beside the first line of the hovered or keyboard-focused link, and rests on the `active` one otherwise. Two links may share an href; only the hovered one lights. Touch never leaves it stuck.
  • Long labels hyphenate when they wrap; a long list scrolls inside the panel without scrolling the page behind it.
  • Escape, a click outside, or picking a link closes it. Focus moves into the panel and returns to the button; Tab stays inside while it is open.
  • The panel inverts the theme (foreground background, background text), so it reads in light and dark.
  • Reduced motion: the panel and links fade, nothing slides.

Props

PropTypeDescription
linksDrawerLink[]The links in the panel, top to bottom. A link is { label, href }.
activestringThe href of the current page or section: its dot shows while nothing is hovered or focused.
headingReactNodedefault "Navigation"The small heading over the links.
footerReactNodePinned to the bottom of the panel: social links, an email, small print.
containedbooleandefault falseFill the nearest relative parent instead of the screen.
defaultOpenbooleandefault falseStart open.
openbooleanControlled state, with onOpenChange.
classNamestringClasses for the round button's position (top-right by default).

Installation

npx shadcn@latest add https://purrfectui.com/r/drawer-menu.json

How to use

import { DrawerMenu } from "@/components/ui/drawer-menu";

<DrawerMenu
  active="#work"
  links={[
    { label: "Work", href: "#work" },
    { label: "About", href: "#about" },
    { label: "Contact", href: "#contact" },
  ]}
  footer={<a href="https://github.com/you">GitHub</a>}
/>

Source code

Loading…

License

MIT. Copy it into your project and change it as you like.

0