npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

base-ui-vaul

v1.0.0

Published

Base UI implementation of Vaul — an unstyled drawer component for React 19.

Readme

base-ui-vaul

npm version license

base-ui-vaul is the Base UI implementation of Vaul — an unstyled drawer component for React.

Vaul is built on Radix UI Dialog. This package keeps the same composable drawer API (Drawer.Root, Drawer.Content, snap points, drag-to-dismiss, nested drawers, and data-vaul-* styling hooks) while using @base-ui/react for dialog primitives. It targets React 19.

Installation

pnpm add base-ui-vaul @base-ui/react react react-dom
npm install base-ui-vaul @base-ui/react react react-dom
yarn add base-ui-vaul @base-ui/react react react-dom
bun add base-ui-vaul @base-ui/react react react-dom

Import the default styles (or reimplement them with your own CSS):

import "base-ui-vaul/style.css";

Peer dependencies

| Package | Version | | --- | --- | | react | ^19 | | react-dom | ^19 | | @base-ui/react | ^1 |

Quick start

import { Drawer } from "base-ui-vaul";
import "base-ui-vaul/style.css";

export function Example() {
  return (
    <Drawer.Root>
      <Drawer.Trigger>Open drawer</Drawer.Trigger>
      <Drawer.Portal>
        <Drawer.Overlay />
        <Drawer.Content>
          <Drawer.Handle />
          <Drawer.Title>Title</Drawer.Title>
          <Drawer.Description>Description</Drawer.Description>
          <p>Drawer content</p>
        </Drawer.Content>
      </Drawer.Portal>
    </Drawer.Root>
  );
}

Migrating from Vaul

Replace the package import and add @base-ui/react as a peer dependency:

- import { Drawer } from "vaul"
+ import { Drawer } from "base-ui-vaul"
- import "vaul/style.css"
+ import "base-ui-vaul/style.css"

Component names and data-vaul-* attributes match Vaul so existing styles and behavior should carry over. Under the hood, Drawer uses Base UI Dialog (Root, Backdrop, Popup, Portal, Trigger, Close, Title, Description) instead of Radix.

Named exports are also available if you prefer not to use the namespace:

  • Root, Content, Overlay, Handle, Portal, NestedRoot
  • DialogProps, ContentProps, HandleProps

Snap points

import { Drawer } from "base-ui-vaul";
import "base-ui-vaul/style.css";

export function SnapPointsExample() {
  return (
    <Drawer.Root snapPoints={[0.25, 0.5, 0.75]} fadeFromIndex={2}>
      <Drawer.Trigger>Open</Drawer.Trigger>
      <Drawer.Portal>
        <Drawer.Overlay />
        <Drawer.Content>
          <Drawer.Handle />
          {/* content */}
        </Drawer.Content>
      </Drawer.Portal>
    </Drawer.Root>
  );
}

Controlled usage

const [open, setOpen] = React.useState(false);

<Drawer.Root open={open} onOpenChange={setOpen}>
  {/* ... */}
</Drawer.Root>;

API

Drawer namespace

| Part | Description | | --- | --- | | Drawer.Root | Drawer state, drag logic, snap points | | Drawer.Trigger | Opens the drawer (Base UI Dialog.Trigger) | | Drawer.Portal | Portals content (optional container) | | Drawer.Overlay | Backdrop | | Drawer.Content | Draggable panel | | Drawer.Handle | Drag handle; double-tap cycles snap points | | Drawer.Close | Close button | | Drawer.Title / Drawer.Description | Accessibility labels | | Drawer.NestedRoot | Nested drawer inside another |

Common Drawer.Root props

| Prop | Default | Description | | --- | --- | --- | | direction | "bottom" | "top" | "bottom" | "left" | "right" | | dismissible | true | Allow drag / outside / Esc to close | | modal | true | Modal focus trap and outside interaction | | snapPoints | — | Heights as fractions (0.5) or px ("400px") | | fadeFromIndex | last snap point | When overlay fade starts (required if using snapPoints with fade) | | shouldScaleBackground | false | Scale page behind drawer | | handleOnly | false | Only drag via Drawer.Handle | | closeThreshold | 0.25 | Fraction dragged to close | | onDrag / onRelease | — | Drag lifecycle callbacks | | onAnimationEnd | — | Fires when open/close animation completes |

See exported DialogProps in TypeScript for the full list.

Styling

Default styles ship in base-ui-vaul/style.css. Target Vaul-compatible attributes:

  • [data-vaul-drawer]
  • [data-vaul-overlay]
  • [data-vaul-handle]
  • [data-vaul-drawer-direction="bottom"] (and top, left, right)

Opt out of drag on specific elements:

<div data-vaul-no-drag>No drag here</div>

Wrap the page for background scaling:

<div data-vaul-drawer-wrapper>{/* app */}</div>

Background scaling

<Drawer.Root shouldScaleBackground>
  {/* ... */}
</Drawer.Root>

Requires a [data-vaul-drawer-wrapper] ancestor around your main content.

Development

pnpm install
pnpm typecheck
pnpm build

Publishing

pnpm build
npm publish

Credits

License

MIT © nunesunil