Drawer
An accessible slide-in panel built on Base UI Dialog. Compound component pattern with Header, Body, Footer, Title, and Description. Four sides (right, left, top, bottom). Five sizes. Five corner-rounding options. Auto-stacking footer for sheets. LTR and RTL support.
Playground
Installation
pnpm add @tessinaui/uiUsage
import {
Drawer,
DrawerTrigger,
DrawerClose,
DrawerContent,
DrawerHeader,
DrawerTitle,
DrawerDescription,
DrawerBody,
DrawerFooter,
} from "@tessinaui/ui";<Drawer>
<DrawerTrigger className="...">Open</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Panel title</DrawerTitle>
<DrawerDescription>Supporting description text.</DrawerDescription>
</DrawerHeader>
<DrawerBody>
<p>Content goes here.</p>
</DrawerBody>
<DrawerFooter>
<DrawerClose className="...">Cancel</DrawerClose>
<DrawerClose className="...">Save</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>Examples
Default
A trigger that opens a right-side panel with a header, body, and footer.
Sides
Slide the panel in from the right, left, top, or bottom edge.
Sizes
Five widths for left/right panels — sm, md, lg, xl, and full.
Rounded
Corner-rounding options applied to the panel's inner edge.
Bottom Sheet
A bottom-anchored sheet with a drag handle and a stacked footer.
Navigation
A left-side navigation drawer with menu items and a sign-out action.
API Reference
Drawer
Root component. Wraps Base UI Dialog.Root and provides context for side, size, and dir.
| Prop | Type | Default | Description |
|---|---|---|---|
side | "right" | "left" | "top" | "bottom" | "right" | Which edge the panel slides from |
size | "sm" | "md" | "lg" | "xl" | "full" | "md" | Panel width (right/left) or max-height (top/bottom) |
dir | "ltr" | "rtl" | "ltr" | Text direction applied to the panel and its children |
open | boolean | — | Controlled open state |
defaultOpen | boolean | — | Uncontrolled initial open state |
onOpenChange | (open: boolean, event: Event) => void | — | Called when the open state changes |
dismissible | boolean | true | Whether backdrop click or Escape closes the drawer |
modal | boolean | true | Whether to use modal behavior (focus trap, scroll lock) |
DrawerContent
Renders the panel inside a portal. Includes the backdrop automatically.
| Prop | Type | Default | Description |
|---|---|---|---|
side | DrawerSide | from context | Override the slide-in side |
size | DrawerSize | from context | Override the panel size |
rounded | "none" | "sm" | "md" | "lg" | "full" | "md" | Corner rounding (applied to inner corners only) |
showHandle | boolean | true for bottom, false otherwise | Show the drag handle pill |
Size values:
| Size | right / left | top / bottom |
|---|---|---|
sm | 320px | max-h 40dvh |
md | 400px | max-h 60dvh |
lg | 512px | max-h 75dvh |
xl | 640px | max-h 90dvh |
full | 100% | 100dvh |
DrawerHeader
| Prop | Type | Default | Description |
|---|---|---|---|
icon | ReactNode | — | Leading icon rendered beside the title |
showClose | boolean | true | Whether to render the built-in X close button |
The first child of DrawerHeader is treated as the title row (shares a line with the icon). All subsequent children (e.g. DrawerDescription) render full-width below it.
DrawerTitle
Renders as Dialog.Title. Accepts all <div> props plus className.
DrawerDescription
Renders as Dialog.Description. Accepts all <div> props plus className.
DrawerBody
Scrollable content area. Grows to fill available space between header and footer. Accepts all <div> props plus className.
DrawerFooter
Action area. For side="bottom" and side="top" drawers, buttons stack vertically (full-width). For side="left" and side="right" drawers, buttons align horizontally to the end. Pass className="flex-row items-center justify-end" to override the auto-stacking behaviour.
DrawerTrigger
Re-export of Dialog.Trigger. Renders a <button> that opens the drawer. Use the render prop to swap in a custom element.
DrawerClose
Re-export of Dialog.Close. Renders a <button> that closes the drawer. Use the render prop to swap in a custom element.
DrawerBackdrop
Pre-styled backdrop with blur and fade animation. Included automatically by DrawerContent.
Divider
A thin line that separates content. Horizontal or vertical, solid / dashed / dotted, five thickness sizes, tonal colours, optional inline label, and RTL support.
Dropdown Menu
A contextual menu that opens from a trigger, built on Radix UI. Supports grouped items, leading/trailing icons, keyboard shortcuts, descriptions, submenus, checkboxes, radio groups, and full RTL layout.