Drawer
A swipe-aware task surface that slides from its viewport edge and fades its backdrop when it opens or closes.
Contract
TRDrawer preserves Base UI's controlled and uncontrolled state, swipe and snap-point gestures, focus management, keyboard dismissal, portals, and React 19 refs and render props. Motion follows swipeDirection and the user's reduced-motion preference. The Playground keeps open and snapPoint synchronized with drawer events; Reset restores the closed, full-height, downward-swiping default.
Install
pnpm add @tinyrack/uiScroll inside the code area to read long lines.
Styles
@import '@tinyrack/ui/components/drawer.css';Scroll inside the code area to read long lines.
Imports
import { TRDrawer } from '@tinyrack/ui/components/drawer';Scroll inside the code area to read long lines.
Playground
Usage
Examples
Snap points and nested content permalink
Drag between compact, medium, and full-height positions. The nested drawer exercises focus containment and coordinated indentation.
Direction permalink
Set swipeDirection to down, up, left, or right. The popup attaches to and dismisses toward the corresponding viewport edge. Left and right drawers use a borderless edge surface.
Provider, detached handle, and swipe area permalink
Provider coordinates page indentation, a typed detached trigger passes payload through createHandle, and SwipeArea opens the same drawer from the viewport edge.
Virtual keyboard permalink
VirtualKeyboardProvider keeps focused fields visible when a mobile virtual keyboard resizes the visual viewport.
Anatomy
Root owns state. Trigger opens it. Portal mounts overlays into document.body or a supplied container. Backdrop, Viewport, Popup, and scrollable Content compose the modal surface. Title and Description label the dialog, and Close dismisses it. SwipeArea enables edge opening. Provider, Indent, and IndentBackground coordinate nested page effects. VirtualKeyboardProvider handles mobile keyboard viewport changes. createHandle connects detached triggers with typed payloads.
Behavior
- Use
openwithonOpenChangefor controlled visibility, ordefaultOpenfor uncontrolled visibility. - Use
snapPointwithonSnapPointChangefor controlled positions, ordefaultSnapPoint; list allowed values insnapPoints. swipeDirectioncontrols the attached edge and dismissal direction. Left and right drawers are borderless edge surfaces; up and down drawers retain the outlined overlay surface.snapToSequentialPointsprevents velocity-based point skipping.- Escape,
Close, backdrop presses, focus-out for non-modal drawers, and swipes dismiss by default. SetdisablePointerDismissalto block outside-pointer dismissal. modaldefaults totrue; usefalsefor non-modal interaction ortrap-focusto trap focus without locking scroll and outside pointers.PopupacceptsinitialFocusandfinalFocus. By default focus enters the drawer and returns to its trigger.actionsRefexposes imperativecloseandunmountactions. Prefer declarative state for normal application flow.Portalis client-mounted while closed SSR markup remains hydration-safe. The default body portal covers the full visual viewport, including a reserved scrollbar gutter. A custom portal keepsViewportwithin its supplied container.
API
Every compound part, its prop type, and its state type is exported from @tinyrack/ui/components/drawer. CSS is opt-in through @tinyrack/ui/components/drawer.css; use --tr-drawer-popup-max-width, --tr-drawer-popup-background, --tr-drawer-backdrop, --tr-drawer-control-background, --tr-drawer-motion-duration, and --tr-drawer-motion-easing for local appearance and motion overrides.