### Vaul Nested Drawer Example Source: https://context7.com/enderh3art/vaul/llms.txt Demonstrates how to implement nested drawers using Vaul. The example shows a parent drawer containing a trigger for a nested drawer, utilizing Drawer.NestedRoot to manage the hierarchy and interactions between the drawers. ```tsx function NestedExample() { return ( Open {/* Use NestedRoot for nested drawers */} Open Nested Nested content ); } ``` -------------------------------- ### Run Development Server (npm, yarn, pnpm) Source: https://github.com/enderh3art/vaul/blob/main/test/README.md Commands to start the Next.js development server using different package managers. These commands initiate the local development environment, allowing for real-time updates as code is edited. No specific input or output is detailed, but it opens the application at http://localhost:3000. ```bash npm run dev ``` ```bash yarn dev ``` ```bash pnpm dev ``` -------------------------------- ### Vaul Drawer Component API Source: https://context7.com/enderh3art/vaul/llms.txt This section details the props available for the root Drawer component and its sub-components, along with example usage for a complete drawer setup and nested drawers. ```APIDOC ## Drawer.Root Props ### Description The root component for the Vaul drawer, controlling its state and behavior. ### Method N/A (Component Props) ### Endpoint N/A ### Parameters #### Props - **open** (boolean) - Optional - Controls the open/closed state of the drawer (controlled mode). - **defaultOpen** (boolean) - Optional - Sets the initial open/closed state of the drawer (uncontrolled mode). - **onOpenChange** (function) - Optional - Callback function triggered when the open state changes. - **onClose** (function) - Optional - Callback function triggered when the drawer is closed. - **onAnimationEnd** (function(open: boolean)) - Optional - Callback function triggered when the drawer animation ends. - **snapPoints** (Array) - Optional - Defines the snap points for the drawer's height or position. - **activeSnapPoint** (number | string | null) - Optional - The currently active snap point. - **setActiveSnapPoint** (function(snapPoint: number | string | null)) - Optional - Function to programmatically set the active snap point. - **fadeFromIndex** (number) - Optional - Index from which the overlay fade animation starts. - **snapToSequentialPoint** (boolean) - Optional - If true, snapping will move to the next/previous snap point. - **onDrag** (function(event: React.PointerEvent, percentageDragged: number)) - Optional - Callback function during drag, returning the drag event and percentage dragged. - **onRelease** (function(event: React.PointerEvent, open: boolean)) - Optional - Callback function on drag release, returning the event and the drawer's open state. - **closeThreshold** (number) - Optional - The drag threshold (0 to 1) for closing the drawer. Defaults to 0.25. - **dismissible** (boolean) - Optional - Whether the drawer can be dismissed by dragging down. Defaults to true. - **handleOnly** (boolean) - Optional - If true, only the handle can be used to drag the drawer. Defaults to false. - **direction** ('top' | 'bottom' | 'left' | 'right') - Optional - The direction from which the drawer opens. Defaults to 'bottom'. - **shouldScaleBackground** (boolean) - Optional - If true, the background content will scale when the drawer opens. - **setBackgroundColorOnScale** (boolean) - Optional - If true, the background will have a color when scaled. Defaults to true. - **modal** (boolean) - Optional - If true, the drawer will be a modal. Defaults to true. - **nested** (boolean) - Optional - If true, allows nested drawers. - **noBodyStyles** (boolean) - Optional - If true, disables default body scrolling prevention. - **disablePreventScroll** (boolean) - Optional - If true, disables scrolling prevention on the body. Defaults to false. - **repositionInputs** (boolean) - Optional - Repositions input elements when the drawer is open. Defaults to true when snapPoints are defined. - **preventScrollRestoration** (boolean) - Optional - Prevents scroll position restoration when the drawer opens/closes. - **autoFocus** (boolean) - Optional - Automatically focuses the first focusable element within the drawer. - **scrollLockTimeout** (number) - Optional - Timeout in ms for scroll lock. Defaults to 500ms. - **container** (HTMLElement | null) - Optional - The container element for the drawer portal. Defaults to `document.body`. - **fixed** (boolean) - Optional - If true, the drawer will be fixed. ### Request Example ```tsx console.log(open)} snapPoints={[0.5, 1]} closeThreshold={0.25} shouldScaleBackground={true} direction="bottom" > {/* Drawer content */} ``` ### Response N/A (Component Props) #### Success Response (N/A) N/A #### Response Example N/A --- ## Drawer.Trigger Props ### Description An element that triggers the opening or closing of the drawer. ### Method N/A (Component Props) ### Endpoint N/A ### Parameters #### Props - **asChild** (boolean) - Optional - If true, renders the child element directly instead of a `button`. ### Request Example ```tsx ``` ### Response N/A (Component Props) #### Success Response (N/A) N/A #### Response Example N/A --- ## Drawer.Portal Props ### Description Used to render the drawer's children into a specified DOM node, similar to React Portals. ### Method N/A (Component Props) ### Endpoint N/A ### Parameters #### Props - **container** (HTMLElement | null) - Optional - The DOM node to render the portal into. Defaults to `document.body`. ### Request Example ```tsx {/* Drawer content */} ``` ### Response N/A (Component Props) #### Success Response (N/A) N/A #### Response Example N/A --- ## Drawer.Overlay Props ### Description A background overlay that appears when the drawer is open, typically with an opacity animation. ### Method N/A (Component Props) ### Endpoint N/A ### Parameters #### Props - **className** (string) - Optional - Tailwind CSS classes for styling the overlay. ### Request Example ```tsx ``` ### Response N/A (Component Props) #### Success Response (N/A) N/A #### Response Example N/A --- ## Drawer.Content Props ### Description The main container for the drawer's content. ### Method N/A (Component Props) ### Endpoint N/A ### Parameters #### Props - **className** (string) - Optional - Tailwind CSS classes for styling the content. ### Request Example ```tsx {/* Drawer content */} ``` ### Response N/A (Component Props) #### Success Response (N/A) N/A #### Response Example N/A --- ## Drawer.Handle Props ### Description An optional drag handle for the drawer, typically used for cycling through snap points. ### Method N/A (Component Props) ### Endpoint N/A ### Parameters #### Props - **preventCycle** (boolean) - Optional - If true, prevents the handle from cycling through snap points on click. ### Request Example ```tsx ``` ### Response N/A (Component Props) #### Success Response (N/A) N/A #### Response Example N/A --- ## Drawer.Title Props ### Description Provides an accessible title for the drawer content, often used by screen readers. ### Method N/A (Component Props) ### Endpoint N/A ### Parameters #### Props None specific to Drawer.Title, inherits from underlying HTML element (e.g., `h2`). ### Request Example ```tsx Drawer Title ``` ### Response N/A (Component Props) #### Success Response (N/A) N/A #### Response Example N/A --- ## Drawer.Description Props ### Description Provides an accessible description for the drawer content, often used by screen readers. ### Method N/A (Component Props) ### Endpoint N/A ### Parameters #### Props None specific to Drawer.Description, inherits from underlying HTML element (e.g., `p`). ### Request Example ```tsx Drawer description ``` ### Response N/A (Component Props) #### Success Response (N/A) N/A #### Response Example N/A --- ## Drawer.Close Props ### Description A button or element that, when clicked, closes the drawer. ### Method N/A (Component Props) ### Endpoint N/A ### Parameters #### Props - **asChild** (boolean) - Optional - If true, renders the child element directly instead of a `button`. ### Request Example ```tsx ``` ### Response N/A (Component Props) #### Success Response (N/A) N/A #### Response Example N/A --- ## Drawer.NestedRoot Props ### Description Component used to enable nested drawer functionality within another drawer. ### Method N/A (Component Props) ### Endpoint N/A ### Parameters #### Props Inherits all props from `Drawer.Root`. ### Request Example ```tsx {/* Nested drawer content */} ``` ### Response N/A (Component Props) #### Success Response (N/A) N/A #### Response Example N/A ``` -------------------------------- ### Vaul Drawer Component API and Example Source: https://context7.com/enderh3art/vaul/llms.txt Defines the TypeScript interface for the Drawer.Root component props in Vaul, including properties for managing open state, snap points, drag behavior, direction, visual effects, and behavior. Includes a complete example demonstrating how to use various Vaul components like Drawer.Trigger, Drawer.Portal, Drawer.Overlay, Drawer.Content, Drawer.Handle, Drawer.Title, Drawer.Description, and Drawer.Close. ```tsx import { Drawer } from 'vaul'; import type { DrawerDirection } from 'vaul/src/types'; // Root component props interface DrawerRootProps { open?: boolean; defaultOpen?: boolean; onOpenChange?: (open: boolean) => void; onClose?: () => void; onAnimationEnd?: (open: boolean) => void; // Snap points snapPoints?: (number | string)[]; activeSnapPoint?: number | string | null; setActiveSnapPoint?: (snapPoint: number | string | null) => void; fadeFromIndex?: number; snapToSequentialPoint?: boolean; // Drag behavior onDrag?: (event: React.PointerEvent, percentageDragged: number) => void; onRelease?: (event: React.PointerEvent, open: boolean) => void; closeThreshold?: number; // Default: 0.25 dismissible?: boolean; // Default: true handleOnly?: boolean; // Default: false // Direction direction?: 'top' | 'bottom' | 'left' | 'right'; // Default: 'bottom' // Visual effects shouldScaleBackground?: boolean; setBackgroundColorOnScale?: boolean; // Default: true // Behavior modal?: boolean; // Default: true nested?: boolean; noBodyStyles?: boolean; disablePreventScroll?: boolean; // Default: false repositionInputs?: boolean; // Default: true when snapPoints defined preventScrollRestoration?: boolean; autoFocus?: boolean; // Timing scrollLockTimeout?: number; // Default: 500ms // Container container?: HTMLElement | null; fixed?: boolean; } // Complete example with all components function CompleteDrawerExample() { return ( console.log(open)} snapPoints={[0.5, 1]} closeThreshold={0.25} shouldScaleBackground={true} direction="bottom" > {/* Trigger: Button that opens the drawer */} {/* Portal: Renders children in document.body or custom container */} {/* Overlay: Background overlay with opacity animation */} {/* Content: Main drawer container */} {/* Handle: Optional drag handle (for cycling snap points on click) */} {/* Title: Accessible title for screen readers */} Drawer Title {/* Description: Accessible description */} Drawer description {/* Close: Button to close drawer */} ); } ``` -------------------------------- ### Configure Drawer Direction (React/TypeScript) Source: https://context7.com/enderh3art/vaul/llms.txt Shows how to create drawers that slide in from different screen edges (top, bottom, left, right). It uses the `direction` prop to control the sliding behavior and `shouldScaleBackground` for visual effects. The example dynamically applies CSS classes based on the selected direction. ```tsx import { useState } from 'react'; import { Drawer } from 'vaul'; import type { DrawerDirection } from 'vaul/src/types'; function DirectionalDrawer() { const [direction, setDirection] = useState('bottom'); const getContentClasses = (dir: DrawerDirection) => { const base = 'bg-white flex fixed p-6'; const directionClasses = { bottom: 'rounded-t-[10px] flex-col h-[50%] bottom-0 left-0 right-0', top: 'rounded-b-[10px] flex-col h-[50%] top-0 left-0 right-0', left: 'rounded-r-[10px] flex-row w-[50%] left-0 top-0 bottom-0', right: 'rounded-l-[10px] flex-row w-[50%] right-0 top-0 bottom-0', }; return `${base} ${directionClasses[dir]}`; }; return (
Drawer from {direction}

