Slide-in panel that can be anchored to any edge of the screen. Perfect for navigation menus, filters, or contextual panels.
Import
import { Drawer } from '@kivora/react';
Usage
import { Drawer, Button, useDisclosure } from '@kivora/react';
function Example() {
const { isOpen, open, close } = useDisclosure();
return (
<>
<Button label="Open Menu" onClick={open} />
<Drawer isOpen={isOpen} onClose={close} title="Navigation">
<nav className="flex flex-col gap-2">
<a href="/" className="p-2 hover:bg-accent rounded">Home</a>
<a href="/about" className="p-2 hover:bg-accent rounded">About</a>
<a href="/contact" className="p-2 hover:bg-accent rounded">Contact</a>
</nav>
</Drawer>
</>
);
}
Positions
Anchor the drawer to any edge:
<Drawer isOpen={isOpen} onClose={close} position="left" title="Left Menu">
<p>Slides in from the left</p>
</Drawer>
<Drawer isOpen={isOpen} onClose={close} position="right" title="Right Panel">
<p>Slides in from the right (default)</p>
</Drawer>
<Drawer isOpen={isOpen} onClose={close} position="top" title="Top Panel">
<p>Slides down from the top</p>
</Drawer>
<Drawer isOpen={isOpen} onClose={close} position="bottom" title="Bottom Sheet">
<p>Slides up from the bottom</p>
</Drawer>
Sizes
Control drawer dimensions with the size prop:
{/* For horizontal drawers (left/right) */}
<Drawer isOpen={isOpen} onClose={close} size="xs" position="left">
<p>Narrow drawer (256px)</p>
</Drawer>
<Drawer isOpen={isOpen} onClose={close} size="lg" position="right">
<p>Wide drawer (384px)</p>
</Drawer>
{/* For vertical drawers (top/bottom) */}
<Drawer isOpen={isOpen} onClose={close} size="md" position="bottom">
<p>Medium height drawer</p>
</Drawer>
<Drawer isOpen={isOpen} onClose={close} size="full" position="top">
<p>Full screen drawer</p>
</Drawer>
Available sizes:
- Horizontal (left/right):
xs (256px), sm (288px), md (320px), lg (384px), xl (512px), full (100vw)
- Vertical (top/bottom):
xs (192px), sm (256px), md (320px), lg (384px), xl (512px), full (100vh)
Navigation Drawer
import { Drawer, Button, useDisclosure } from '@kivora/react';
import { Menu, Home, Settings } from 'lucide-react';
function NavDrawer() {
const { isOpen, open, close } = useDisclosure();
return (
<>
<Button
label="Menu"
leftIcon={<Menu size={16} />}
variant="ghost"
onClick={open}
/>
<Drawer
isOpen={isOpen}
onClose={close}
position="left"
size="sm"
title="Navigation"
>
<div className="flex flex-col gap-1">
<button className="flex items-center gap-3 p-3 hover:bg-accent rounded-lg">
<Home size={18} />
<span>Home</span>
</button>
<button className="flex items-center gap-3 p-3 hover:bg-accent rounded-lg">
<Settings size={18} />
<span>Settings</span>
</button>
</div>
</Drawer>
</>
);
}
Filter Panel
function FilterDrawer() {
const { isOpen, open, close } = useDisclosure();
const [filters, setFilters] = useState({ category: '', price: '' });
return (
<>
<Button label="Filters" onClick={open} />
<Drawer
isOpen={isOpen}
onClose={close}
position="right"
title="Filter Products"
>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium mb-2">Category</label>
<select className="w-full p-2 border rounded">
<option>All</option>
<option>Electronics</option>
<option>Clothing</option>
</select>
</div>
<div>
<label className="block text-sm font-medium mb-2">Price Range</label>
<input type="range" className="w-full" />
</div>
<Button label="Apply Filters" onClick={close} fullWidth />
</div>
</Drawer>
</>
);
}
Disable Backdrop Close
Prevent closing when clicking outside:
<Drawer
isOpen={isOpen}
onClose={close}
title="Important Form"
closeOnBackdrop={false}
>
<form>
<p>Complete this form before closing</p>
</form>
</Drawer>
Props
Whether the drawer is visible
Callback to close the drawer
Optional title rendered in the drawer header
size
'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full'
default:"md"
Width (for left/right) or height (for top/bottom) of the drawer
position
'left' | 'right' | 'top' | 'bottom'
default:"right"
Which edge of the screen to anchor the drawer to
Close when clicking the backdrop
Close when pressing Escape key
Additional CSS classes for the drawer panel
Accessibility
- Uses
role="dialog" and aria-modal="true"
- Automatically manages focus trap within the drawer
- Locks body scroll when open
- Links title with
aria-labelledby
- Close button has
aria-label
- Escape key support (configurable)
Features
- Portal rendering into
document.body
- Smooth slide animations from any edge
- Focus trap using
useFocusTrap hook
- Scroll lock using
useScrollLock hook
- Backdrop blur effect
- Configurable sizes and positions
- Fixed header with close button
- Scrollable content area