Rebar UI

1.0

opinion

BottomSheet

A draggable panel for richer content, with a handle.

Move toTap, then drag the handle down

Offline sync for tasks

Jonas Weber · In progress

Empty
Error
Loading
Long text

In context

Three sheetsA list of choices, a filter form and a loading sheet, open on the phone
Harbour rebrand

Offline sync for tasks

Jonas · Eng

Harbour homepage

Maya · Design

Move to
Tideline mobile

Offline sync for tasks

Jonas · Eng

Harbour homepage

Maya · Design

Filter tasks
MineOverdueThis week
DesignEngResearchOps
Crew interviews

Offline sync for tasks

Jonas · Eng

Harbour homepage

Maya · Design

Depot signage proofs

Leo · Ops

Loading members

Hold on a moment.

Props

PropTypeRequiredDefault
openboolean | undefinedNo—
defaultOpenboolean | undefinedNo—
onOpenChange((open: boolean) => void) | undefinedNo—
triggerReactNodeNo—
titleReactNodeNo—
descriptionReactNodeNo—
footerReactNodeNo—
classNamestring | undefinedNo—
sizenumber | "auto" | undefinedNo—
maxHeightstring | number | undefinedNo—
dismissibleboolean | undefinedNo—
containerHTMLElement | null | undefinedNo—
appearance"default" | "popup" | undefinedNo—
showHandleboolean | undefinedNo—
titleStyle"eyebrow" | "heading" | undefinedNo—

Accessibility

Drawer fixed to side="bottom", so it inherits the Radix Dialog wiring: role="dialog" with aria-modal="true", focus trapped while open, Esc and backdrop click close it. The handle is a real drag-to-dismiss surface (past a quarter of the sheet's height, release closes it), but the visible close button, Esc and the backdrop always work too.

data-rebar-* attributes

data-rebar-component="bottom-sheet" on the panel; data-rebar-part="handle" on the drag handle, plus every data-rebar-part Drawer carries (header, title, description, body, footer, close).

Migrating to Ant Design

AntD has no direct equivalent. Migrate to antd's Drawer with placement="bottom" and drop the handle.

Auto height and non-dismissible

Pass size="auto" to fit the content (up to maxHeight, default 85vh; the body scrolls past that) instead of a fixed pixel height. Drawer takes the same props. dismissible={false} removes the grab bar and close button, disables drag-to-dismiss and ignores Esc and backdrop clicks, so only your own controls close it.

<BottomSheet open title="Pick one" size="auto" maxHeight="70vh">...</BottomSheet>\n<BottomSheet open title="Confirm" dismissible={false} footer={<Button onClick={done}>Done</Button>} />

appearance="popup"

appearance="popup" is the flat mobile-UI popup: no close button (kept, visually hidden), no grab bar unless showHandle, an eyebrow title (or titleStyle="heading"), a body that scrolls between header and footer, content height by default, and popups stack in the order they opened. Tokens: --rebar-popup-bg / -text / -radius / -padding / -title-color / -title-padding / -hairline / -footer-padding / -handle-bg / -handle-margin / -bleed.