Rendered from the shared Frontfriend stories with React Base, the same
preview Studio shows. Styling comes from your Design System; the code below
is native to Radix UI.
Installation
Complete project setup first. Your configuration
must select react/radix and include your Design System ID.
pnpm exec frontfriend download drawer -f react --primitive radix
Review dependencies reported by the downloader and keep your source
changes in version control.
Usage
import {
Drawer,
DrawerTrigger,
DrawerContent,
DrawerHeader,
DrawerTitle,
DrawerDescription,
DrawerBody,
DrawerFooter,
DrawerClose,
} from "@/components/ui/drawer";
import { Button } from "@/components/ui/button";
const paragraph =
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth.";
<Drawer side="bottom" lgSide="right">
<DrawerTrigger asChild>
<Button variant="tertiary">Open Drawer</Button>
</DrawerTrigger>
<DrawerContent
height="auto"
width="md"
>
<DrawerHeader closeIcon>
<DrawerTitle>Move Goal</DrawerTitle>
<DrawerDescription>Set your daily activity goal.</DrawerDescription>
</DrawerHeader>
<DrawerBody>
<p>{paragraph}</p>
</DrawerBody>
<DrawerFooter>
<DrawerClose asChild>
<Button variant="tertiary">Cancel</Button>
</DrawerClose>
<Button>Submit</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>;
Examples
Default
import {
Drawer,
DrawerTrigger,
DrawerContent,
DrawerHeader,
DrawerTitle,
DrawerDescription,
DrawerBody,
DrawerFooter,
DrawerClose,
} from "@/components/ui/drawer";
import { Button } from "@/components/ui/button";
const paragraph =
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth.";
<Drawer side="bottom" lgSide="right">
<DrawerTrigger asChild>
<Button variant="tertiary">Open Drawer</Button>
</DrawerTrigger>
<DrawerContent
>
<DrawerHeader closeIcon>
<DrawerTitle>Move Goal</DrawerTitle>
<DrawerDescription>Set your daily activity goal.</DrawerDescription>
</DrawerHeader>
<DrawerBody>
<p>{paragraph}</p>
</DrawerBody>
<DrawerFooter>
<DrawerClose asChild>
<Button variant="tertiary">Cancel</Button>
</DrawerClose>
<Button>Submit</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>;
Sides
import {
Drawer,
DrawerTrigger,
DrawerContent,
DrawerHeader,
DrawerTitle,
DrawerDescription,
DrawerBody,
} from "@/components/ui/drawer";
import { Button } from "@/components/ui/button";
const paragraph =
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth.";
<div className="flex flex-wrap items-center justify-center gap-3">
{(["bottom", "left", "right", "top"] as const).map((side) => (
<Drawer key={side} side={side} lgSide={side}>
<DrawerTrigger asChild>
<Button variant="tertiary" className="capitalize">
{side}
</Button>
</DrawerTrigger>
<DrawerContent>
<DrawerHeader closeIcon>
<DrawerTitle className="capitalize">{side}</DrawerTitle>
<DrawerDescription>
This drawer opens from the {side}.
</DrawerDescription>
</DrawerHeader>
<DrawerBody>
<p>{paragraph}</p>
</DrawerBody>
</DrawerContent>
</Drawer>
))}
</div>;
import {
Drawer,
DrawerTrigger,
DrawerContent,
DrawerHeader,
DrawerTitle,
DrawerDescription,
DrawerBody,
DrawerFooter,
} from "@/components/ui/drawer";
import { Button } from "@/components/ui/button";
const paragraph =
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth.";
<Drawer side="bottom" lgSide="right">
<DrawerTrigger asChild>
<Button variant="tertiary">Open Scrollable</Button>
</DrawerTrigger>
<DrawerContent height="full" width="md">
<DrawerHeader closeIcon>
<DrawerTitle>Ullamco dolor laboris reprehenderit.</DrawerTitle>
<DrawerDescription>
Scroll through the full content below.
</DrawerDescription>
</DrawerHeader>
<DrawerBody>
{Array.from({ length: 8 }, (_, index) => (
<p key={index}>{paragraph}</p>
))}
</DrawerBody>
<DrawerFooter>
<Button variant="tertiary">Cancel</Button>
<Button>Save</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>;
import {
Drawer,
DrawerTrigger,
DrawerContent,
DrawerHeader,
DrawerTitle,
DrawerDescription,
DrawerBody,
DrawerFooter,
} from "@/components/ui/drawer";
import { Button } from "@/components/ui/button";
const paragraph =
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth.";
<div className="flex flex-wrap items-center justify-center gap-3">
{(["end", "justify", "start", "stretch"] as const).map((align) => (
<Drawer key={align} side="bottom" lgSide="right">
<DrawerTrigger asChild>
<Button variant="tertiary" className="capitalize">
{align}
</Button>
</DrawerTrigger>
<DrawerContent>
<DrawerHeader closeIcon>
<DrawerTitle className="capitalize">align={align}</DrawerTitle>
<DrawerDescription>
The body below is rendered with `noPadding`.
</DrawerDescription>
</DrawerHeader>
<DrawerBody noPadding>
<p>{paragraph}</p>
</DrawerBody>
<DrawerFooter align={align}>
<Button variant="tertiary">Cancel</Button>
<Button>Save</Button>
</DrawerFooter>
</DrawerContent>
</Drawer>
))}
</div>;
API reference
Frontfriend-owned props. Native HTML and inherited primitive props
remain documented by Radix UI.
Drawer
| Prop | Type | Default | Description |
lgSide | "bottom" | "left" | "right" | "top" | — | Edge the drawer opens from from `lg` up. |
overlay | boolean | — | |
side | "bottom" | "left" | "right" | "top" | — | Edge the drawer opens from on small screens. |
DrawerBody
| Prop | Type | Default | Description |
closeIcon | boolean | — | |
noPadding | boolean | false | |
DrawerContent
| Prop | Type | Default | Description |
container | HTMLDivElement | null | — | |
containerClassname | string | — | |
height | "auto" | "full" | — | |
width | "xs" | "sm" | "md" | "lg" | "3xl" | "5xl" | "full" | "fit" | "md" | |
DrawerFooter
| Prop | Type | Default | Description |
align | "end" | "justify" | "start" | "stretch" | "end" | |
DrawerHeader
| Prop | Type | Default | Description |
closeIcon | boolean | false | |
Configuration determines the actual classes and available styling hooks.
See Theming & component configuration before introducing
a repeated local override.