WUI logo

Drawer

Allows user to open a modal with a special style.

version

5.10.1

install

yarn add @welcome-ui/drawer

usage

import { Drawer } from '@welcome-ui/drawer'

About #

Drawer based on Ariakit dialog with a really nice theme 💅

Usage #

The most basic drawer needs useDrawer(), <Drawer.Trigger /> and <Drawer />. If you don't want a backdrop to be visible, please provide it a withBackdrop prop set to false. Backdrop allows us to have a smooth scroll across all browsers by wrapping the Drawer. This way, the Drawer can be absolutely positioned in the fixed Backdrop wrapper.

Backdrop #

You have to add on <Drawer /> a prop withBackdrop. This adds our backdrop <Drawer.Backdrop /> on the drawer. You can also add a custom wrapper with the property backdrop.

Layout #

We provide basic layout components for your drawer: <Drawer.Title />, <Drawer.Content /> and <Drawer.Footer />. They are all optional. By default, you have a close button <Drawer.Close /> that you can remove by setting the withCloseButton property to false. If you're using <Drawer.Close /> along with <Drawer.Title />, please make sure to position <Drawer.Close /> first in your code for styling purposes.

Placement #

By default the placement of the drawer will be on the right but you can set it to top, bottom, or left.

Size #

By default the size of the drawer will be lg which is set in the theme. We provide 3 different sizes that will adapt according to the position of the Drawer. You can also set a custom size if needed.

Styling #

All the elements can be styled as you see fit, by extending drawer's theme or directly with styled props.

useDrawer #

We use useDialogStore from Ariakit Dialog for the state of the drawer with the animated flag set to true by default.

Pass options to useDrawer:

  • defaultOpen: e.g. const drawer = useDrawer({ defaultOpen: true })

And the hook returns (among other things):

  • useState('open'): whether the drawer is currently open
  • hide: a function to hide the drawer

Properties #

Drawer #
NameType(s)DefaultRequired
placement
"top"
"right"
"bottom"
"left"
right
size
string
lg
withBackdrop
Boolean
false
withCloseButton
Boolean
true
store
DialogStoreFunctions & DisclosureStoreFunctions & Store<DisclosureStoreState> & { useState: UseState<...>; }

Object returned by the [`useDialogStore`](https://ariakit.org/reference/use-dialog-store) hook. If not provided, the closest [`DialogProvider`](https://ariakit.org/reference/dialog-provider) component's context will be used. Otherwise, an internal store will be created.

open
Boolean

Controls the open state of the dialog. This is similar to the [`open`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/open) attribute on native dialog elements. Live examples: - [Dialog with scrollable backdrop](https://ariakit.org/examples/dialog-backdrop-scrollable) - [Dialog with details & summary](https://ariakit.org/examples/dialog-details) - [Warning on Dialog hide](https://ariakit.org/examples/dialog-hide-warning) - [Dialog with Menu](https://ariakit.org/examples/dialog-menu)

onClose
(event: Event) => void

This is an event handler prop triggered when the dialog's `close` event is dispatched. The `close` event is similar to the native dialog [`close`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/close_event) event. The only difference is that this event can be cancelled with `event.preventDefault()`, which will prevent the dialog from hiding. It's important to note that this event only fires when the dialog store's [`open`](https://ariakit.org/reference/use-dialog-store#open) state is set to `false`. If the controlled [`open`](https://ariakit.org/reference/dialog#open) prop value changes, or if the dialog's visibility is altered in any other way (such as unmounting the dialog without adjusting the open state), this event won't be triggered. Live examples: - [Dialog with scrollable backdrop](https://ariakit.org/examples/dialog-backdrop-scrollable) - [Dialog with details & summary](https://ariakit.org/examples/dialog-details) - [Warning on Dialog hide](https://ariakit.org/examples/dialog-hide-warning) - [Dialog with Menu](https://ariakit.org/examples/dialog-menu)

modal
Boolean

Determines whether the dialog is modal. Modal dialogs have distinct states and behaviors: - The [`portal`](https://ariakit.org/reference/dialog#portal) and [`preventBodyScroll`](https://ariakit.org/reference/dialog#preventbodyscroll) props are set to `true`. They can still be manually set to `false`. - A visually hidden dismiss button will be rendered if the [`DialogDismiss`](https://ariakit.org/reference/dialog-dismiss) component hasn't been used. This allows screen reader users to close the dialog. - When the dialog is open, element tree outside it will be disabled. - When using the [`Heading`](https://ariakit.org/reference/heading) or [`DialogHeading`](https://ariakit.org/reference/dialog-heading) components within the dialog, their level will be reset so they start with `h1`. Live examples: - [Dialog with details & summary](https://ariakit.org/examples/dialog-details) - [Form with Select](https://ariakit.org/examples/form-select) - [Context menu](https://ariakit.org/examples/menu-context-menu) - [Responsive Popover](https://ariakit.org/examples/popover-responsive)

true
backdrop
false
true
"abbr"
"address"
"article"
"aside"
"b"
"bdi"
"bdo"
"big"
"caption"
"cite"
"code"
"dd"
"dfn"
"div"
"dt"
"em"
"figcaption"
"figure"
"footer"
"h1"
"h2"
"h3"
"h4"
"h5"
"h6"
"head"
"header"
"hgroup"
"i"
"kbd"
"keygen"
"main"
"mark"
"menu"
"menuitem"
"nav"
"noindex"
"noscript"
"p"
"picture"
"rp"
"rt"
"ruby"
"s"
"samp"
"section"
"small"
"span"
"strong"
"sub"
"summary"
"sup"
"u"
"var"
"wbr"
"webview"
ReactElement<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; }, string | JSXElementConstructor<...>>
ComponentClass<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; }, any>
FunctionComponent<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; }>

