{"id":12346,"library":"vaul-vue","title":"Vaul Vue Unstyled Drawer","description":"Vaul Vue is an unstyled, headless drawer component specifically designed for Vue 3 applications, serving as a modern and highly customizable replacement for traditional dialogs and modals, particularly optimized for tablet and mobile devices. It stands at version 0.4.1 and demonstrates an active development cadence with frequent patch releases addressing bug fixes and occasional minor releases introducing new features or significant architectural refactorings. This library is a feature-complete port of Emil Kowalski's original Vaul library, which was built for React, ensuring a mature and well-tested interaction model. Under the hood, Vaul Vue leverages Reka UI's Dialog primitive, providing a robust foundation for accessibility and core interaction logic. Its unstyled nature is a key differentiator, granting developers complete control over the visual presentation to seamlessly integrate with any design system. The headless architecture ensures that essential accessibility features are provided out-of-the-box, without dictating styling. Key features include highly customizable snap points, support for various drag directions, and a comprehensive set of primitives (`DrawerRoot`, `DrawerTrigger`, `DrawerPortal`, `DrawerOverlay`, `DrawerContent`) that enable building bespoke drawer experiences tailored to specific application needs, making it a powerful tool for responsive web design.","status":"active","version":"0.4.1","language":"javascript","source_language":"en","source_url":"https://github.com/Elliot-Alexander/vaul-vue","tags":["javascript","vue","vue3","drawer","dialog","modal","headless","typescript"],"install":[{"cmd":"npm install vaul-vue","lang":"bash","label":"npm"},{"cmd":"yarn add vaul-vue","lang":"bash","label":"yarn"},{"cmd":"pnpm add vaul-vue","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Provides the underlying Dialog primitive for accessibility and interaction logic.","package":"reka-ui","optional":false},{"reason":"Required peer dependency for Vue 3 applications.","package":"vue","optional":false}],"imports":[{"note":"Vaul Vue is an ESM-first library primarily used in Vue 3 projects. CommonJS 'require' is not supported.","wrong":"const { DrawerRoot } = require('vaul-vue')","symbol":"{ DrawerRoot, DrawerTrigger, DrawerPortal, DrawerOverlay, DrawerContent }","correct":"import { DrawerRoot, DrawerTrigger, DrawerPortal, DrawerOverlay, DrawerContent } from 'vaul-vue'"},{"note":"As of v0.4.0, default styles are shipped as a separate CSS file. You must explicitly import this file for basic functionality or provide your own complete styles. Failing to import will result in an unstyled and potentially non-functional drawer.","symbol":"CSS Styles","correct":"import 'vaul-vue/dist/style.css'"}],"quickstart":{"code":"<script setup lang=\"ts\">\nimport { DrawerContent, DrawerOverlay, DrawerPortal, DrawerRoot, DrawerTrigger } from 'vaul-vue'\nimport 'vaul-vue/dist/style.css' // Important: import Vaul Vue's default styles\n</script>\n\n<template>\n  <DrawerRoot :snap-points=\"[0.5, 0.8]\" :open=\"true\"> <!-- Added :open for demonstration -->\n    <DrawerTrigger as-child>\n      <button class=\"px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600\">Open Drawer</button>\n    </DrawerTrigger>\n    <DrawerPortal>\n      <!-- Overlay for background dimming when drawer is open -->\n      <DrawerOverlay class=\"fixed inset-0 bg-black/40 z-40\" />\n      <DrawerContent class=\"bg-white flex flex-col rounded-t-[10px] h-full mt-24 fixed bottom-0 left-0 right-0 max-h-[96%] max-w-md mx-auto z-50\">\n        <div class=\"mx-auto w-12 h-1.5 flex-shrink-0 rounded-full bg-gray-300 my-3\" />\n        <div class=\"flex-1 p-4 overflow-y-auto\">\n          <h2 class=\"text-xl font-semibold text-gray-800 mb-2\">Welcome to Vaul Vue!</h2>\n          <p class=\"text-gray-700 leading-relaxed\">\n            This is an unstyled, headless drawer component for Vue 3. It's designed to be a flexible\n            and accessible replacement for dialogs and modals on mobile and tablet devices.\n            You can drag it up or down to adjust its position or dismiss it.\n            It uses <a href=\"https://www.reka-ui.com/docs/components/dialog\" target=\"_blank\" class=\"text-blue-600 hover:underline\">Reka UI's Dialog primitive</a>\n            under the hood for robust accessibility.\n          </p>\n          <p class=\"text-gray-700 leading-relaxed mt-4\">\n            Feel free to customize all aspects of its appearance with your own CSS or utility classes.\n            The `snap-points` prop allows you to define specific heights where the drawer can rest.\n          </p>\n          <div class=\"mt-8\">\n            <h3 class=\"font-medium text-gray-800 mb-2\">Key Features:</h3>\n            <ul class=\"list-disc list-inside text-gray-700\">\n              <li>Unstyled & Headless</li>\n              <li>Mobile-first interaction</li>\n              <li>Customizable snap points</li>\n              <li>Uses Reka UI for accessibility</li>\n            </ul>\n          </div>\n          <p class=\"text-gray-500 text-sm mt-8\">Drag this drawer down to close it, or click the overlay.</p>\n        </div>\n        <div class=\"border-t border-gray-200 p-4 flex justify-end\">\n          <button class=\"px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600\">Close Drawer</button>\n        </div>\n      </DrawerContent>\n    </DrawerPortal>\n  </DrawerRoot>\n</template>","lang":"typescript","description":"Demonstrates a basic Vaul Vue drawer with snap points, custom styling (using Tailwind-like classes), and a trigger button, including the necessary CSS import."},"warnings":[{"fix":"Review the Reka UI documentation for Dialog primitives and update your component usage accordingly. The public API of Vaul Vue components should mostly remain consistent, but direct primitive usage will need adjustment.","message":"The underlying primitive library for Vaul Vue migrated from Radix Vue to Reka UI. This change occurred in v0.3.0 and may require updating component imports or props if directly interacting with the underlying primitives.","severity":"breaking","affected_versions":">=0.3.0"},{"fix":"Update all CSS selectors and JavaScript code that targets `vaul-*` attributes to use `data-vaul-*` instead (e.g., `[vaul-drawer]` becomes `[data-vaul-drawer]`).","message":"Data attributes used for styling and interaction changed from `[vaul-*]` to `[data-vaul-*]` for better web standards compliance and CSP header compatibility. This affects direct CSS targeting and any manual interaction with these attributes.","severity":"breaking","affected_versions":">=0.4.0"},{"fix":"Add `import 'vaul-vue/dist/style.css'` to your main application entry file or directly within the component where Vaul Vue is used.","message":"As of v0.4.0, default styles are no longer automatically included and must be explicitly imported from `vaul-vue/dist/style.css`. Failing to do so will result in an unstyled and potentially non-functional drawer.","severity":"gotcha","affected_versions":">=0.4.0"},{"fix":"Upgrade to `vaul-vue@0.4.1` or later to resolve these issues.","message":"Before v0.4.1, there were issues where the `<body>` element's styles (e.g., overflow) might persist after the drawer unmounted, and clicking the overlay might not dismiss the drawer as expected.","severity":"gotcha","affected_versions":"<0.4.1"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Add `import 'vaul-vue/dist/style.css'` to your main application file or component.","cause":"The default styles for Vaul Vue need to be explicitly imported as of version 0.4.0.","error":"CSS styles are not applying to my Vaul drawer component."},{"fix":"Update your HTML and CSS to use `data-vaul-*` attributes instead of `vaul-*` (e.g., `data-vaul-drawer` instead of `vaul-drawer`).","cause":"In v0.4.0, data attributes were refactored from `[vaul-*]` to `[data-vaul-*]` for improved compliance and CSP compatibility.","error":"My custom `vaul-*` data attributes are no longer working or applying styles."},{"fix":"Upgrade to `vaul-vue@0.4.1` or a newer version to benefit from the fixes.","cause":"Earlier versions (before 0.4.1) had known bugs related to overlay dismissal and body style persistence.","error":"Clicking on the drawer overlay doesn't close the drawer, or body scrolling is still disabled after closing."},{"fix":"Remove any lingering Radix Vue imports or usage that were previously tied to Vaul Vue. Ensure you are only using the `vaul-vue` components which now internally rely on Reka UI, or follow Reka UI's documentation for direct primitive usage.","cause":"Version 0.3.0 broke compatibility with Radix Vue components by migrating to Reka UI primitives. Your application might still be trying to use Radix Vue components or expecting their API.","error":"TypeError: Cannot read properties of undefined (reading 'setup') or similar errors related to Radix Vue components after upgrading."}],"ecosystem":"npm"}