Skip to content
Esc
navigateopen⌘Jpreview
On this page

Sheet

Extends the Dialog component to display content that complements the main content of the screen.

import * as stylex from '@stylexjs/stylex';

import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from '@/components/ui/sheet';
import { space } from '@/lib/constants.stylex';

export default function SheetDemo() {
  return (
    <Sheet>
      <SheetTrigger render={<Button variant="outline" />}>Open</SheetTrigger>
      <SheetContent>
        <SheetHeader>
          <SheetTitle>Edit profile</SheetTitle>
          <SheetDescription>
            Make changes to your profile here. Click save when you're done.
          </SheetDescription>
        </SheetHeader>
        <div {...stylex.props(styles.fields)}>
          <Label>
            Name <Input defaultValue="Pedro Duarte" />
          </Label>
          <Label>
            Username <Input defaultValue="@peduarte" />
          </Label>
        </div>
        <SheetFooter>
          <SheetClose render={<Button />}>Save changes</SheetClose>
          <SheetClose render={<Button variant="outline" />}>Close</SheetClose>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  );
}

const styles = stylex.create({
  fields: {
    display: 'flex',
    flexDirection: 'column',
    gap: space.s4,
    paddingInline: space.s4,
  },
});

Install

npx shadcn@latest add @madeui/sheet

Usage

import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from '@/components/ui/sheet';

Composition

<Sheet>
  <SheetTrigger />
  <SheetContent>
    <SheetHeader>
      <SheetTitle />
      <SheetDescription />
    </SheetHeader>
    <SheetFooter>
      <SheetClose />
    </SheetFooter>
  </SheetContent>
</Sheet>

Sides

import * as stylex from '@stylexjs/stylex';

import { Button } from '@/components/ui/button';
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
  type SheetSide,
} from '@/components/ui/sheet';
import { space } from '@/lib/constants.stylex';

const sides: SheetSide[] = ['top', 'right', 'bottom', 'left'];

export default function SheetSides() {
  return (
    <div {...stylex.props(styles.row)}>
      {sides.map((side) => (
        <Sheet key={side}>
          <SheetTrigger render={<Button variant="outline" />}>
            {side}
          </SheetTrigger>
          <SheetContent side={side}>
            <SheetHeader>
              <SheetTitle>Sheet from {side}</SheetTitle>
              <SheetDescription>
                Slides in from the {side} edge of the screen.
              </SheetDescription>
            </SheetHeader>
          </SheetContent>
        </Sheet>
      ))}
    </div>
  );
}

const styles = stylex.create({
  row: {
    display: 'flex',
    flexWrap: 'wrap',
    gap: space.s2,
  },
});

No close button

Set showCloseButton={false} and close the sheet through your own footer buttons instead.

import { Button } from '@/components/ui/button';
import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from '@/components/ui/sheet';

export default function SheetNoCloseButton() {
  return (
    <Sheet>
      <SheetTrigger render={<Button variant="outline" />}>
        Open
      </SheetTrigger>
      <SheetContent showCloseButton={false}>
        <SheetHeader>
          <SheetTitle>Publish changes</SheetTitle>
          <SheetDescription>
            Review your changes, then publish or discard them below.
          </SheetDescription>
        </SheetHeader>
        <SheetFooter>
          <SheetClose render={<Button />}>Publish</SheetClose>
          <SheetClose render={<Button variant="outline" />}>Discard</SheetClose>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  );
}

API reference

Built on Base UI Dialog (same primitive as Dialog). The table below covers the props this library adds or changes — every other prop is forwarded; see the Base UI Dialog API reference.

SheetContent

Prop Type Default Description
side 'top' | 'right' | 'bottom' | 'left' 'right' Edge of the screen the sheet slides in from.
showCloseButton boolean true Renders an X close button in the top-right corner.
style StyleXStyles StyleX styles merged last — always win over the component’s own styles.

Was this page helpful?