Drawer and Sheet
Use drawer and sheet with the current published Askr packages.
@askrjs/themes/drawer0.0.13@askrjs/themes/sheet0.0.13
How to use drawer and sheet
Drawer and Sheet should use the standard themed surface unless the application is deliberately implementing its own design system on top of @askrjs/ui.
- Import the themed component from @askrjs/themes/components; use @askrjs/ui directly only when building a custom visual system.
- Keep drawer and sheet labels, state, and application actions visible at the call site instead of styling internal DOM nodes.
- Verify keyboard behavior, focus movement or return, disabled state, and both standard themes.
import { Button, Dialog, DialogContent, DialogDescription, DialogTitle, DialogTrigger } from '@askrjs/themes/components';
<Dialog>
<DialogTrigger asChild><Button>Edit project</Button></DialogTrigger>
<DialogContent>
<DialogTitle>Edit project</DialogTitle>
<DialogDescription>Changes are visible immediately.</DialogDescription>
<ProjectForm />
</DialogContent>
</Dialog>Purpose
Drawer and Sheet are themed components for panel-style overlays — a drawer sliding in from an edge, a sheet covering more of the viewport — but as shipped today they're both exported as direct aliases of `Dialog` under `@askrjs/themes`, with no headless `@askrjs/ui` primitive of their own. That's why this page is marked experimental: the names exist to signal intent in your markup, but the underlying behavior, positioning, and CSS are currently identical to Dialog.
Install and import
Headless control for these components comes from `@askrjs/ui/dialog` — no separate `@askrjs/ui/drawer` or `@askrjs/ui/sheet` package exists. Themed usage is different: import from `@askrjs/themes/drawer` and `@askrjs/themes/sheet`, which compile to the same output as `@askrjs/themes/dialog` under the hood. The only visible difference is naming — you'll get `Drawer`/`Sheet`-prefixed exports such as `DrawerContent` and `SheetTrigger` instead of `Dialog`-prefixed ones.
Live examples
A Drawer or Sheet example looks exactly like a Dialog example with the names swapped: a root component wrapping a trigger and a portal-rendered content block with title, description, and close affordances. There is currently no `side` prop or edge-anchored slide-in animation distinguishing them visually from a centered modal — that's the clearest way to see the alias in practice.
Anatomy
`DrawerContent`/`SheetContent` are `DialogContent` under a different name, so they inherit the same overlay-plus-content structure: `DrawerTrigger` opens it, `DrawerPortal` mounts it outside the normal DOM flow, `DrawerOverlay` is the backdrop, and `DrawerTitle`/`DrawerDescription` supply the accessible name and description. Swap the `Drawer` prefix for `Sheet` and the story is identical.
State model
Open state follows Dialog's shape exactly: `open`, `defaultOpen`, `onOpenChange`, and `modal` on the root component. There is no drawer-specific state, like which edge it's anchored to, because that behavior hasn't been built out separately from Dialog yet.
Keyboard and accessibility
Because the implementation is Dialog's, Escape-to-close, focus trapping, and the `dialog`/`alertdialog` role handling all carry over unchanged — `DialogContentOwnProps`' `onEscapeKeyDown`, `onPointerDownOutside`, and `onDismiss` hooks are available under the Drawer/Sheet names too. Don't assume drawer-specific screen-reader behavior (like announcing a direction of entry) exists; it doesn't yet.
Styling and tokens
There's no dedicated `drawer.css` or `sheet.css` in the default theme — both ride on the same overlay CSS and `data-state`/`data-slot` attributes as Dialog. If you want an actual slide-in panel from an edge, you'll need to add that positioning and transition CSS yourself against the Dialog-derived markup, since the shipped styles only render it as a centered modal.
API
The full Dialog prop surface is inherited: `DrawerContent`/`SheetContent` take `forceMount`, `role`, `onEscapeKeyDown`, `onPointerDownOutside`, `onInteractOutside`, and `onDismiss`; `DrawerTrigger`/`SheetTrigger` and `DrawerClose`/`SheetClose` take standard button-like props. There are no drawer- or sheet-specific props like `side` or `size` in the current release.
Edge cases
If your design calls for a genuine edge-anchored panel with its own slide transition, treat Drawer and Sheet as a naming convention today, not a distinct component — you're responsible for the positioning CSS and any width/height constraints. Because both names compile to the same module as Dialog, mixing `Drawer` and `Sheet` imports in one tree carries no behavioral risk, but it also means renaming one to the other later is a no-op beyond your own class names.
Related pages
See Dialog for the primitive Drawer and Sheet are currently built from, including its full controlled-state and dismissal-handling API. See Alert Dialog for the confirmation-flow variant of the same underlying pattern.