Powerful and customizable React drawer components built for modern applications and websites. These drawers are built using React Aria and styled with Tailwind CSS.
Installation
You can add this drawer component using our CLI or manually:
npx untitledui@latest add slideout-menu
Drawers examples
Below are examples and variations of this drawers component:
API reference
Import the parts and assemble them:
import { Dialog, Modal, ModalOverlay, SlideoutMenu } from "@/components/application/slideout-menus/slideout-menu"; <SlideoutMenu> <SlideoutMenu.Header /> <SlideoutMenu.Content /> <SlideoutMenu.Footer /> </SlideoutMenu> <ModalOverlay> <Modal> <Dialog /> </Modal> </ModalOverlay>
Dialog
Renders React Aria’s Dialog — all of its props are supported.
Styling (4)
Accessibility (5)
Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.
Modal
Renders React Aria’s Modal — all of its props are supported.
Styling (5)
Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.
ModalOverlay
Renders React Aria’s ModalOverlay — all of its props are supported.
Styling (5)
Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.
FAQs
Please refer to our frequently asked questions page for more.
The drawer is exported as SlideoutMenu and is built on React Aria's modal primitives, so it takes the same open-state props. For a controlled drawer, pass isOpen and onOpenChange; for an uncontrolled one, wrap a trigger button and the drawer in SlideoutMenu.Trigger (React Aria's DialogTrigger) and let it manage state. Add isDismissable to close the drawer when the user clicks the overlay.
SlideoutMenu is a compound component with SlideoutMenu.Header for the title area, SlideoutMenu.Content for the scrollable body, SlideoutMenu.Footer for pinned actions, and SlideoutMenu.Trigger for the uncontrolled pattern. The ModalOverlay, Modal, and Dialog pieces it composes are exported from the same file if you need to assemble a custom layout.
SlideoutMenu.Header always renders a small CloseButton in its top-right corner, but it only does something when you pass onClose, for example onClose={() => setIsOpen(false)} or the close function from the drawer's render-function children. Everything you pass as children renders beneath it, so a featured icon, title and supporting text all sit in the header.
Pass a render function as the drawer's children instead of elements. It receives the React Aria modal render props plus a close function: <SlideoutMenu>{({ close }) => <Button onClick={close}>Cancel</Button>}</SlideoutMenu>. This is handy for footer actions that need to dismiss the drawer without lifting state.
Yes. The panel defaults to w-full max-w-100, sits flush against the right edge for the full viewport height, and both className and dialogClassName are merged with the built-in classes — className targets the overlay and sliding panel, while dialogClassName targets the inner dialog (the examples use dialogClassName="gap-0" to remove the default spacing between header, content, and footer).
It slides in from the right. The panel animates with slide-in-from-right over 300ms on enter and slide-out-to-right over 500ms on exit, while the translucent overlay behind it fades in and out over the same intervals.
It is built on React Aria's Modal and Dialog, so focus is trapped inside the panel while it is open, focus returns to the trigger on close, and pressing Escape dismisses it. Set isKeyboardDismissDisabled to opt out. The dialog renders with role="dialog" and a default aria-label, and SlideoutMenu.Content renders with role="main" by default, which you can override with the role prop.