Determines whether there will be a backdrop behind the dialog. On modal dialogs, this is `true` by default. Besides a `boolean`, this prop can also be a React component or JSX element that will be rendered as the backdrop. **If a custom component is used, it must accept ref and spread all props to its underlying DOM element**, the same way a native element would. Live examples: - [Animated Dialog](https://ariakit.org/examples/dialog-animated) - [Dialog with scrollable backdrop](https://ariakit.org/examples/dialog-backdrop-scrollable) - [Dialog with Framer Motion](https://ariakit.org/examples/dialog-framer-motion) - [Dialog with Menu](https://ariakit.org/examples/dialog-menu) - [Nested Dialog](https://ariakit.org/examples/dialog-nested) - [Dialog with Next.js App Router](https://ariakit.org/examples/dialog-next-router) @example ```jsx <Dialog backdrop={<div className="backdrop" />} /> ```

backdropProps
Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; }

Props that will be passed to the backdrop element if [`backdrop`](https://ariakit.org/reference/dialog#backdrop) is `true`. @deprecated Use the [`backdrop`](https://ariakit.org/reference/dialog#backdrop) prop instead.

hideOnEscape
false
true
(arg: KeyboardEvent | React.KeyboardEvent<Element>) => boolean

Determines whether the dialog will be hidden when the user presses the Escape key.

true
hideOnInteractOutside
false
true
(arg: Event | SyntheticEvent<Element, Event>) => boolean

Determines whether the dialog will be hidden when the user clicks or focus on an element outside of the dialog. Live examples: - [Selection Popover](https://ariakit.org/examples/popover-selection)

true
getPersistentElements
() => Iterable<Element>

When a dialog is open, the elements outside of it will be disabled so they can't be interacted with if the dialog is modal. For non-modal dialogs, interacting with elements outside of the dialog will close it. With this function, you can return a collection of elements that will be considered part of the dialog and therefore will be excluded from this behavior. Live examples: - [Dialog with React-Toastify](https://ariakit.org/examples/dialog-react-toastify)

preventBodyScroll
Boolean

Determines whether the body scrolling will be prevented when the dialog is shown.

autoFocusOnShow
false
true
(arg: HTMLElement) => boolean

Determines whether an element inside the dialog will receive focus when the dialog is shown. By default, this is usually the first tabbable element in the dialog or the dialog itself. The `initialFocus` prop can be used to set a different element to receive focus. Live examples: - [Warning on Dialog hide](https://ariakit.org/examples/dialog-hide-warning) - [Sliding Menu](https://ariakit.org/examples/menu-slide) - [Selection Popover](https://ariakit.org/examples/popover-selection)

true
autoFocusOnHide
false
true
(arg: HTMLElement) => boolean

Determines whether an element outside of the dialog will be focused when the dialog is hidden if another element hasn't been focused in the action of hiding the dialog (for example, by clicking or tabbing into another tabbable element outside of the dialog). By default, this is usually the disclosure element. The `finalFocus` prop can be used to define a different element to be focused.

true
initialFocus
HTMLElement
RefObject<HTMLElement>

Specifies the element that will receive focus when the dialog is first opened. It can be an `HTMLElement` or a `React.RefObject` with an `HTMLElement`. If [`autoFocusOnShow`](https://ariakit.org/reference/dialog#autofocusonshow) is set to `false`, this prop will have no effect. If left unset, the dialog will attempt to determine the initial focus element in the following order: 1. A [Focusable](https://ariakit.org/components/focusable) element with an [`autoFocus`](https://ariakit.org/reference/focusable#autofocus) prop. 2. The first tabbable element inside the dialog. 3. The first focusable element inside the dialog. 4. The dialog element itself.

finalFocus
HTMLElement
RefObject<HTMLElement>

Determines the element that will receive focus once the dialog is closed, provided that no other element has been focused while the dialog was being hidden (e.g., by clicking or tabbing into another tabbable element outside of the dialog). However, if `autoFocusOnHide` is set to `false`, this prop will have no effect. If left unset, the element that was focused before the dialog was opened will be focused again.

disabled
Boolean

Determines if the element is disabled. This sets the `aria-disabled` attribute accordingly, enabling support for all elements, including those that don't support the native `disabled` attribute. This feature can be combined with the [`accessibleWhenDisabled`](https://ariakit.org/reference/focusable#accessiblewhendisabled) prop to make disabled elements still accessible via keyboard. Live examples: - [Submenu](https://ariakit.org/examples/menu-nested)

false
autoFocus
Boolean

Automatically focuses the element upon mounting, similar to the native `autoFocus` prop. This addresses an issue where the element with the native `autoFocus` attribute might receive focus before React effects are executed. The `autoFocus` prop can also be used with [Focusable](https://ariakit.org/components/focusable) elements within a [Dialog](https://ariakit.org/components/dialog) component, establishing the initial focus as the dialog opens. Live examples: - [Warning on Dialog hide](https://ariakit.org/examples/dialog-hide-warning) - [Dialog with React Router](https://ariakit.org/examples/dialog-react-router) - [Nested Dialog](https://ariakit.org/examples/dialog-nested)

false
focusable
Boolean

Determines if [Focusable](https://ariakit.org/components/focusable) features should be active on non-native focusable elements. **Note**: This prop only turns off the additional features provided by the [Focusable](https://ariakit.org/components/focusable) component. Non-native focusable elements will lose their focusability entirely. However, native focusable elements will retain their inherent focusability, but without added features such as improved [`autoFocus`](https://ariakit.org/reference/focusable#autofocus), [`accessibleWhenDisabled`](https://ariakit.org/reference/focusable#accessiblewhendisabled), [`onFocusVisible`](https://ariakit.org/reference/focusable#onfocusvisible), etc.

true
accessibleWhenDisabled
Boolean

Indicates whether the element should be focusable even when it is [`disabled`](https://ariakit.org/reference/focusable#disabled). This is important when discoverability is a concern. For example: > A toolbar in an editor contains a set of special smart paste functions that are disabled when the clipboard is empty or when the function is not applicable to the current content of the clipboard. It could be helpful to keep the disabled buttons focusable if the ability to discover their functionality is primarily via their presence on the toolbar. Learn more on [Focusability of disabled controls](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#focusabilityofdisabledcontrols).

onFocusVisible
BivariantCallback<(event: SyntheticEvent<Element, Event>) => void>

Custom event handler invoked when the element gains focus through keyboard interaction or a key press occurs while the element is in focus. This is a programmatic equivalent of the `data-focus-visible` attribute. Live examples: - [Custom Checkbox](https://ariakit.org/examples/checkbox-custom)

preserveTabOrder
Boolean

When enabled, `preserveTabOrder` will keep the DOM element's tab order the same as the order in which the underlying [`Portal`](https://ariakit.org/reference/portal) component was mounted in the React tree.

false
portalRef
RefCallback<HTMLElement>
MutableRefObject<HTMLElement>

`portalRef` is similar to `ref` but is scoped to the portal node. It's useful when you need to be informed when the portal element is appended to the DOM or removed from the DOM. @example ```jsx const [portalElement, setPortalElement] = useState(null); <Portal portalRef={setPortalElement} /> ```

portal
Boolean

Determines whether the element should be rendered as a React Portal.

true
portalElement
HTMLElement
(element: HTMLElement) => HTMLElement

An HTML element or a memoized callback function that returns an HTML element to be used as the portal element. By default, the portal element will be a `div` element appended to the `document.body`. @example ```jsx const [portal, setPortal] = useState(null); <> <Portal portalElement={portal} /> <div ref={setPortal} /> </> ``` @example ```jsx const getPortalElement = useCallback(() => { const div = document.createElement("div"); const portalRoot = document.getElementById("portal-root"); portalRoot.appendChild(div); return div; }, []); <Portal portalElement={getPortalElement} /> ```

HTMLDivElement
alwaysVisible
Boolean

Determines whether the content element should remain visible even when the `open` state is `false`. If this prop is set to `true`, the `hidden` prop and the `display: none` style will not be applied, unless explicitly set otherwise. This prop is particularly useful when using third-party animation libraries such as Framer Motion or React Spring, where the element needs to be visible for exit animations to work. Live examples: - [Dialog with Framer Motion](https://ariakit.org/examples/dialog-framer-motion) - [Menu with Framer Motion](https://ariakit.org/examples/menu-framer-motion) - [Tooltip with Framer Motion](https://ariakit.org/examples/tooltip-framer-motion) - [Dialog with details & summary](https://ariakit.org/examples/dialog-details)

false
unmountOnHide
Boolean

When set to `true`, the content element will be unmounted and removed from the DOM when it's hidden. Live examples: - [Combobox with links](https://ariakit.org/examples/combobox-links) - [Textarea with inline Combobox](https://ariakit.org/examples/combobox-textarea) - [Standalone Popover](https://ariakit.org/examples/popover-standalone) - [Animated Select](https://ariakit.org/examples/select-animated) - [Multi-Select](https://ariakit.org/examples/select-multiple)

false

Packages #

Dependencies #
Peer dependencies #

Previous

Toast

Next

Modal