Spring physics
Critical-damped harmonic oscillator. Drag velocity carries into the settle — no jerk on flick. Sub-stepped at 240Hz, one DOM write per RAF.
A universal sheet engine. One framework-agnostic core, seven adapters, native-feel gestures.
Add, remove, edit, reorder snaps. Sheet remounts live.
Cycle min↔full at decreasing intervals. Watch the FPS.
idle
Opt-in via class on .bs-root. Loads the theme CSS
lazily.
default
Critical-damped harmonic oscillator. Drag velocity carries into the settle — no jerk on flick. Sub-stepped at 240Hz, one DOM write per RAF.
Sized once via height; resized via
transform: translate3d. Zero layout per frame.
will-change gated to drag/animate.
Snap points accept px, percentages, fit,
full, plus arbitrary CSS: 50dvh,
clamp(), env().
bottom · top · left · right. Same engine — drawer-side sheets without code duplication. Pointer axis & sign computed.
Touch flicks: 0.65px/ms threshold, 120ms velocity window. Mouse inertia: 0.4px/ms, 160ms window. Gesture parses what the pointer is.
role=slider on handle. ↑↓ steps snaps, Home/End jumps,
Esc closes. Focus trap with restore. ARIA-live announcer. WCAG 2.1
AA.
env(safe-area-inset-*), hardware-back interception,
haptic tick on snap, body scroll lock that's iOS-safe
(position:fixed).
Use useBottomSheet() for full JSX control, or grab the
ready-made <BottomSheet>. Three layers, your
call.
Open a sheet from another sheet. Z-index orchestrated, backdrops de-duped, only the topmost owns Escape.
Zero window at import.
useSyncExternalStore with cached snapshot. Optional
noSSR prop kills hydration mismatches in Next.js.
createSheetManager() — typed registry mapping route
keys to configs. onOpen/onClose hooks like
the original Vue 2 manager, framework-agnostic.
138 unit tests (vitest + happy-dom) covering snap math, spring, gestures, focus trap, scroll lock, manager, vh→dvh, viewport resize. 25 e2e via Playwright on mobile-Chrome. All green.