Package Exports
- blocx-drawer
- blocx-drawer/dist/index.esm.js
- blocx-drawer/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (blocx-drawer) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Blocx Drawer
A modern, feature-rich drawer component for React/Next.js applications. Built with TypeScript and designed for mobile-first experiences.
✨ Features
- 🎯 4-Direction Support: Left, right, top, bottom drawers
- 📱 Mobile Optimized: Touch gestures, swipe to close, proper iOS handling
- 🎨 3-Mode System: Normal, expanded, and minimized states (top/bottom only)
- ♿ Accessibility: Focus trapping, ARIA support, keyboard navigation
- 🎭 Smooth Animations: GPU-accelerated, configurable transitions
- 📏 5 Size Options: s, m, l, xl, fullscreen
- 🎛️ Highly Configurable: Backdrop, dismissible, swipe gestures
- 📦 Zero Dependencies: Self-contained, no external dependencies
- 🔧 TypeScript: Full type safety and IntelliSense support
📦 Installation
npm install blocx-drawer
npx blocx-setup
After installation, run npx blocx-setup
to choose your preferred styling option:
🎨 Blocx Drawer Setup
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Choose your preferred styling option:
1. 📝 CSS (Default - Recommended)
2. 🎨 Tailwind CSS
3. ⚙️ SCSS with Design Tokens
Enter your choice (1-3) or press Enter for default CSS:
🎨 Styling Options
Blocx Drawer provides three styling options to fit your project's needs:
Option 1: CSS (Default - Recommended)
Self-contained CSS with CSS custom properties for easy theming.
// Import the component (CSS is automatically included)
import { Drawer } from 'blocx-drawer';
Option 2: Tailwind CSS
If you're using Tailwind CSS, import the Tailwind-specific styles:
import { Drawer } from 'blocx-drawer';
// Import Tailwind styles instead of default CSS
import 'blocx-drawer/styles/blocx-drawer-tailwind.css';
Option 3: SCSS with Design Tokens
For projects using SCSS, import the SCSS version with design tokens:
import { Drawer } from 'blocx-drawer';
// Import SCSS version (requires SCSS compiler)
import 'blocx-drawer/styles/blocx-drawer.scss';
🚀 Quick Start
import React, { useState } from 'react';
import {
Drawer,
DrawerHeader,
DrawerBody,
DrawerFooter,
DrawerTitle,
DrawerDescription
} from 'blocx-drawer';
function App() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(true)}>
Open Drawer
</button>
<Drawer
open={isOpen}
onClose={() => setIsOpen(false)}
side="right"
size="m"
>
<DrawerHeader>
<DrawerTitle>Settings</DrawerTitle>
<DrawerDescription>
Manage your account settings and preferences
</DrawerDescription>
</DrawerHeader>
<DrawerBody>
<p>Drawer content goes here...</p>
</DrawerBody>
<DrawerFooter>
<button onClick={() => setIsOpen(false)}>
Close
</button>
</DrawerFooter>
</Drawer>
</div>
);
}
🎛️ Props Reference
Drawer Props
Prop | Type | Default | Description |
---|---|---|---|
open |
boolean |
- | Required. Controls drawer visibility |
onClose |
() => void |
- | Required. Called when drawer should close |
side |
'left' | 'right' | 'top' | 'bottom' |
'left' |
Drawer position |
size |
's' | 'm' | 'l' | 'xl' | 'fullscreen' |
'm' |
Drawer size |
dismissible |
boolean |
true |
Allow closing with ESC key or backdrop click |
swipeToClose |
boolean |
true |
Enable swipe gestures to close |
backdrop |
boolean |
true |
Show backdrop overlay |
trapFocus |
boolean |
true |
Trap focus within drawer |
expandMode |
boolean |
false |
Enable expand to fullscreen (top/bottom only) |
minimizeMode |
boolean |
false |
Enable minimize to header only (top/bottom only) |
bottomOffset |
number |
0 |
Bottom offset in pixels (useful for nav bars) |
onMinimize |
() => void |
- | Called when drawer is minimized |
onRestore |
() => void |
- | Called when drawer is restored from minimized |
Component Props
All sub-components (DrawerHeader
, DrawerBody
, DrawerFooter
, DrawerTitle
, DrawerDescription
) accept standard HTML props for their respective elements.
DrawerBody
Prop | Type | Default | Description |
---|---|---|---|
scrollable |
boolean |
true |
Enable internal scrolling |
📐 Size Guide
Size | Left/Right Width | Top/Bottom Height |
---|---|---|
s |
78vw (max 340px) | 55vh |
m |
86vw (max 420px) | 65vh |
l |
92vw (max 520px) | 75vh |
xl |
96vw (max 680px) | 88vh |
fullscreen |
100vw | 100vh |
🎯 Advanced Examples
Bottom Drawer with 3-Mode System
<Drawer
open={isOpen}
onClose={() => setIsOpen(false)}
side="bottom"
size="m"
expandMode={true}
minimizeMode={true}
onMinimize={() => console.log('Minimized!')}
onRestore={() => console.log('Restored!')}
>
<DrawerHeader>
<DrawerTitle>Music Player</DrawerTitle>
</DrawerHeader>
<DrawerBody>
{/* This drawer can be:
- Normal: Default size
- Expanded: Drag up to expand to nearly fullscreen
- Minimized: Drag down to minimize to header only */}
<div>Player controls and playlist...</div>
</DrawerBody>
</Drawer>
Non-scrollable Content
<Drawer open={isOpen} onClose={() => setIsOpen(false)}>
<DrawerHeader>
<DrawerTitle>Image Viewer</DrawerTitle>
</DrawerHeader>
<DrawerBody scrollable={false}>
{/* Content here won't scroll - all gestures control the drawer */}
<img src="large-image.jpg" alt="Full size image" />
</DrawerBody>
</Drawer>
Custom Styling
<Drawer
open={isOpen}
onClose={() => setIsOpen(false)}
className="custom-drawer"
panelClassName="custom-panel"
backdropClassName="custom-backdrop"
>
<DrawerHeader>
<DrawerTitle as="h1">Custom Styled Drawer</DrawerTitle>
</DrawerHeader>
<DrawerBody>
<p>Apply your own CSS classes for custom styling</p>
</DrawerBody>
</Drawer>
🎨 Styling
The component includes comprehensive CSS with CSS custom properties for easy theming:
/* Example: Dark mode customization */
.custom-drawer {
--panel-bg: #1f2937;
--panel-color: #f9fafb;
--panel-border: 1px solid rgba(255, 255, 255, 0.2);
--backdrop-bg: rgba(0, 0, 0, 0.75);
}
📱 Mobile Behavior
- Touch Gestures: Natural swipe gestures on mobile devices
- iOS Safari: Proper viewport handling and safe area support
- Overscroll Prevention: Prevents page bounce while allowing drawer scrolling
- Focus Management: Proper focus handling for screen readers
- Keyboard Navigation: Full keyboard support with Tab trapping
🎯 Gesture System
Left/Right Drawers
- Swipe towards edge: Close drawer
- Swipe from edge: Elastic resistance effect
- Velocity detection: Fast swipes trigger immediate close
Top/Bottom Drawers (3-Mode System)
Normal Mode:
- Drag down (bottom) / up (top): Close or minimize
- Drag up (bottom) / down (top): Expand (if enabled)
Expanded Mode:
- Drag down (bottom) / up (top): Shrink to normal or close
Minimized Mode:
- Drag up (bottom) / down (top): Restore to normal
- Drag down (bottom) / up (top): Close
⚡ Performance
- GPU Acceleration: Hardware-accelerated animations
- Containment: CSS containment for optimal rendering
- Lazy Portal: Portal created only when needed
- Event Optimization: Efficient touch/pointer event handling
- Bundle Size: ~15KB gzipped (component + styles)
🔧 Browser Support
- Chrome/Edge: ✅ Full support
- Safari: ✅ Full support (including iOS)
- Firefox: ✅ Full support
- IE11: ❌ Not supported (uses modern CSS features)
📄 License
MIT © Alex Trick (https://mrtrick.me)
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.