Skip to content
GetUrUI

Bottom Sheet

.md

Draggable glass sheet with snap points; release velocity is projected forward to pick the detent and the scrim fades with the sheet's height.

bottom sheetdrawersheetmodalmobiledragsnap pointsdetentsglass

Installation

$npx shadcn@latest add @geturui/bottom-sheet
Download source (.zip)

Usage

usage.tsx
1"use client";
2import * as React from "react";
3import { BottomSheet } from "@/components/ui/bottom-sheet";
4
5export function TripDetails() {
6  const [open, setOpen] = React.useState(false);
7  return (
8    <>
9      <button onClick={() => setOpen(true)}>Show trip details</button>
10      <BottomSheet
11        open={open}
12        onOpenChange={setOpen}
13        snapPoints={[0.25, 0.55, 0.9]}
14        defaultSnap={1}
15        title="Your ride to GetUrUI HQ"
16        description="Arriving in 4 min"
17      >
18        <p>Driver, stops and fare go here.</p>
19      </BottomSheet>
20    </>
21  );
22}

Props

PropTypeDefaultDescription
open*boolean—Whether the sheet is shown.
onOpenChange*(open: boolean) => void—Called on Escape, scrim press or a dismissing swipe.
snapPointsnumber[][0.25, 0.55, 0.9]Detents as ascending fractions of the container height.
defaultSnapnumber1Detent index used each time the sheet opens.
snapnumber—Controlled detent index.
onSnapChange(index: number) => void—Called when the sheet settles on a new detent.
titleReactNode—Heading; labels the dialog.
descriptionReactNode—Supporting line; describes the dialog.
dismissiblebooleantrueAllow closing by swiping below the lowest detent or pressing the scrim.
containedbooleanfalseFill the nearest positioned parent instead of the viewport, without scroll lock.
classNamestring—Classes for the sheet surface.

Accessibility

  • role="dialog" (aria-modal when not contained) labelled by the title; focus moves to the sheet on open and returns to the opener on close.
  • Escape closes. The handle is a button: Up and Down step through detents (Down from the lowest closes), Enter or Space cycles.
  • Body scroll is locked while a viewport sheet is open; the content area scrolls on its own with overscroll containment.
  • With reduced motion the sheet moves with short tweens instead of springs.

Related