Releases: harshmandan/svaul
Release list
v2.0.0
svaul v2 is a ground-up rebuild of the motion core. It answers to momentum, not keyframes: fling it and the close speed follows your throw, catch it mid-close, reverse it on a dime. Every close is interruptible by construction, the whole system is declarative now (CSS transitions + variables, no per-frame JavaScript).
More:
- Background scale is a theme-able stylesheet (removed inline styles
bodymutations). - Snap points now take
%/rem/vh/vw/calc(). - More sturdier scroll-lock, focus-trap, and modal
inert.
Breaking
- Enter/exit are CSS transitions, not keyframes —
@keyframes svaul-drawer-*removed. - Removed the
scrollLockTimeoutprop. - Background scale is driven by CSS variables +
data-*attributes, not inlinetransform/filterorbody.background. - Snap points: a number
> 1is pixels (≤ 1stays a fraction). - Scroll-lock now locks
<html>in addition to<body>.
Details in #1.
v1.2.1
Fix (mobile): swipe-dismissing the drawer then tapping the trigger dropped the first tap's synthesized click on Chrome/Android, so it took a second tap to reopen. The drag now claims the gesture via a non-passive touchmove preventDefault, which stops the click-suppression.
Motion: velocity-scaled swipe close (a fast flick closes faster) + interruptible reopen (grab it mid-close). Non-swipe closes (overlay / Escape / programmatic) keep the default animation.
Responsiveness: removed the post-open (500 ms) and post-scroll (250 ms) drag-lock timers; scroll-vs-drag is now decided structurally. The backdrop is non-interactive while closing so a reopen tap reaches the trigger.
Note: the scrollLockTimeout prop was removed (its debounce is gone). GitHub release only — not published to npm.
v1.2.0
1.2.0 - Major release
⚠️ Breaking changes
svaul-* namespace
Every hook the library exposes to the DOM/CSS is now brand-namespaced (was the too-generic data-drawer / --drawer-*, which could collide with your own selectors/vars).
Migration
| Before | After |
|---|---|
[data-drawer], [data-drawer-overlay], [data-drawer-handle], … |
[data-svaul-drawer], [data-svaul-drawer-overlay], … |
[data-drawer-wrapper], [data-drawer-no-drag] |
[data-svaul-drawer-wrapper], [data-svaul-drawer-no-drag] |
--drawer-bg, --drawer-radius, --drawer-handle-bg, … |
--svaul-drawer-bg, --svaul-drawer-radius, … |
.drawer-dragging |
.svaul-drawer-dragging |
data-svaul-ignore and data-state are unchanged. If you don't target svaul's attributes/vars in your own CSS, no changes are needed.
⚠️ Peer dependency
svelte peer range tightened ^5.0.0 → ^5.29.0 — the code requires createAttachmentKey/{@attach} (5.29) and $props.id() (5.20). Previously 5.0–5.28 installed cleanly then failed to compile.
Fixes
Gestures
- Swipe-to-close now survives
pointercancel/touchcancelfrom scrollable content and system interruptions (incoming call, shade pull). - Direction-aware scroll-vs-drag gate: top drawers use the bottom scroll edge; side drawers yield to horizontal scrollers (and can be swiped closed at the edge).
overscroll-behaviorstops Android pull-to-refresh during a swipe-close.- Multi-touch no longer corrupts a drag; abandoned cross-axis gestures no longer jump snap points; drag state can't get stuck.
Snap points
- Snap points supplied/changed after mount reconcile correctly (no more off-screen/frozen drawer); container-relative offsets reflow on resize/rotation; unit-less string points (
"0.5") resolve as fractions.
A11y
- Only the topmost drawer traps Tab (nested drawers no longer freeze keyboard nav); Escape ignored during IME composition; SSR markup carries the accessible name; focus restore no longer drops to
<body>;visibility:hiddenelements excluded from the focus trap.
Mobile / visual
- Reopening a
keepMounted(or quickly-reopened) drawer no longer sticks mid-drag; scroll-lock restores both axes instantly; background-scale revert can't leave a permanently-black body; drawer text is selectable (not blanketuser-select:none).
Cleanup
- Removed a dead CSS selector and a write-only attribute.
v1.1.1
Fixes
- Swipe-to-close now works from scrollable content. A scrollable full-screen drawer couldn't be flicked closed even when scrolled to the top (regression vs vaul). The browser fires
pointercancelthe moment it claims a touch gesture for native scrolling, which was aborting the drag. The drawer now ignorespointercancelfor touch input and finishes the gesture through atouchmove/touchendfallback. - Default
scrollLockTimeoutraised100ms → 250msso the drawer is less eager to re-drag immediately after a scroll.
Demo
- New Full-screen scrollable drawer example on the homepage.
v1.1.0
Features
calc(), percentage and pixel-offset snap points (e.g."calc(50% + 24px)")- Compounding nested card-stack: drawers step back per level and the background dims one notch per level
- Portal/shadow-DOM-aware dismiss — mark layers
data-svaul-ignore; outside-click usescomposedPath() keepMounted— keep content in the DOM (hidden + inert) while closedonlyPrimaryPointer— ignore non-primary (right/middle) button drags
Install: npm i @harshmandan/svaul
v1.0.0
First stable release of svaul — a hand-rolled, zero-dependency drawer/bottom-sheet for Svelte 5 (runes).
- Drag-to-dismiss with velocity/fling, rubber-band, and all four directions
- Snap points (with handle tap-to-cycle), background scaling, nested drawers
- Accessible modal dialog: focus trap, inert background, Escape, ARIA wiring
- iOS-safe scroll lock + on-screen-keyboard repositioning
- Ergonomic single
<Drawer>component plus a headlessDrawerclass
Install: npm i @harshmandan/svaul