Meet Frontfriend.Your brand. Your rules. Your agents, connected.Explore what’s new

Drawer

Interactive preview

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>;

Scrollable

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>;

Footer Alignment

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.