A modern, accessible, and highly customizable draggable drawer component for React 18+ and React 19
npm install draggable-react-drawer





A modern, accessible, and highly customizable draggable drawer component for React applications. Perfect for mobile-first designs, filter panels, forms, and modal-like experiences.
- π― TypeScript Support - Full type safety and IntelliSense
- π± Mobile-First Design - Optimized for touch interactions
- βΏ Accessibility - ARIA attributes, keyboard navigation, focus management
- π¨ Customizable - Snap points, animations, backdrop, and styling
- π Lightweight - Small bundle size with zero dependencies
- π§ͺ Well Tested - Comprehensive test coverage
- π¦ Tree Shakeable - ES modules support
- π Multiple Positions - Bottom, top, left, right drawer support
- β‘ React 19 Ready - Optimized for React 19 with concurrent features
- π Concurrent Rendering - Uses startTransition for smooth animations
``bash`
npm install draggable-react-draweror
yarn add draggable-react-draweror
pnpm add draggable-react-drawer
`tsx
import React, { useState } from 'react';
import { Drawer } from 'draggable-react-drawer';
function App() {
const [isOpen, setIsOpen] = useState(false);
return (
This is a draggable drawer!
π API Reference
$3
| Prop | Type | Default | Description |
|------|------|---------|-------------|
|
open | boolean | - | Required. Controls drawer visibility |
| setOpen | (open: boolean) => void | - | Required. Function to control drawer state |
| children | ReactNode | - | Required. Content to render inside drawer |
| verticalRatio | number | 100 | Height ratio (1-100) of the drawer |
| snapPoints | number[] | [0, 0.25, 0.5, 0.75, 1] | Snap points for drawer positioning |
| animationDuration | number | 300 | Animation duration in milliseconds |
| backdrop | boolean | true | Show backdrop overlay |
| onBackdropClick | () => void | - | Callback when backdrop is clicked |
| keyboardAware | boolean | true | Adjust position when keyboard appears |
| className | string | '' | Additional CSS class name |
| style | CSSProperties | {} | Inline styles |
| aria-label | string | - | Accessibility label |
| aria-labelledby | string | - | ID of element that labels the drawer |
| aria-describedby | string | - | ID of element that describes the drawer |
| unstable_useFormStatus | boolean | - | React 19: Enable form status integration |
| unstable_useFormState | boolean | - | React 19: Enable form state integration |π¨ Examples
$3
`tsx
Your content here
`$3
`tsx
open={isOpen}
setOpen={setIsOpen}
verticalRatio={60}
snapPoints={[0, 0.3, 0.6, 1]}
>
Custom height drawer
`$3
`tsx
open={isOpen}
setOpen={setIsOpen}
backdrop={false}
>
No backdrop drawer
`$3
`tsx
open={isOpen}
setOpen={setIsOpen}
className="my-custom-drawer"
style={{
backgroundColor: '#f0f0f0',
borderRadius: '20px 20px 0 0'
}}
>
Styled drawer
`$3
`tsx
open={isOpen}
setOpen={setIsOpen}
aria-label="Settings Panel"
aria-labelledby="settings-title"
aria-describedby="settings-description"
>
Settings
Configure your preferences
Settings content...
`$3
`tsx
open={isOpen}
setOpen={setIsOpen}
unstable_useFormStatus={true}
unstable_useFormState={true}
>
`π― Use Cases
- Mobile Navigation - Slide-out menus and navigation panels
- Filter Panels - Product filters, search options
- Forms - Multi-step forms, checkout flows
- Settings - User preferences, configuration panels
- Media Galleries - Image/video viewers with controls
- Notifications - Toast messages, alerts
βΏ Accessibility
This component follows WCAG 2.1 guidelines and includes:
- Keyboard Navigation - ESC key to close, Tab navigation
- Screen Reader Support - Proper ARIA attributes
- Focus Management - Focus trapping and restoration
- High Contrast - Supports system preferences
- Reduced Motion - Respects user preferences
π§ͺ Testing
`bash
Run tests
npm testRun tests in watch mode
npm run test:watchRun tests with coverage
npm test -- --coverage
`π οΈ Development
`bash
Install dependencies
npm installStart development
npm run build:devType checking
npm run type-checkLinting
npm run lintBuild for production
npm run build
`π Bundle Size
- Minified: ~2.5KB gzipped
- With Dependencies: ~15KB gzipped (includes antd-mobile)
π€ Contributing
Contributions are welcome! Please read our Contributing Guide for details.
1. Fork the repository
2. Create your feature branch (
git checkout -b feature/amazing-feature)
3. Commit your changes (git commit -m 'Add some amazing feature')
4. Push to the branch (git push origin feature/amazing-feature`)This project is licensed under the MIT License - see the LICENSE file for details.
- Built with antd-mobile FloatingPanel
- Inspired by modern mobile app patterns
- Community feedback and contributions
- GitHub Repository
- NPM Package
- Live Demo (Coming Soon)
- Storybook (Coming Soon)
---
Made with β€οΈ by YaΕar Tahir KΓΆse