Skip to content

Repository files navigation

svaul

svaul

version downloads

The best drawer on the planet — for Svelte 5. Velocity-based, runes-first, unstyled: drag-to-dismiss, snap points, nested drawers, an accessible dialog core. Zero runtime dependencies. Fling it, catch it mid-close, reverse it on a dime — joy to use. (See Why svaul?.)

Quick start

npm i @harshmandan/svaul

Requires Svelte ^5.

<script lang="ts">
  import Drawer from "@harshmandan/svaul";
  let open = $state(false);
</script>

<Drawer bind:open class="rounded-t-xl bg-white p-4">
  {#snippet trigger(props)}
    <button {...props}>Open</button>
  {/snippet}

  <h2>A bottom sheet</h2>
  <p>Drag it down to dismiss, or tap outside.</p>

  {#snippet footer({ close })}
    <button onclick={close}>Close</button>
  {/snippet}
</Drawer>

Every part of the drawer is customizable via named snippets in the <Drawer> component: trigger, overlay, content, handle, title, description, header, footer, and the default children (the scrollable body). Supply only the parts you want to own; each renders a sensible default otherwise. Body snippets receive { open, close, setOpen, closeAll, cycleSnapPoint } controls.

To close the drawer on the browser back button, drive open yourself and reset it from onOpenChange + a popstate listener (svaul intentionally doesn't touch history).

Key props

Prop Default
bind:open controlled/uncontrolled open state (also onOpenChange)
direction "bottom" top · bottom · left · right
snapPoints fractions (0.5) or px ("148px"); pair with bind:activeSnapPoint
dismissible true drag / overlay-click / Escape can close
modal true overlay + scroll-lock + focus-trap
scaleBackground false scale [data-svaul-drawer-wrapper] (the card-stack look)
handleOnly false only the handle initiates a drag
dragSensitivity 1 >1 makes the drawer move faster than the cursor
disableAnimation false instant open / close

Plus closeThreshold, repositionInputs, preventScrollRestoration, noBodyStyles, setBackgroundColorOnScale, backgroundColor, borderRadius, autoFocus, fadeFromIndex, snapToSequentialPoint, container, keepMounted, onlyPrimaryPointer — see the exported types.

Snap points accept fractions (≤ 1, e.g. 0.5), pixels ("148px" or a plain number > 1), percentages ("50%"), rem/vh/vw, and calc() combinations: snapPoints={["calc(50% + 24px)", 1]}.

Styling

It ships unstyled — bring your own class. Everything is reachable via data attributes ([data-svaul-drawer], [data-svaul-drawer-overlay], [data-svaul-drawer-handle]) and CSS variables (--svaul-drawer-bg, --svaul-drawer-overlay-bg, --svaul-drawer-handle-bg, --svaul-drawer-handle-gap, …).

The library's own CSS lives in the svaul cascade layer, so your styles always win without !important. With Tailwind v4, declare the layer order once:

@layer svaul;
@import "tailwindcss";

scaleBackground note: wrap your page in <div data-svaul-drawer-wrapper> and give it an opaque background. The gap behind the lifted page is painted via setBackgroundColorOnScale (default black) — if the wrapper is transparent the whole page looks black.

Why svaul?

  • Svelte 5 runes-native — built on $state/$derived/$effect, {@attach} attachments and snippets, not stores or $: side-effect chains.
  • Zero runtime dependencies — the portal, focus-trap, scroll-lock, dismiss/Escape, inert background and ARIA are all hand-rolled. (vaul-svelte ships bits-ui; vaul is React-only.)
  • Svelte Native API — a single <Drawer> with named snippets and a headless Drawer class, instead of compound Drawer.Root/Content/… parts.
  • Bug fixes Fixes bugs with both vaul and svelte-vaul: ref-counted scroll-lock & background-color restore that always reverts, topmost-only outside-click for nested drawers, the on-screen-keyboard "drawer shoots off-screen" fix, pixel-snapped snap offsets (no blurry text), a dismiss-blink fix, prefers-reduced-motion honored on the scaled background, and modal actually wired through. And more.

Credits

svaul v1 was inspired by vaul and vaul-svelte. v2 reimagines the motion system but the look is still from vaul. Thanks to both ♥.

License

MIT

About

Svelte 5 port of the amazing Vaul bottom drawer

Topics

Resources

Stars

29 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages