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
| Prop | Type | Description |
|---|---|---|
| links | DrawerLink[] | The links in the panel, top to bottom. A link is { label, href }. |
| active | string | The href of the current page or section: its dot shows while nothing is hovered or focused. |
| heading | ReactNodedefault "Navigation" | The small heading over the links. |
| footer | ReactNode | Pinned to the bottom of the panel: social links, an email, small print. |
| contained | booleandefault false | Fill the nearest relative parent instead of the screen. |
| defaultOpen | booleandefault false | Start open. |
| open | boolean | Controlled state, with onOpenChange. |
| className | string | Classes for the round button's position (top-right by default). |
Installation
npx shadcn@latest add https://purrfectui.com/r/drawer-menu.jsonHow 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.