Skip to Content
⭐️ Leave a star →
ComponentsSheet

Sheet

A Drawer-adjacent panel that slides in from the top or bottom edge with iOS-style snap points. Drag the handle to rest at configured heights, or flick past the smallest snap to dismiss. Modal by default — it traps focus and locks page scroll.

Features

Slides from the top or bottom edge via the side prop.
Snap points let the sheet rest at multiple heights.
Drag the handle to resize, or past the smallest snap to dismiss.
Closes on Escape and overlay click when dismissible.
Portal rendering with focus trap and scroll lock when modal.
Can be controlled or uncontrolled.

Example

import { Sheet } from '@wire-ui/react' <Sheet.Root snapPoints={[0.4]}> <Sheet.Trigger>Open Sheet</Sheet.Trigger> <Sheet.Portal> <Sheet.Overlay /> <Sheet.Content> <Sheet.Handle /> <Sheet.Title>Bottom sheet</Sheet.Title> <Sheet.Description>Slides up from the bottom edge.</Sheet.Description> <Sheet.Close>Done</Sheet.Close> </Sheet.Content> </Sheet.Portal> </Sheet.Root>

Styling

Sheet sets data-state on Overlay and Content, plus data-side and data-dragging on Content. Use them to drive slide-in transitions and to disable the transition while dragging.

<Sheet.Overlay className=" bg-black/50 data-[state=closed]:opacity-0 transition-opacity " /> <Sheet.Content className=" transition-transform data-[side=top]:rounded-b-[20px] data-[side=bottom]:rounded-t-[20px] data-[dragging]:transition-none " />

Using data attributes

Overlay receives data-state; Content receives data-state, data-side, and (while dragging) data-dragging.

/* Slide up from bottom */ [data-side="bottom"][data-state="closed"] { transform: translateY(100%); } [data-side="bottom"][data-state="open"] { transform: translateY(0); } /* Kill the transition mid-drag so the handle tracks the pointer */ [data-dragging] { transition: none; }

Root props

PropTypeDefaultDescription
openbooleanControlled open state
defaultOpenbooleanfalseInitial open state (uncontrolled)
onOpenChange(open: boolean) => voidCalled when the open state changes
side'top' | 'bottom''bottom'Edge the sheet slides from
snapPointsnumber[][1]Rest positions. Values ≤ 1 are a fraction of the viewport; values > 1 are px. Order smallest → largest
activeSnapPointnumberControlled active snap index
defaultActiveSnapPointnumberlargest snapInitial active snap index
onActiveSnapPointChange(index: number) => voidCalled when the active snap index changes
modalbooleantrueRender a focus-trapping, scroll-locking modal
dismissiblebooleantrueAllow closing by dragging past the smallest snap, Escape, or overlay click

Trigger / Portal / Overlay / Handle / Title / Description / Close props

Sub-componentTypeDescription
Sheet.TriggerButtonHTMLAttributesOpens the sheet on click. Sets aria-haspopup="dialog" and aria-expanded
Sheet.Portal{ container?: Element | null }Renders children into container (defaults to document.body) when open
Sheet.OverlayHTMLAttributesBackdrop. Closes the sheet on click when dismissible
Sheet.ContentHTMLAttributesThe panel; role="dialog", aria-modal, labelled/described by Title/Description
Sheet.HandleHTMLAttributesDrag affordance; role="button", aria-label="Drag to resize"
Sheet.TitleHTMLAttributesRenders an <h2> referenced by aria-labelledby
Sheet.DescriptionHTMLAttributesRenders a <p> referenced by aria-describedby
Sheet.CloseButtonHTMLAttributesCloses the sheet on click

Data attributes

AttributeElementValues
data-stateOverlay, Content"open" / "closed"
data-sideContent"top" / "bottom"
data-draggingContentPresent while the handle is being dragged

Accessibility

  • Sheet.Content renders role="dialog" with aria-modal and is labelled by Sheet.Title (aria-labelledby) and described by Sheet.Description (aria-describedby).
  • When modal is set, focus is trapped inside the content and page scroll is locked.
  • Sheet.Trigger exposes aria-haspopup="dialog" and reflects open state via aria-expanded.

Keyboard Interactions

KeyDescription
EscapeCloses the sheet when dismissible.
TabMoves focus to the next focusable element inside the sheet.
Shift+TabMoves focus to the previous focusable element inside the sheet.
Last updated on

MIT License © 2026 wire-ui

Sheet – Wire UI