Overlay
Sheet
Modal slide-in panel anchored to a screen edge. Same semantics as Dialog (backdrop, focus trap, Escape, scroll lock) with a slide animation and four sides. Composes with SheetHeader/Body/Footer, SheetTitle/Description and SheetClose.
Import
import { Sheet, SheetHeader, SheetBody, SheetFooter, SheetTitle, SheetDescription, SheetClose } from "@zephora/react";Examples
Basic sheet
Slides in from the end (right in LTR) by default.
const [open, setOpen] = React.useState(false);
<Button onClick={() => setOpen(true)}>Open sheet</Button>
<Sheet open={open} onOpenChange={setOpen}>
<SheetHeader>
<SheetTitle>Settings</SheetTitle>
</SheetHeader>
<SheetBody>Panel content goes here.</SheetBody>
<SheetFooter>
<Button variant="outline" onClick={() => setOpen(false)}>Close</Button>
</SheetFooter>
</Sheet>Sides
`side` picks the edge the panel slides in from.
<Sheet open={open} onOpenChange={setOpen} side="start">
…
</Sheet>
<Sheet open={open2} onOpenChange={setOpen2} side="bottom" size="sm">
…
</Sheet>API
Sheet props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state. |
defaultOpen | boolean | false | Initial open state (uncontrolled). |
onOpenChange | (open: boolean) => void | — | Called whenever the sheet requests an open state change. |
side | "start" | "end" | "top" | "bottom" | "end" | Edge the panel slides in from. |
size | "sm" | "md" | "lg" | "full" | "md" | Panel size along its sliding axis. |
closeOnOverlayClick | boolean | true | Clicking the backdrop closes the sheet. |
closeOnEscape | boolean | true | Pressing Escape closes the sheet. |
showClose | boolean | true | Renders a SheetClose "X" button in the header area. Set to false when you place your own <SheetClose />. |
initialFocusRef | RefObject<HTMLElement | null> | — | Element focused when the sheet opens (defaults to the first focusable). |
classNames | Partial<Record<SheetSlot, string>> | — | Per-slot class overrides set once on the root: "root" / "panel" (both target the panel, which is the root element — className still lands there last) | "backdrop" | "header" | "body" | "footer" | "title" | "description" | "close". Appended after the module classes and also applied in unstyled mode. |
unstyled | boolean | false | Headless mode — skips Zephora styling. |
SheetHeader / SheetBody / SheetFooter / SheetTitle / SheetDescription props
| Prop | Type | Default | Description |
|---|---|---|---|
unstyled | boolean | false | Headless mode. SheetTitle and SheetDescription also auto-wire themselves to the panel via aria-labelledby / aria-describedby. |
…rest | HTMLAttributes | — | Native element props are forwarded. |
SheetClose props
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Custom close glyph; defaults to an X icon. |
aria-label | string | "Close" | Accessible name of the close button. |
unstyled | boolean | false | Headless mode. |
Keyboard
| Key | Action |
|---|---|
Escape | Closes the sheet (unless closeOnEscape is false). |
Tab / Shift+Tab | Cycles focus inside the panel — focus is trapped while open. |