Sheet
Side-anchored panel for longer flows, built on Radix Dialog with directional slide-in from any edge.
Overview
Sheet is a Radix Dialog stylized as a side panel. Use it for content that doesn't deserve full focus the way a Dialog does, but is too rich for a Popover: filter trays, detail panels, multi-section settings, navigation menus on mobile. Slide direction is configurable per side (top, right, bottom, left).
For desktop ergonomics, prefer right (filter and detail panels). left is conventional for navigation. On mobile breakpoints, Drawer is usually a better fit because it adds native drag-to-dismiss gestures.
Preview
Installation
bash npx gremorie@latest add rx-sheet bash pnpm dlx gremorie@latest add rx-sheet bash yarn dlx gremorie@latest add rx-sheet bash bunx --bun gremorie@latest add rx-sheet Usage
import { Button } from "@gremorie/rx-forms";
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@gremorie/rx-overlays";
export function Example() {
return (
<Sheet>
<SheetTrigger asChild>
<Button variant="outline">Open filters</Button>
</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>Filters</SheetTitle>
<SheetDescription>
Narrow down the registry by category and edition.
</SheetDescription>
</SheetHeader>
{/* filter controls */}
</SheetContent>
</Sheet>
);
}Angular edition planned for Phase 5h. Star the repo to track progress.
API
<Sheet>
Extends Radix Dialog.Root. Same controlled API as Dialog (open, defaultOpen, onOpenChange, modal).
<SheetContent>
| Prop | Type | Default | Description |
|---|---|---|---|
side | "top" | "right" | "bottom" | "left" | "right" | Edge the sheet docks against and slides in from. |
showCloseButton | boolean | true | Renders the top-right X close button. |
Wraps Radix Dialog.Content in a Portal with the overlay. Width and height adapt to side:
right/left: full-height,w-3/4capped atsm:max-w-sm.top/bottom: full-width,h-auto.
<SheetHeader>, <SheetFooter>
Layout containers padded p-4. Header stacks title and description; footer pushes to the bottom (mt-auto) with gap-2.
<SheetTitle>, <SheetDescription>
Map to Radix Dialog.Title and Dialog.Description. Both are required by Radix; render with className="sr-only" if visually hidden.
<SheetTrigger>, <SheetClose>, <SheetOverlay>, <SheetPortal>
Pass-throughs over the Radix primitives with data-slot attributes.
Composition
<Sheet>owns the open/close state.<SheetTrigger asChild>wraps the focusable element that opens it.<SheetContent side="right">mounts via Portal, draws the overlay, slides in from the chosen edge.- Header carries title and description; body holds the main content; footer pins primary actions at the bottom.
- Dismissal: click overlay, press
Esc, click the X (showCloseButton), or callSheetClose.
Variations
Right filter panel
The canonical desktop pattern. Filter form pinned, scrollable body, apply/reset in the footer.
<Sheet>
<SheetTrigger asChild>
<Button variant="outline">Filters</Button>
</SheetTrigger>
<SheetContent side="right">
<SheetHeader>
<SheetTitle>Filters</SheetTitle>
</SheetHeader>
<div className="flex-1 overflow-auto px-4">{/* filter form */}</div>
<SheetFooter>
<Button variant="outline">Reset</Button>
<Button>Apply</Button>
</SheetFooter>
</SheetContent>
</Sheet>Left navigation drawer
Pair with a hamburger trigger on mobile for primary navigation.
<Sheet>
<SheetTrigger asChild>
<Button variant="ghost" size="icon" aria-label="Open menu">
<MenuIcon />
</Button>
</SheetTrigger>
<SheetContent side="left">
<SheetHeader>
<SheetTitle>Navigation</SheetTitle>
</SheetHeader>
<nav className="px-4">{/* nav links */}</nav>
</SheetContent>
</Sheet>Bottom notification panel
Use side="bottom" for transient panels that don't deserve a centered modal (system status, recent activity).
<SheetContent side="bottom">
<SheetHeader>
<SheetTitle>Recent activity</SheetTitle>
</SheetHeader>
{/* activity feed */}
</SheetContent>Accessibility
- Role:
role="dialog"witharia-modal="true"(defaultmodalprop). - Keyboard:
Esccloses;Tabcycles focus within the content; focus is trapped while open. - Focus management: focus moves to the first focusable element on open and returns to the trigger on close.
- Title:
SheetTitleis mandatory; without it Radix logs a warning. Usesr-onlyif you need to hide it visually. - Description: links to content via
aria-describedbyautomatically. - Reduced motion: slide animations honor
prefers-reduced-motionvia the underlying Tailwind animate utilities.
Related
- Drawer - vaul-based bottom sheet with drag-to-dismiss for mobile.
- Dialog - centered modal for focused decisions.
- Popover - inline anchored overlay for small contextual UI.
- Navigation Menu - top-level navigation that doesn't overlay.