ComponentsOverlays & feedback

Sheet / Drawer

An edge panel that keeps the list behind it in view — quick edit, record preview, mobile filters and navigation. Logical sides, four widths, an inset floating style, a non-modal preview mode, and a Drawer that closes by dragging down.

Radix Dialog + pointer events components/sheet.tsx, components/dialog.tsx, styles/overlays.csstheme · material · accent · density · font

Installation

$ pnpm add @vamos-ui/react

The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";

Usage

import { Sheet, SheetTrigger, SheetContent, SheetHeader, SheetBody, SheetFooter, Button } from "@vamos-ui/react";

<Sheet>
  <SheetTrigger asChild><Button>Quick edit</Button></SheetTrigger>
  <SheetContent side="end" size="md">
    <SheetHeader title="Edit contact" />
    <SheetBody>…</SheetBody>
    <SheetFooter>…</SheetFooter>
  </SheetContent>
</Sheet>

Blur turns off while dragging (data-dragging), following the glass budget.

A docked, resizable preview column belongs to Record detail / List layout, not to Sheet.

Examples

Sides

start / end are logical and flip in RTL. inset floats the panel with an 8px gutter.

Record preview (CRM)

modal={false}: no overlay or focus trap, the list stays clickable and switching rows updates the panel. Esc still closes.

Filters as a bottom sheet

side="bottom" fits its content up to the size cap; the footer keeps the result count visible.

Drawer

Drag the handle or header down to close. Drags never start on controls or inside a scrolled body; Esc and × always work.

API

Sheet / Drawer

PropTypeDefault
open / defaultOpen / onOpenChange
Same as Dialog.
boolean / boolean / (open) => void—
modal
false → page stays interactive, no overlay, outside clicks don't close (aria-modal="false").
booleantrue

SheetContent

PropTypeDefault
side
Logical edge. left / right are accepted as aliases of start / end.
"start" | "end" | "top" | "bottom""end"
size
start/end width: 360 / 440 / 560 / 720 px. top/bottom height cap: 40 / 60 / 75 / 85 % of the viewport.
"sm" | "md" | "lg" | "xl" | "full""md"
inset
8px gutter and full radius — a floating panel.
booleanfalse
dismissible / onBeforeClose / hideClose / container / labels
Shared layer behaviour.
as DialogContent—

DrawerContent

PropTypeDefault
dragToDismiss
Close by dragging down past 30% of the height, or with a quick flick.
booleantrue
handle
Show the grab handle (aria-hidden).
booleantrue
size
Height cap.
SheetContent size"lg"

Parts

PropTypeDefault
SheetHeader / SheetBody / SheetFooter
Same API as the Dialog parts.
LayerHeader / LayerBody / LayerFooter—
DrawerHeader / DrawerBody / DrawerFooter / DrawerHandle
Drawer variants; DrawerBody marks the scroll area for drag handling.
layout parts—
SheetTrigger / SheetClose / DrawerTrigger / DrawerClose
Use asChild with a Button.
Radix parts—
useDragDismiss()
The pointer logic, for custom bottom panels.
({ onDismiss, threshold?, velocity?, enabled? }) => { ref, handlers }—