- Accordion
- Alert
- Alert Dialog
- Autocomplete
- Avatar
- Badge
- Breadcrumb
- Button
- Calendar
- Card
- Checkbox
- Checkbox Group
- Collapsible
- Combobox
- Command
- Date Picker
- Dialog
- DrawerNew
- Empty
- Field
- Fieldset
- Form
- Frame
- Group
- Input
- Input Group
- Kbd
- Label
- Menu
- Meter
- Number Field
- Pagination
- Popover
- Preview Card
- Progress
- Radio Group
- Scroll Area
- Select
- Separator
- Sheet
- Skeleton
- Slider
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Toggle Group
- Toolbar
- Tooltip
Drawer
A panel that slides in from the edge of the screen with swipe gestures, snap points, and nested drawer support.
import { Button } from "@/components/ui/button";
import {
Drawer,
DrawerClose,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerPopup,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
export default function Particle() {
return (
<Drawer>
<DrawerTrigger render={<Button variant="outline" />}>
Open drawer
</DrawerTrigger>
<DrawerPopup showBar>
<DrawerHeader className="text-center">
<DrawerTitle>Notifications</DrawerTitle>
<DrawerDescription>
This is the description of the drawer.
</DrawerDescription>
</DrawerHeader>
<DrawerFooter
className="justify-center sm:justify-center"
variant="bare"
>
<DrawerClose render={<Button variant="outline" />}>Close</DrawerClose>
</DrawerFooter>
</DrawerPopup>
</Drawer>
);
}
Installation
pnpm dlx shadcn@latest add @coss/drawer
Usage
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerMenu,
DrawerMenuCheckboxItem,
DrawerMenuGroup,
DrawerMenuGroupLabel,
DrawerMenuItem,
DrawerMenuRadioGroup,
DrawerMenuRadioItem,
DrawerMenuSeparator,
DrawerPanel,
DrawerPopup,
DrawerMenuTrigger,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer"<Drawer>
<DrawerTrigger>Open</DrawerTrigger>
<DrawerPopup>
<DrawerHeader>
<DrawerTitle>Drawer Title</DrawerTitle>
<DrawerDescription>Drawer Description</DrawerDescription>
</DrawerHeader>
<DrawerPanel>Content</DrawerPanel>
<DrawerFooter>
<DrawerClose>Close</DrawerClose>
</DrawerFooter>
</DrawerPopup>
</Drawer>API Reference
Drawer
Root component. Wraps Drawer.Root from Base UI with automatic swipeDirection mapping based on position.
| Prop | Type | Default | Description |
|---|---|---|---|
position | "right" | "left" | "top" | "bottom" | "bottom" | Controls which edge the drawer opens from. Sets the swipe direction automatically and flows to child components via context |
swipeDirection | "up" | "down" | "left" | "right" | derived | Overrides the swipe direction derived from position. Use when you need different swipe behavior |
All other props from Drawer.Root are supported, including open, onOpenChange, modal, snapPoints, snapPoint, onSnapPointChange, and snapToSequentialPoints. Note: Snap points only work for bottom drawers.
DrawerTrigger
Trigger button that opens the drawer. Alias for Drawer.Trigger from Base UI.
DrawerPopup
Popup container that displays the drawer content.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "straight" | "inset" | "default" | Controls the drawer style. straight removes rounded corners, inset adds spacing around the drawer on desktop screens |
showCloseButton | boolean | false | When true, displays a close button in the top-right corner |
showBar | boolean | false | When true, displays a drag bar indicator |
Example:
// Bottom drawer (default)
<Drawer>
<DrawerPopup>...</DrawerPopup>
</Drawer>
// Right side drawer
<Drawer position="right">
<DrawerPopup>...</DrawerPopup>
</Drawer>
// Left side drawer
<Drawer position="left">
<DrawerPopup>...</DrawerPopup>
</Drawer>
// Drawer with inset variant
<Drawer position="right">
<DrawerPopup variant="inset">...</DrawerPopup>
</Drawer>DrawerHeader
Container for the drawer title and description. Supports the render prop for polymorphic composition (e.g. render={<header />}).
| Prop | Type | Default | Description |
|---|---|---|---|
allowSelection | boolean | false | When true, wraps the header in DrawerContent to reduce swipe interference during mouse text selection |
DrawerFooter
Footer section for action buttons. Supports the render prop for polymorphic composition.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "bare" | "default" | Controls the footer styling. default includes border and background, bare removes them |
allowSelection | boolean | true | When true, wraps the footer in DrawerContent to reduce swipe interference during mouse text selection |
DrawerTitle
Title component. Alias for Drawer.Title from Base UI.
DrawerDescription
Description component. Alias for Drawer.Description from Base UI.
DrawerPanel
Content container. When scrollable is true (default), wraps content in a ScrollArea component. Supports the render prop for polymorphic composition.
| Prop | Type | Default | Description |
|---|---|---|---|
scrollable | boolean | true | When true, wraps content in a ScrollArea. Set to false for non-scrollable content |
scrollFade | boolean | true | When true, shows a fade effect at scroll edges (only applies when scrollable is true) |
allowSelection | boolean | true | When true, wraps the panel in DrawerContent to reduce swipe interference during mouse text selection |
DrawerMenu
Container for drawer menu items. Use with DrawerMenuItem, DrawerMenuSeparator, DrawerMenuGroup, DrawerMenuGroupLabel, DrawerMenuCheckboxItem, DrawerMenuRadioGroup, DrawerMenuRadioItem, and DrawerMenuTrigger to build menus that mirror the Menu component API. Supports the render prop for polymorphic composition.
DrawerMenuItem
Styled menu item that matches MenuItem appearance. Does not close the drawer — wrap with DrawerClose when close-on-click is needed. Supports the render prop for polymorphic composition.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "destructive" | "default" | When destructive, uses destructive text color |
disabled | boolean | — | When true, disables the item |
Example: Use with DrawerClose for close-on-click: <DrawerClose render={<DrawerMenuItem />}>Edit</DrawerClose>
DrawerMenuSeparator
Horizontal separator between menu items or groups. Supports the render prop for polymorphic composition.
DrawerMenuGroup
Container for grouping related menu items. Use with DrawerMenuGroupLabel for labeled sections. Supports the render prop for polymorphic composition.
DrawerMenuGroupLabel
Label for a DrawerMenuGroup section. Renders muted, smaller text above a group of items. In nested drawers, use as a section title at the top of the menu (no back button needed — swipe to go back). Supports the render prop for polymorphic composition.
DrawerMenuTrigger
Trigger that opens a nested drawer. Styled like a menu item with a trailing chevron. Use for menu items that open nested drawers (e.g. "Add to Playlist" → nested drawer with playlist options). Wraps DrawerTrigger internally.
Example: <DrawerMenuTrigger>Add to Playlist</DrawerMenuTrigger> opens a nested drawer when tapped.
DrawerMenuCheckboxItem
Checkbox menu item for independent toggles. Supports variant="switch" for toggle-style switches. For selection groups, use DrawerMenuRadioGroup with DrawerMenuRadioItem.
DrawerMenuRadioGroup
Container for radio menu items. Use with DrawerMenuRadioItem for mutually exclusive options (e.g. "Sort by" with Artist, Album, Title).
DrawerMenuRadioItem
Radio menu item. Must be used inside DrawerMenuRadioGroup with a value prop.
DrawerClose
Close button component. Alias for Drawer.Close from Base UI.
DrawerPortal
Portal component for rendering outside the DOM hierarchy. Alias for Drawer.Portal from Base UI.
DrawerBackdrop
Backdrop/overlay component. Alias for Drawer.Backdrop from Base UI.
DrawerViewport
Viewport component for positioning. Alias for Drawer.Viewport from Base UI. Typically not used directly — DrawerPopup renders it internally.
DrawerBar
Drag handle indicator shown when showBar is true on DrawerPopup. Typically not used directly.
DrawerContent
Primitive content wrapper used for polymorphic composition with the render prop. Alias for Drawer.Content from Base UI.
Examples
Inset variant
import { Button } from "@/components/ui/button";
import {
Drawer,
DrawerHeader,
DrawerPanel,
DrawerPopup,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
export default function Particle() {
return (
<div className="flex flex-wrap gap-2">
<Drawer position="right">
<DrawerTrigger render={<Button variant="outline" />}>
Right
</DrawerTrigger>
<DrawerPopup variant="inset">
<DrawerHeader>
<DrawerTitle>Right</DrawerTitle>
</DrawerHeader>
<DrawerPanel>
<p className="text-muted-foreground text-sm">
Content from the right.
</p>
</DrawerPanel>
</DrawerPopup>
</Drawer>
<Drawer position="left">
<DrawerTrigger render={<Button variant="outline" />}>
Left
</DrawerTrigger>
<DrawerPopup variant="inset">
<DrawerHeader>
<DrawerTitle>Left</DrawerTitle>
</DrawerHeader>
<DrawerPanel>
<p className="text-muted-foreground text-sm">
Content from the left.
</p>
</DrawerPanel>
</DrawerPopup>
</Drawer>
<Drawer position="top">
<DrawerTrigger render={<Button variant="outline" />}>Top</DrawerTrigger>
<DrawerPopup variant="inset">
<DrawerHeader>
<DrawerTitle>Top</DrawerTitle>
</DrawerHeader>
<DrawerPanel>
<p className="text-muted-foreground text-sm">
Content from the top.
</p>
</DrawerPanel>
</DrawerPopup>
</Drawer>
<Drawer>
<DrawerTrigger render={<Button variant="outline" />}>
Bottom
</DrawerTrigger>
<DrawerPopup variant="inset">
<DrawerHeader>
<DrawerTitle>Bottom</DrawerTitle>
</DrawerHeader>
<DrawerPanel>
<p className="text-muted-foreground text-sm">
Content from the bottom.
</p>
</DrawerPanel>
</DrawerPopup>
</Drawer>
</div>
);
}
Straight variant
import { Button } from "@/components/ui/button";
import {
Drawer,
DrawerHeader,
DrawerPanel,
DrawerPopup,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
export default function Particle() {
return (
<div className="flex flex-wrap gap-2">
<Drawer position="right">
<DrawerTrigger render={<Button variant="outline" />}>
Right
</DrawerTrigger>
<DrawerPopup variant="straight">
<DrawerHeader>
<DrawerTitle>Right</DrawerTitle>
</DrawerHeader>
<DrawerPanel>
<p className="text-muted-foreground text-sm">
Content from the right.
</p>
</DrawerPanel>
</DrawerPopup>
</Drawer>
<Drawer position="left">
<DrawerTrigger render={<Button variant="outline" />}>
Left
</DrawerTrigger>
<DrawerPopup variant="straight">
<DrawerHeader>
<DrawerTitle>Left</DrawerTitle>
</DrawerHeader>
<DrawerPanel>
<p className="text-muted-foreground text-sm">
Content from the left.
</p>
</DrawerPanel>
</DrawerPopup>
</Drawer>
<Drawer position="top">
<DrawerTrigger render={<Button variant="outline" />}>Top</DrawerTrigger>
<DrawerPopup variant="straight">
<DrawerHeader>
<DrawerTitle>Top</DrawerTitle>
</DrawerHeader>
<DrawerPanel>
<p className="text-muted-foreground text-sm">
Content from the top.
</p>
</DrawerPanel>
</DrawerPopup>
</Drawer>
<Drawer>
<DrawerTrigger render={<Button variant="outline" />}>
Bottom
</DrawerTrigger>
<DrawerPopup variant="straight">
<DrawerHeader>
<DrawerTitle>Bottom</DrawerTitle>
</DrawerHeader>
<DrawerPanel>
<p className="text-muted-foreground text-sm">
Content from the bottom.
</p>
</DrawerPanel>
</DrawerPopup>
</Drawer>
</div>
);
}
Scrollable content
import { Button } from "@/components/ui/button";
import {
Drawer,
DrawerClose,
DrawerFooter,
DrawerHeader,
DrawerPanel,
DrawerPopup,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
export default function Particle() {
return (
<Drawer>
<DrawerTrigger render={<Button variant="outline" />}>
Scrollable content
</DrawerTrigger>
<DrawerPopup showBar>
<DrawerHeader>
<DrawerTitle>Scrollable content</DrawerTitle>
</DrawerHeader>
<DrawerPanel>
<div className="flex flex-col gap-2">
{Array.from({ length: 48 }, (_, i) => `box-${i}`).map((key) => (
<div
className="h-12 shrink-0 rounded-xl border bg-muted"
key={key}
/>
))}
</div>
</DrawerPanel>
<DrawerFooter>
<DrawerClose render={<Button variant="outline" />}>Close</DrawerClose>
</DrawerFooter>
</DrawerPopup>
</Drawer>
);
}
Nested drawers
import { Button } from "@/components/ui/button";
import {
Drawer,
DrawerClose,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerPanel,
DrawerPopup,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
export default function Particle() {
return (
<Drawer>
<DrawerTrigger render={<Button variant="outline" />}>
Nested drawers
</DrawerTrigger>
<DrawerPopup showBar>
<DrawerHeader className="text-center">
<DrawerTitle>First step</DrawerTitle>
<DrawerDescription>
This is the first step. Tap the button below to continue to the next
screen.
</DrawerDescription>
</DrawerHeader>
<DrawerFooter
className="justify-center sm:justify-center"
variant="bare"
>
<DrawerClose render={<Button variant="ghost" />}>Cancel</DrawerClose>
<Drawer>
<DrawerTrigger render={<Button variant="outline" />}>
Continue
</DrawerTrigger>
<DrawerPopup showBar>
<DrawerHeader className="text-center">
<DrawerTitle>Second step</DrawerTitle>
<DrawerDescription>
You've reached the second step. Tap the button below to
continue to the next screen.
</DrawerDescription>
</DrawerHeader>
<DrawerPanel>
<div className="flex justify-center">
<div className="size-48 shrink-0 rounded-xl border bg-muted" />
</div>
</DrawerPanel>
<DrawerFooter
className="justify-center sm:justify-center"
variant="bare"
>
<DrawerClose render={<Button variant="ghost" />}>
Back
</DrawerClose>
<Drawer>
<DrawerTrigger render={<Button variant="outline" />}>
Continue
</DrawerTrigger>
<DrawerPopup showBar>
<DrawerHeader className="text-center">
<DrawerTitle>Third step</DrawerTitle>
<DrawerDescription>
You've reached the final step. You can close this
drawer or go back.
</DrawerDescription>
</DrawerHeader>
<DrawerPanel>
<div className="flex justify-center">
<div className="size-32 shrink-0 rounded-full border bg-muted" />
</div>
</DrawerPanel>
</DrawerPopup>
</Drawer>
</DrawerFooter>
</DrawerPopup>
</Drawer>
</DrawerFooter>
</DrawerPopup>
</Drawer>
);
}
Snap points
"use client";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import {
Drawer,
DrawerDescription,
DrawerHeader,
DrawerPanel,
DrawerPopup,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
export default function Particle() {
const snapPoints = ["300px", 1] as const;
const [snapPoint, setSnapPoint] = useState<
(typeof snapPoints)[number] | null
>(snapPoints[0]);
return (
<Drawer
onSnapPointChange={(point) =>
setSnapPoint(point as (typeof snapPoints)[number] | null)
}
position="bottom"
snapPoint={snapPoint}
snapPoints={[...snapPoints]}
snapToSequentialPoints
>
<DrawerTrigger render={<Button variant="outline" />}>
With snap points
</DrawerTrigger>
<DrawerPopup showBar>
<DrawerHeader>
<DrawerTitle>Snap Points</DrawerTitle>
<DrawerDescription>
Drag the drawer to snap between a compact peek and full-height view.
</DrawerDescription>
</DrawerHeader>
<DrawerPanel>
<div className="flex flex-col gap-2">
{Array.from({ length: 48 }, (_, i) => `box-${i}`).map((key) => (
<div
className="h-12 shrink-0 rounded-xl border bg-muted"
key={key}
/>
))}
</div>
</DrawerPanel>
</DrawerPopup>
</Drawer>
);
}
Mobile menu
import Link from "next/link";
import { Button } from "@/components/ui/button";
import {
Drawer,
DrawerClose,
DrawerHeader,
DrawerPanel,
DrawerPopup,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
export default function Particle() {
return (
<Drawer position="left">
<DrawerTrigger render={<Button variant="outline" />}>
Open menu
</DrawerTrigger>
<DrawerPopup showCloseButton variant="straight">
<DrawerHeader>
<DrawerTitle>Menu</DrawerTitle>
</DrawerHeader>
<DrawerPanel>
<nav className="-mx-[calc(--spacing(3)-1px)] flex flex-col gap-0.5">
<DrawerClose
nativeButton={false}
render={
<Button
className="justify-start"
render={<Link href="#" />}
variant="ghost"
/>
}
>
Home
</DrawerClose>
<DrawerClose
nativeButton={false}
render={
<Button
className="justify-start"
render={<Link href="#" />}
variant="ghost"
/>
}
>
Profile
</DrawerClose>
<DrawerClose
nativeButton={false}
render={
<Button
className="justify-start"
render={<Link href="#" />}
variant="ghost"
/>
}
>
Settings
</DrawerClose>
<DrawerClose
nativeButton={false}
render={
<Button
className="justify-start"
render={<Link href="#" />}
variant="ghost"
/>
}
>
Sign out
</DrawerClose>
</nav>
</DrawerPanel>
</DrawerPopup>
</Drawer>
);
}
Responsive dialog
Use Drawer on small screens and Dialog on larger ones to show the same content in a modal on desktop and a bottom sheet on mobile.
"use client";
import { useMediaQuery } from "@/hooks/use-media-query";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogClose,
DialogDescription,
DialogFooter,
DialogHeader,
DialogPanel,
DialogPopup,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import {
Drawer,
DrawerClose,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerPanel,
DrawerPopup,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
import { Field, FieldLabel } from "@/components/ui/field";
import { Form } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
const FORM_TITLE = "Edit profile";
const FORM_DESCRIPTION =
"Make changes to your profile here. Click save when you're done.";
const TRIGGER_LABEL = "Open";
const CANCEL_LABEL = "Cancel";
const SAVE_LABEL = "Save";
const formFields = (
<>
<Field>
<FieldLabel>Name</FieldLabel>
<Input defaultValue="Margaret Welsh" type="text" />
</Field>
<Field>
<FieldLabel>Username</FieldLabel>
<Input defaultValue="@maggie.welsh" type="text" />
</Field>
</>
);
export default function Particle() {
const isMobile = useMediaQuery("max-md");
if (isMobile) {
return (
<Drawer>
<DrawerTrigger render={<Button variant="outline" />}>
{TRIGGER_LABEL}
</DrawerTrigger>
<DrawerPopup showBar>
<Form className="contents">
<DrawerHeader>
<DrawerTitle>{FORM_TITLE}</DrawerTitle>
<DrawerDescription>{FORM_DESCRIPTION}</DrawerDescription>
</DrawerHeader>
<DrawerPanel className="grid gap-4" scrollable={false}>
{formFields}
</DrawerPanel>
<DrawerFooter>
<DrawerClose render={<Button variant="ghost" />}>
{CANCEL_LABEL}
</DrawerClose>
<Button type="submit">{SAVE_LABEL}</Button>
</DrawerFooter>
</Form>
</DrawerPopup>
</Drawer>
);
}
return (
<Dialog>
<DialogTrigger render={<Button variant="outline" />}>
{TRIGGER_LABEL}
</DialogTrigger>
<DialogPopup className="sm:max-w-sm">
<Form className="contents">
<DialogHeader>
<DialogTitle>{FORM_TITLE}</DialogTitle>
<DialogDescription>{FORM_DESCRIPTION}</DialogDescription>
</DialogHeader>
<DialogPanel className="grid gap-4">{formFields}</DialogPanel>
<DialogFooter>
<DialogClose render={<Button variant="ghost" />}>
{CANCEL_LABEL}
</DialogClose>
<Button type="submit">{SAVE_LABEL}</Button>
</DialogFooter>
</Form>
</DialogPopup>
</Dialog>
);
}
Responsive menu
Pair Drawer with Menu so actions appear in a dropdown on desktop and a swipe-up sheet on mobile. Use DrawerMenuTrigger for items that open nested drawers on mobile. Nested drawers use DrawerMenuGroupLabel as section titles; swipe to go back.
"use client";
import {
CopyIcon,
EllipsisIcon,
PencilIcon,
ShareIcon,
TrashIcon,
} from "lucide-react";
import { useMediaQuery } from "@/hooks/use-media-query";
import { Button } from "@/components/ui/button";
import {
Drawer,
DrawerClose,
DrawerMenu,
DrawerMenuCheckboxItem,
DrawerMenuGroup,
DrawerMenuGroupLabel,
DrawerMenuItem,
DrawerMenuRadioGroup,
DrawerMenuRadioItem,
DrawerMenuSeparator,
DrawerMenuTrigger,
DrawerPanel,
DrawerPopup,
DrawerTrigger,
} from "@/components/ui/drawer";
import {
Menu,
MenuCheckboxItem,
MenuGroup,
MenuGroupLabel,
MenuItem,
MenuPopup,
MenuRadioGroup,
MenuRadioItem,
MenuSeparator,
MenuSub,
MenuSubPopup,
MenuSubTrigger,
MenuTrigger,
} from "@/components/ui/menu";
const TRIGGER_ARIA_LABEL = "Open menu";
export default function Particle() {
const isMobile = useMediaQuery("max-md");
if (isMobile) {
return (
<Drawer>
<DrawerTrigger
render={
<Button
aria-label={TRIGGER_ARIA_LABEL}
size="icon"
variant="outline"
/>
}
>
<EllipsisIcon aria-hidden />
</DrawerTrigger>
<DrawerPopup showBar>
<DrawerPanel>
<DrawerMenu>
<DrawerMenuGroup>
<DrawerMenuGroupLabel>Actions</DrawerMenuGroupLabel>
<DrawerClose render={<DrawerMenuItem />}>
<PencilIcon aria-hidden />
Edit
</DrawerClose>
<DrawerClose render={<DrawerMenuItem />}>
<CopyIcon aria-hidden />
Duplicate
</DrawerClose>
<DrawerClose render={<DrawerMenuItem />}>
<ShareIcon aria-hidden />
Share
</DrawerClose>
</DrawerMenuGroup>
<DrawerMenuSeparator />
<DrawerMenuCheckboxItem>Shuffle</DrawerMenuCheckboxItem>
<DrawerMenuCheckboxItem>Repeat</DrawerMenuCheckboxItem>
<DrawerMenuCheckboxItem disabled>
Enhanced Audio
</DrawerMenuCheckboxItem>
<DrawerMenuSeparator />
<DrawerMenuGroup>
<DrawerMenuGroupLabel>Sort by</DrawerMenuGroupLabel>
<DrawerMenuRadioGroup defaultValue="artist">
<DrawerMenuRadioItem value="artist">
Artist
</DrawerMenuRadioItem>
<DrawerMenuRadioItem value="album">Album</DrawerMenuRadioItem>
<DrawerMenuRadioItem value="title">Title</DrawerMenuRadioItem>
</DrawerMenuRadioGroup>
</DrawerMenuGroup>
<DrawerMenuSeparator />
<DrawerMenuCheckboxItem variant="switch">
Auto save
</DrawerMenuCheckboxItem>
<DrawerMenuSeparator />
<Drawer>
<DrawerMenuTrigger>Add to Playlist</DrawerMenuTrigger>
<DrawerPopup showBar>
<DrawerPanel>
<DrawerMenu>
<DrawerMenuGroup>
<DrawerMenuGroupLabel>
Add to Playlist
</DrawerMenuGroupLabel>
</DrawerMenuGroup>
<DrawerClose render={<DrawerMenuItem />}>
Jazz
</DrawerClose>
<Drawer>
<DrawerMenuTrigger>Rock</DrawerMenuTrigger>
<DrawerPopup showBar>
<DrawerPanel>
<DrawerMenu>
<DrawerMenuGroup>
<DrawerMenuGroupLabel>
Rock
</DrawerMenuGroupLabel>
</DrawerMenuGroup>
<DrawerClose render={<DrawerMenuItem />}>
Hard Rock
</DrawerClose>
<DrawerClose render={<DrawerMenuItem />}>
Soft Rock
</DrawerClose>
<DrawerClose render={<DrawerMenuItem />}>
Classic Rock
</DrawerClose>
<DrawerMenuSeparator />
<DrawerClose render={<DrawerMenuItem />}>
Metal
</DrawerClose>
<DrawerClose render={<DrawerMenuItem />}>
Punk
</DrawerClose>
<DrawerClose render={<DrawerMenuItem />}>
Grunge
</DrawerClose>
<DrawerClose render={<DrawerMenuItem />}>
Alternative
</DrawerClose>
<DrawerClose render={<DrawerMenuItem />}>
Indie
</DrawerClose>
<DrawerClose render={<DrawerMenuItem />}>
Electronic
</DrawerClose>
</DrawerMenu>
</DrawerPanel>
</DrawerPopup>
</Drawer>
<DrawerClose render={<DrawerMenuItem />}>Pop</DrawerClose>
</DrawerMenu>
</DrawerPanel>
</DrawerPopup>
</Drawer>
<DrawerMenuSeparator />
<DrawerMenuGroup>
<DrawerMenuGroupLabel>Danger zone</DrawerMenuGroupLabel>
<DrawerClose render={<DrawerMenuItem variant="destructive" />}>
<TrashIcon aria-hidden />
Delete
</DrawerClose>
</DrawerMenuGroup>
</DrawerMenu>
</DrawerPanel>
</DrawerPopup>
</Drawer>
);
}
return (
<Menu>
<MenuTrigger
render={
<Button
aria-label={TRIGGER_ARIA_LABEL}
size="icon"
variant="outline"
/>
}
>
<EllipsisIcon aria-hidden />
</MenuTrigger>
<MenuPopup>
<MenuGroup>
<MenuGroupLabel>Actions</MenuGroupLabel>
<MenuItem>
<PencilIcon aria-hidden />
Edit
</MenuItem>
<MenuItem>
<CopyIcon aria-hidden />
Duplicate
</MenuItem>
<MenuItem>
<ShareIcon aria-hidden />
Share
</MenuItem>
</MenuGroup>
<MenuSeparator />
<MenuCheckboxItem>Shuffle</MenuCheckboxItem>
<MenuCheckboxItem>Repeat</MenuCheckboxItem>
<MenuCheckboxItem disabled>Enhanced Audio</MenuCheckboxItem>
<MenuSeparator />
<MenuGroup>
<MenuGroupLabel>Sort by</MenuGroupLabel>
<MenuRadioGroup defaultValue="artist">
<MenuRadioItem value="artist">Artist</MenuRadioItem>
<MenuRadioItem value="album">Album</MenuRadioItem>
<MenuRadioItem value="title">Title</MenuRadioItem>
</MenuRadioGroup>
</MenuGroup>
<MenuSeparator />
<MenuCheckboxItem variant="switch">Auto save</MenuCheckboxItem>
<MenuSeparator />
<MenuSub>
<MenuSubTrigger>Add to Playlist</MenuSubTrigger>
<MenuSubPopup>
<MenuItem>Jazz</MenuItem>
<MenuSub>
<MenuSubTrigger>Rock</MenuSubTrigger>
<MenuSubPopup>
<MenuItem>Hard Rock</MenuItem>
<MenuItem>Soft Rock</MenuItem>
<MenuItem>Classic Rock</MenuItem>
<MenuSeparator />
<MenuItem>Metal</MenuItem>
<MenuItem>Punk</MenuItem>
<MenuItem>Grunge</MenuItem>
<MenuItem>Alternative</MenuItem>
<MenuItem>Indie</MenuItem>
<MenuItem>Electronic</MenuItem>
</MenuSubPopup>
</MenuSub>
<MenuItem>Pop</MenuItem>
</MenuSubPopup>
</MenuSub>
<MenuSeparator />
<MenuGroup>
<MenuGroupLabel>Danger zone</MenuGroupLabel>
<MenuItem variant="destructive">
<TrashIcon aria-hidden />
Delete
</MenuItem>
</MenuGroup>
</MenuPopup>
</Menu>
);
}
On This Page