vaul

repository·main·Indexed 27 days ago

https://github.com/emilkowalski/vaul

A drawer component for React built on top of Radix UI Dialog. It provides accessible, mobile-friendly bottom-sheet functionality with support for snap points, dragging, and multiple directions (top, bottom, left, right). The library includes components for managing state (Root), content containers (Content), overlays (Overlay), and interaction handles (Handle), as well as a usePreventScroll hook to lock background scrolling.

Tokens
1.3K
Snippets
0
Records
13
Agent score
44%

What's inside vaul

  1. Use the Vaul Drawer component

    main

    Vaul provides a drawer component built on top of Radix UI Dialog. It supports snap points, dragging, and various directions (top, bottom, left, right).

    To use it, compose the Root, Overlay, and Content components. You can optionally include a Handle to allow dragging only via a specific element.

  2. Configure usePreventScroll options

    main

    The usePreventScroll hook accepts an optional PreventScrollOptions object:

    • isDisabled (boolean): If true, the scroll lock mechanism is disabled.
    • focusCallback (function): A callback function to be executed (Note: while defined in the interface, implementation details for this specific callback are not explicitly utilized in the provided source logic).
  3. Configure Drawer.Root props

    main

    The Root component controls the drawer's state and behavior. Key props include:

    • snapPoints: An array of numbers (0-100) or pixel strings representing the height/width percentages or values the drawer should snap to. Example: [0.2, 0.5, 0.8] or ['200px', '500px'].
    • activeSnapPoint / setActiveSnapPoint: Controlled state for the current snap point.
    • open / onOpenChange: Controlled state for the drawer's visibility.
    • direction: The axis of movement. Options: 'top' | 'bottom' | 'left' | 'right'. Defaults to 'bottom'.
    • dismissible: If false, prevents closing via clicking outside, pressing Esc, or dragging (unless snap points are used).
    • handleOnly: If true, the drawer can only be dragged using the Drawer.Handle component.
    • modal: If true, prevents interaction with elements outside the drawer. Defaults to true.
    • closeThreshold: A number between 0 and 1 determining how far a user must swipe to close the drawer. Defaults to 0.25.
    • shouldScaleBackground: If true, scales the background content when the drawer is open.
    • snapToSequentialPoint: If true, prevents skipping snap points during high-velocity swipes.
    • repositionInputs: If true, repositions inputs when the keyboard opens to prevent them from being obscured. Defaults to true when snapPoints are defined.
  4. Reference the Drawer component sub-components

    main

    The Drawer object provides access to all necessary components for building a drawer interface:

    • Drawer.Root: The main wrapper that manages the drawer state.
    • Drawer.NestedRoot: Used for nesting drawers within other drawers.
    • Drawer.Content: The container for the drawer's actual content.
    • Drawer.Overlay: The background overlay that appears when the drawer is open.
    • Drawer.Trigger: The element that triggers the drawer to open.
    • Drawer.Portal: Renders content into a portal.
    • Drawer.Handle: The visual handle used to drag or interact with the drawer.
    • Drawer.Close: The component used to close the drawer.
    • Drawer.Title: Accessible title for the drawer.
    • Drawer.Description: Accessible description for the drawer.
  5. Use Drawer.Handle

    main

    The Handle component provides a dedicated area for users to grab and drag the drawer.

    If the Root component has handleOnly={true} set, the drawer will only respond to drag gestures initiated on the Handle. The handle also supports double-tapping to cycle through available snapPoints.

  6. Use Portal to render drawer content in a specific container

    main
    The Portal component renders the drawer content into a different part of the DOM. By default, it uses the container provided by the Drawer context, but you can pass a specific container prop to target a different DOM element.
  7. Prevent background scroll with usePreventScroll

    main

    The usePreventScroll hook prevents scrolling on the document body when mounted and restores it when unmounted. It includes specialized handling for Mobile Safari to prevent page shifting and unwanted scrolling when interacting with inputs or the viewport.

    Use this hook when implementing overlays, drawers, or modals where you want to lock the background content in place.

  8. Check if an element is a text input with isInput

    main

    The isInput function checks if a DOM element is a text-entry field. It returns true if the element is:

    • An HTMLInputElement whose type is not in the nonTextInputTypes set (e.g., it is not a checkbox, radio, range, etc.).
    • An HTMLTextAreaElement.
    • An HTMLElement with isContentEditable set to true.
  9. Use Drawer.Content

    main

    The Content component is the container for the drawer's actual content. It handles the dragging logic, snap point transitions, and keyboard interaction.

    It accepts all standard Radix UI Dialog.Content props. Note that if snapPoints are provided, it will inject a CSS variable --snap-point-height into the element's style.