RRezi UI

Sheet

Panel that slides in from the start or end edge, laid out like Dialog, built on Radix Dialog.

Slides in over 250ms and out in 200ms over the same scrim as Dialog; under reduced motion it appears at once. Focus stays inside while it is open, and Escape returns it to the trigger.

Installation

npx shadcn@latest add @reziui/sheet

Usage

app/page.tsx
import {
  Sheet,
  SheetBody,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from "@/components/ui/sheet";

export function Example() {
  return (
    <Sheet>
      <SheetTrigger asChild>
        <Button variant="secondary">Filters</Button>
      </SheetTrigger>
      <SheetContent>
        <SheetHeader>
          <SheetTitle>Filters</SheetTitle>
          <SheetDescription>Narrow the project list.</SheetDescription>
        </SheetHeader>
        <SheetBody>…</SheetBody>
        <SheetFooter>…</SheetFooter>
      </SheetContent>
    </Sheet>
  );
}

Examples

side="start" opens from the left edge in left-to-right layouts and from the right in right-to-left ones; side="end" (the default) is the mirror. The mobile menu of these docs is a start sheet.

The slide direction follows the page language: Tailwind v4's CSS build turns the :dir() selectors it relies on into a list of right-to-left languages for older browsers. Set lang on <html> (for example lang="ar") along with dir="rtl", as accessibility guidelines require anyway.

API reference

ComponentNotes
SheetRadix Dialog.Root: open, defaultOpen, onOpenChange.
SheetTrigger · SheetCloseUse asChild to wrap your own button.
SheetContentside ("start" | "end", default "end"), showCloseButton (default true). 320px wide, at most 85% of the viewport.
SheetHeader · SheetTitle · SheetDescriptionAs in Dialog. Always include a title.
SheetBodyFills the space between header and footer and scrolls.
SheetFooterTinted strip pinned to the bottom.