Tinyrack

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/ui

Scroll 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 open with onOpenChange for controlled visibility, or defaultOpen for uncontrolled visibility.
  • Use snapPoint with onSnapPointChange for controlled positions, or defaultSnapPoint; list allowed values in snapPoints.
  • swipeDirection controls the attached edge and dismissal direction. Left and right drawers are borderless edge surfaces; up and down drawers retain the outlined overlay surface. snapToSequentialPoints prevents velocity-based point skipping.
  • Escape, Close, backdrop presses, focus-out for non-modal drawers, and swipes dismiss by default. Set disablePointerDismissal to block outside-pointer dismissal.
  • modal defaults to true; use false for non-modal interaction or trap-focus to trap focus without locking scroll and outside pointers.
  • Popup accepts initialFocus and finalFocus. By default focus enters the drawer and returns to its trigger.
  • actionsRef exposes imperative close and unmount actions. Prefer declarative state for normal application flow.
  • Portal is 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 keeps Viewport within 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.