Files
Basilosaurusrex f027651f9b main repo
2025-11-24 18:09:40 +01:00

182 lines
7.3 KiB
Markdown

https://github.com/emilkowalski/vaul/assets/36730035/fdf8c5e8-ade8-433b-8bb0-4ce10e722516
Vaul is an unstyled drawer component for React that can be used as a Dialog replacement on tablet and mobile devices. You can read about why and how it was built [here](https://emilkowal.ski/ui/building-a-drawer-component).
## Usage
To start using the library, install it in your project:,
```bash
npm install vaul
```
Use the drawer in your app.
```jsx
import { Drawer } from 'vaul';
function MyComponent() {
return (
<Drawer.Root>
<Drawer.Trigger>Open</Drawer.Trigger>
<Drawer.Portal>
<Drawer.Content>
<p>Content</p>
</Drawer.Content>
<Drawer.Overlay />
</Drawer.Portal>
</Drawer.Root>
);
}
```
## Examples
Play around with the examples on codesandbox:
- [With scaled background](https://codesandbox.io/p/sandbox/drawer-with-scale-g24vvh?file=%2Fapp%2Fmy-drawer.tsx%3A1%2C1)
- [Without scaled background](https://codesandbox.io/p/sandbox/drawer-with-scale-forked-nx2glp?file=%2Fapp%2Fmy-drawer.tsx%3A4%2C1)
- [With snap points](https://codesandbox.io/p/sandbox/drawer-non-dismissable-forked-jchtff?file=/app/my-drawer.tsx:1,1)
- [Scrollable with inputs](https://codesandbox.io/p/sandbox/drawer-with-scale-forked-73f8jw?file=%2Fapp%2Fmy-drawer.tsx%3A1%2C1)
- [Drawer from right instead of bottom](https://codesandbox.io/p/devbox/drawer-direction-right-n338ml?file=%2Fapp%2Fmy-drawer.tsx%3A47%2C2)
- [Nested drawers](https://codesandbox.io/p/sandbox/drawer-non-dismissable-forked-5z2r3j?file=%2Fapp%2Fmy-drawer.tsx%3A49%2C16-49%2C246)
- [Non-dismissible](https://codesandbox.io/p/sandbox/drawer-without-scale-forked-kxh9j5?file=%2Fapp%2Fmy-drawer.tsx%3A1%2C1)
- [Non-draggable element](https://codesandbox.io/p/devbox/drawer-with-scale-forked-hwtfws?file=%2Fapp%2Fmy-drawer.tsx%3A42%2C37)
## API Reference
### Root
Contains all parts of a dialog. Use `shouldScaleBackground` to enable background scaling, it requires an element with `[data-vaul-drawer-wrapper]` data attribute to scale its background.
Can be controlled with the `value` and `onOpenChange` props. Can be opened by default via the `open` prop.
Additional props:
`closeThreshold`: Number between 0 and 1 that determines when the drawer should be closed. Example: threshold of 0.5 would close the drawer if the user swiped for 50% of the height of the drawer or more.
`scrollLockTimeout`: Duration for which the drawer is not draggable after scrolling content inside of the drawer. Defaults to 500ms.
`snapPoints`: Array of numbers from 0 to 100 that corresponds to % of the screen a given snap point should take up. Should go from least visible. Example `[0.2, 0.5, 0.8]`. You can also use px values, which doesn't take screen height into account.
`fadeFromIndex`: Index of a `snapPoint` from which the overlay fade should be applied. Defaults to the last snap point.
`modal`: When `false` it allows to interact with elements outside of the drawer without closing it. Defaults to `true`.
`direction`: Direction of the drawer. Can be `top` or `bottom`, `left`, `right`. Defaults to `bottom`.
`repositionInputs`: When `true` Vaul will reposition inputs rather than scroll then into view if the keyboard is in the way. Setting it to `false` will fall back to the default browser behavior.
`noBodyStyles`: When `true` the `body` doesn't get any styles assigned from Vaul.
`handleOnly`: When `true` only allows the drawer to be dragged by the `<Drawer.Handle />` component. Defaults to `false`.
`setBackgroundColorOnScale`: When `false` we don't change body's background color when the drawer is open. `true` by default.
`defaultOpen`: Opened by default, still reacts to `open` state changes.
`dismissible`: When `false` dragging, clicking outside, pressing esc, etc. will not close the drawer. Use this in comination with the `open` prop, otherwise you won't be able to open/close the drawer.
`snapToSequentialPoint`: Disabled velocity based swiping for snap points. This means that a snap point won't be skipped even if the velocity is high enough. Useful if each snap point in a drawer is equally important.
`onAnimationEnd`: Gets triggered after the open or close animation ends, it receives an `open` argument with the `open` state of the drawer by the time the function was triggered. Useful to revert any state changes for example.
`[data-vaul-no-drag]`: When interacting with an element with this data attribute, the drawer won't be dragged.
### Controlled Drawer
Drawer can be controlled programmatically by providing the `open` prop. If you want to react to open state changes from within the Drawer use the `onOpenChange` prop, this will allow you to provide your own open state while still closing the drawer when the escape key is pressed for example.
```
const [open, setOpen] = React.useState(false);
// ...
<Drawer.Root open={open} onOpenChange={setOpen}>
// ...
</Drawer.Root>
```
### Custom Container
Customize the element that your drawer portals into. By default, drawer will be appended to `document.body`.
```tsx
import React from 'react';
import { Drawer } from 'vaul';
export default () => {
const [container, setContainer] = React.useState(null);
return (
<div>
<Drawer.Root container={container}>
<Drawer.Trigger />
<Drawer.Portal>
<Drawer.Overlay />
<Drawer.Content>...</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
// Drawer will be rendered inside this div.
<div ref={setContainer} />
</div>
);
};
```
### Handle
A drag hint (also known as grabber). Shows people that they can drag the drawer; they can also tap it to cycle through the snap points, and double tap quickly to close the drawer.
```jsx
import { Drawer } from 'vaul';
function MyComponent() {
return (
<Drawer.Root>
<Drawer.Trigger>Open</Drawer.Trigger>
<Drawer.Portal>
<Drawer.Content>
<Drawer.Handle />
<p>Content</p>
</Drawer.Content>
<Drawer.Overlay />
</Drawer.Portal>
</Drawer.Root>
);
}
```
### Trigger
The button that opens the dialog. [Props](https://www.radix-ui.com/docs/primitives/components/dialog#trigger).
### Content
Content that should be rendered in the drawer. [Props](https://www.radix-ui.com/docs/primitives/components/dialog#content).
### Overlay
A layer that covers the inert portion of the view when the dialog is open. [Props](https://www.radix-ui.com/docs/primitives/components/dialog#overlay).
### Title
An accessible title to be announced when the dialog is opened. [Props](https://www.radix-ui.com/docs/primitives/components/dialog#title).
### Description
An optional accessible description to be announced when the dialog is opened. [Props](https://www.radix-ui.com/docs/primitives/components/dialog#description).
### Close
The button that closes the dialog. [Props](https://www.radix-ui.com/docs/primitives/components/dialog#close).
### Portal
Portals your drawer into the body.
### CSS File
CSS in this library is inserted by JavaScript into `<head>` element by default. If you're having issue with it such as [CSP restriction](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src), you can use `vaul/style.css` CSS as a workaround to apply the styles.
> Note: You don't need to import it unless the default inline styles is blocked by CSP.