Building a Resizable Drawer
A deep dive into creating a responsive, resizable drawer system with React and TypeScript
Introduction
Modern web applications often require flexible UI components that can display contextual information without disrupting the main content flow. In this article, we'll explore how to build a versatile drawer system that supports multiple instances, resizing, and smooth animations.
Key Features
- Multiple concurrent drawers with proper z-index management
- Resizable drawer width with minimum and maximum constraints
- Collapsible state with smooth animations
- Dynamic component loading
- TypeScript support for type safety
The Core Architecture
The drawer system consists of three main components:
- DrawerManager: Handles the creation and management of multiple drawer instances
- Drawer: The individual drawer component with resize and collapse functionality
- Registry: A central place to register and lazy-load drawer contents
Usage Example
To trigger a drawer, we use a simple function call:
openDrawer(
'component-name', // Registered drawer component
{ /* props */ }, // Props to pass to the component
'Custom Header', // Optional header text
400 // Optional default width
);
Styling with CSS Modules
The drawer uses CSS modules for scoped styling and smooth transitions. Key features include:
- Slide-in animation using transforms
- Smooth width transitions for resizing
- Responsive layout adjustments
- Dark mode support through CSS variables
Advanced Features
Resize Functionality
The resize functionality is implemented using mouse events and a draggable handle:
const resize = (e: MouseEvent) => {
if (drawerRef.current) {
const newWidth = window.innerWidth - e.clientX;
if (newWidth > MIN_WIDTH && newWidth < MAX_WIDTH) {
drawerRef.current.style.width = `${newWidth}px`;
}
}
}
Collapse State
Users can collapse drawers to save space while keeping them accessible:
const toggleDrawer = () => setIsOpen(!isOpen); // Width changes from full
width to 50px when collapsed style={
{ width: isOpen ? drawerWidth.current : 50 }
}
Conclusion
This drawer system provides a flexible foundation for displaying contextual content in web applications. Its modular design and type-safe implementation make it easy to extend and maintain.