Drawer Component
The Drawer component creates sliding panels that appear from any screen edge. Perfect for sidebars, mobile menus, settings panels, and more. Supports both structured layouts with sub-components and fully custom headless rendering.
Import Component From Library
1import {
2 Drawer,
3 DrawerBody,
4 DrawerButton,
5 DrawerContent,
6 DrawerFooter,
7 DrawerHeader,
8 DrawerTriggerButton
9} from "@neuctra/ui";Basic Usage Code
Start with a simple drawer. The component provides sliding panels from any screen edge with customizable content and positioning.
1import { useState } from 'react';
2import {
3 Drawer,
4 DrawerContent,
5 DrawerHeader,
6 DrawerBody,
7 DrawerFooter,
8 Button
9} from '@neuctra/ui';
10
11function BasicExample() {
12 const [open, setOpen] = useState(false);
13
14 return (
15 <>
16 <Button onClick={() => setOpen(true)}>
17 Open Drawer
18 </Button>
19
20 <Drawer isOpen={open} onClose={() => setOpen(false)}>
21 <DrawerContent>
22 <DrawerHeader title="Drawer Title" onClose={() => setOpen(false)} />
23 <DrawerBody>
24 <p>Drawer content goes here</p>
25 </DrawerBody>
26 <DrawerFooter>
27 <Button onClick={() => setOpen(false)}>
28 Close
29 </Button>
30 </DrawerFooter>
31 </DrawerContent>
32 </Drawer>
33 </>
34 );
35}Basic Example
Headless Mode (renderContent)
Sub-Components
Use these helper components to build structured drawer layouts:
Drawer Props
| Prop | Type | Default | Description |
|---|---|---|---|
| isOpen | boolean | — | Controls drawer visibility |
| onClose | () => void | — | Called when drawer closes |
| children | ReactNode | — | Drawer content (static) |
| renderContent | (close) => ReactNode | — | Render prop with access to close() |
| position | "left" | "right" | "top" | "bottom" | "right" | Slide direction |
| size | string | "320px" | Width or height depending on position |
| disableOverlayClose | boolean | false | Prevents closing on overlay click (also blocks Escape unless disableEscapeClose says otherwise) |
| disableEscapeClose | boolean | disableOverlayClose | Also blocks the Escape key |
| ariaLabel | string | — | Accessible name for the dialog when no DrawerHeader is used |
| overlayClassName | string | — | Overlay styling |
| overlayStyle | CSSProperties | — | Inline overlay styles |
| panelClassName | string | — | Styles the sliding panel that hosts the drawer content |
DrawerButton Props
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | "" | Button text content |
| icon | ReactNode | — | Optional icon element |
| iconPosition | "left" | "right" | "left" | Controls icon placement |
| onClick | () => void | — | Click handler |
| className | string | — | Root button classes |
| style | CSSProperties | — | Inline styles |
| labelClassName | string | — | Label styling |
| iconClassName | string | — | Icon wrapper styling |
DrawerTriggerButton Props
Extends ButtonProps
| Prop | Type | Default | Description |
|---|---|---|---|
| drawerContent | (close) => ReactNode | — | Function to render drawer with access to close() |
| children | ReactNode | — | Trigger button content |
| drawerProps | Omit<DrawerProps, "isOpen" | "onClose" | "children"> | — | Forwarded to the underlying Drawer |
DrawerHeader Props
| title | string | — | Header title |
| icon | ReactNode | — | Optional icon |
| onClose | () => void | — | Shows close button if provided |
| className | string | — | Header wrapper class |
| style | CSSProperties | — | Header wrapper styles |
| titleWrapperClassName | string | — | Styles the wrapper around the icon and title |
| titleClassName | string | — | Styles the title heading |
| closeButtonClassName | string | — | Styles the close button |
DrawerContent Props
Wrapper for full-height layout inside Drawer.
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Full drawer layout (header/body/footer) |
| className | string | — | Wrapper class |
| style | CSSProperties | — | Wrapper styles |
DrawerBody Props
Scrollable content area with padding.
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Scrollable body content |
| className | string | — | Body wrapper class |
| style | CSSProperties | — | Body wrapper styles |
DrawerFooter Props
Footer actions container (buttons, etc).
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Footer actions |
| className | string | — | Footer wrapper class |
| style | CSSProperties | — | Footer wrapper styles |
Common Mistakes
<Drawer isOpen />Always bind isOpen to a state variable and provide onClose.
<Drawer isOpen={open} />Missing onClose means overlay clicks won't close the drawer.
<Drawer isOpen={open} onClose={...} />Missing position prop — defaults to "right". Be explicit when using other positions.
<Drawer isOpen={open} onClose={() => setOpen(false)} position="left" />Correct — state, close handler, and position all explicit.
use disableOverlayClose for modalsPrevent accidental closes in critical flows.
Pro Tips
- Use
renderContentfor full control — forms, menus, dashboards. - Combine
overlayClassNamewithbackdrop-blur-smfor a modern frosted glass look. - Use
disableOverlayClosefor critical flows to prevent accidental closes. - Prefer
top/bottompositions for mobile bottom sheets. - Use
DrawerHeaderwithonClosefor consistent close UX.
Frequently Asked Questions
How do I install and import the Drawer component?
Install the @neuctra/ui package, then import it with: import { Drawer } from "@neuctra/ui";
Can I customize the Drawer component's appearance?
Yes. Drawer accepts a className prop for custom Tailwind CSS classes, so you can adjust spacing, layout, and styling without overriding the component internals.
Is the Drawer component accessible?
Drawer is built with semantic HTML and standard ARIA attributes, and supports keyboard navigation and focus states out of the box, so it works well with screen readers and keyboard-only users.