This drawer slides in from the {direction} edge.

); } ``` -------------------------------- ### Render Drawer Within a Specific Container Element Source: https://context7.com/enderh3art/vaul/llms.txt This example shows how to use the `container` prop on `Drawer.Root` and `Drawer.Portal` to render the drawer within a specified DOM element instead of the default viewport. This is useful for isolating the drawer's DOM tree or for managing its positioning within a specific layout. The `containerRef` from `useRef` is used to reference the target DOM element. ```tsx import { useRef } from 'react'; import { Drawer } from 'vaul'; function CustomContainerDrawer() { const containerRef = useRef(null); return (

Page Content

{/* Custom container for the drawer */}

The drawer will be contained within this blue border.

Contained Drawer

This drawer is constrained to its parent container instead of the entire viewport.

); } ``` -------------------------------- ### Configure Multi-Height Drawer with Snap Points (React/TypeScript) Source: https://context7.com/enderh3art/vaul/llms.txt Demonstrates creating a drawer with multiple snap points, allowing it to rest at different heights (e.g., 0%, 50%, 100% of screen height). It uses `snapPoints`, `activeSnapPoint`, and `setActiveSnapPoint` props for control. The `fadeFromIndex` prop manages overlay fading behavior. ```tsx import { useState } from 'react'; import { Drawer } from 'vaul'; function SnapPointsDrawer() { const snapPoints = [0, 0.5, 1]; // 0%, 50%, 100% of screen height // Can also use pixel values: ['148px', '355px', 1] const [snap, setSnap] = useState(snapPoints[1]); const activeSnapIndex = snapPoints.indexOf(snap as number); return (
Resizable Drawer

Active snap point: {activeSnapIndex}

Drag to resize between snap points: 0%, 50%, and 100%

{[0, 1, 2].map(i => ( ))}
); } ``` -------------------------------- ### Basic Drawer Implementation in React (TSX) Source: https://context7.com/enderh3art/vaul/llms.txt Demonstrates the basic implementation of a Vaul drawer with a trigger button and an overlay. It utilizes Drawer.Root, Drawer.Trigger, Drawer.Portal, Drawer.Overlay, and Drawer.Content components for a functional drawer. Styling is applied using Tailwind CSS classes. ```tsx import { Drawer } from 'vaul'; function BasicDrawer() { return (
Drawer Title This is a basic drawer component with gesture support.

Drag the handle or swipe down to close the drawer.

); } ``` -------------------------------- ### Implement Nested Drawers in React Source: https://context7.com/enderh3art/vaul/llms.txt Demonstrates how to create drawers within drawers using Vaul's Drawer.NestedRoot component. This allows for hierarchical UI elements where parent drawers scale automatically. It requires the 'vaul' library. ```tsx import { Drawer } from 'vaul'; function NestedDrawersExample() { return (
First Drawer

This is the outer drawer. You can open another drawer inside.

{/* Nested drawer using NestedRoot */} Open Second Drawer
Nested Drawer

This drawer is nested inside the first one. The parent drawer scales automatically.

); } ``` -------------------------------- ### Handle Drawer Animation Completion with Callbacks Source: https://context7.com/enderh3art/vaul/llms.txt This snippet demonstrates how to use the `onAnimationEnd` and `onOpenChange` callbacks of the Vaul Drawer component to log animation events. It helps in understanding when the drawer's opening or closing animation finishes, and when its state changes. The `onAnimationEnd` callback is particularly useful for performing actions after the animation is complete, such as cleaning up state when the drawer closes. ```tsx import { useState } from 'react'; import { Drawer } from 'vaul'; function AnimationCallbacksDrawer() { const [animationLog, setAnimationLog] = useState([]); const handleAnimationEnd = (open: boolean) => { const timestamp = new Date().toLocaleTimeString(); const message = `${timestamp}: Animation ended - drawer is ${open ? 'open' : 'closed'}`; setAnimationLog(prev => [...prev, message].slice(-5)); if (!open) { console.log('Drawer closed animation complete - safe to clean up state'); } }; const handleOpenChange = (open: boolean) => { const timestamp = new Date().toLocaleTimeString(); setAnimationLog(prev => [...prev, `${timestamp}: State changed to ${open ? 'open' : 'closed'}`].slice(-5)); }; return (

Animation Log:

{animationLog.map((log, i) => (

{log}

))}
Animation Callbacks

Watch the log above to see when animations complete.

); } ``` -------------------------------- ### Track Drawer Drag Events with React Callbacks Source: https://context7.com/enderh3art/vaul/llms.txt Shows how to use `onDrag` and `onRelease` callbacks in Vaul Drawer to track user interaction. The `onDrag` callback provides the drag percentage, while `onRelease` indicates whether the drawer was released in an open or closed state. This is useful for implementing custom animations or logic based on drag gestures. ```tsx import { useState } from 'react'; import { Drawer } from 'vaul'; function DragCallbacksDrawer() { const [dragPercentage, setDragPercentage] = useState(0); const [dragStatus, setDragStatus] = useState('idle'); const handleDrag = (event: React.PointerEvent, percentage: number) => { setDragPercentage(Math.round(percentage * 100)); setDragStatus('dragging'); }; const handleRelease = (event: React.PointerEvent, open: boolean) => { setDragStatus(open ? 'released-open' : 'released-closed'); console.log('Drawer released:', { open, dragPercentage }); // Reset after animation setTimeout(() => { setDragStatus('idle'); setDragPercentage(0); }, 500); }; return (
Drag Tracking

Status: {dragStatus}

Dragged: {dragPercentage}%

Try dragging the drawer and watch the percentage change. Close threshold is set to 30%.

); } ``` -------------------------------- ### Controlled Drawer State Management in React (TSX) Source: https://context7.com/enderh3art/vaul/llms.txt Shows how to manage the open/close state of a Vaul drawer externally using React's useState hook and callbacks like onOpenChange and onClose. This allows for programmatic control over the drawer's visibility and reaction to state changes. ```tsx import { useState } from 'react'; import { Drawer } from 'vaul'; function ControlledDrawer() { const [open, setOpen] = useState(false); const handleOpenChange = (newOpen: boolean) => { console.log('Drawer state changed:', newOpen); setOpen(newOpen); }; const handleClose = () => { console.log('Drawer closed via callback'); }; return (
Controlled Drawer

Current state: {open ? 'Open' : 'Closed'}

); } ``` -------------------------------- ### Create Non-Dismissible Drawer with React Source: https://context7.com/enderh3art/vaul/llms.txt Demonstrates how to create a Vaul Drawer that cannot be closed by swiping down or clicking the overlay. It uses the `dismissible={false}` prop on `Drawer.Root` and a dedicated close button within the drawer content. This pattern is useful for forms or critical information that must be explicitly dismissed by the user. ```tsx import { useState } from 'react'; import { Drawer } from 'vaul'; function NonDismissibleDrawer() { const [open, setOpen] = useState(false); return (
Non-Dismissible Drawer

This drawer cannot be dismissed by swiping down or clicking the overlay. You must use the close button.

); } ``` -------------------------------- ### Create Non-Modal Drawer in React Source: https://context7.com/enderh3art/vaul/llms.txt Illustrates how to configure a Vaul Drawer to operate in non-modal mode using `modal={false}`. In this mode, the drawer does not block interaction with the background content, and there is no overlay. This is suitable for less intrusive UI elements or when users need to continue interacting with the underlying page while the drawer is open. ```tsx import { Drawer } from 'vaul'; function NonModalDrawer() { return (

Background Content

{/* No overlay in non-modal mode */}
Non-Modal Drawer

This drawer allows interaction with background content. There's no overlay, and clicking outside won't close it.

); } ``` -------------------------------- ### Add Background Scaling Effect to Vaul Drawer in React Source: https://context7.com/enderh3art/vaul/llms.txt Implements a visual effect where the background content scales down when the drawer opens, mimicking iOS sheet behavior. This utilizes the `shouldScaleBackground` and `setBackgroundColorOnScale` props of the Drawer.Root. It requires the 'vaul' library. ```tsx import { Drawer } from 'vaul'; function ScaledBackgroundDrawer() { return (

Page Content

This content will scale down when the drawer opens.

Scaled Background

Notice how the background content scales and transforms when this drawer opens, creating a depth effect similar to iOS sheets.

); } ``` -------------------------------- ### Restrict Vaul Drawer Dragging to Handle in React Source: https://context7.com/enderh3art/vaul/llms.txt Configures a Vaul drawer so that it can only be dragged using a specific handle element, preventing the content area from initiating a drag. This is achieved using the `handleOnly` prop on Drawer.Root. It requires the 'vaul' library. ```tsx import { Drawer } from 'vaul'; function HandleOnlyDrawer() { return (
{/* Only this handle can drag the drawer */} Handle-Only Dragging

This drawer can only be dragged via the handle above. The content area is not draggable.