2025-07-20ยทreact
Creating Responsive Dialog and Drawer Components with shadcn/ui
Taher Hathi
Taher Hathi
Learn how to build adaptive modal components that transform from dialogs on desktop to drawers on mobile for optimal user experience.

Creating responsive modal components that adapt to different screen sizes is crucial for modern web applications. While desktop users prefer centered dialogs, mobile users benefit from drawer-style interfaces that slide up from the bottom. This article shows how to build a unified component that seamlessly transitions between these two patterns.
The Challenge with Traditional Modals
Standard dialog components work well on desktop but can feel cramped and awkward on mobile devices. The small screen real estate makes centered modals difficult to interact with, especially when they contain forms or lengthy content. Users often struggle with:
- Limited viewport space being consumed by the modal
- Difficulty reaching close buttons in corner positions
- Poor thumb accessibility on larger phones
- Awkward scrolling within constrained modal heights
Building the Adaptive Solution
Our approach uses a single component that detects screen size and renders appropriately. The component leverages Radix UI primitives for accessibility while applying different styling patterns based on device capabilities.
Key Features
The responsive dialog/drawer component includes several thoughtful design decisions:
Mobile-First Drawer Experience
- Slides up from the bottom for natural thumb interaction
- Includes a visual drag handle for intuitive gesture recognition
- Maximizes content area while maintaining familiar mobile patterns
- Positions close button in easily reachable locations
Desktop Dialog Behavior
- Centers content with appropriate sizing constraints
- Maintains traditional modal interaction patterns
- Provides subtle animations that feel polished
- Uses backdrop blur effects for modern visual appeal
Consistent Styling Across Breakpoints
- Unified color scheme that adapts to light and dark modes
- Smooth transitions between mobile and desktop layouts
- Accessible focus management regardless of presentation style
- Proper ARIA labeling for screen readers
Implementation Details
The component uses a custom hook to detect mobile screens and conditionally renders different layouts. Here's how the magic happens:
Device Detection Strategy
1const isMobile = useIsMobile();This hook determines whether to show the drawer or dialog version, typically checking for screen widths below tablet breakpoints.
Mobile Drawer Layout
For mobile devices, the component renders at the bottom of the screen with:
- Rounded top corners for visual polish
- A drag handle indicator for gesture hints
- Slide-up animations that feel natural
- Full-width content area maximization
The mobile version uses these key styling patterns:
1/* Bottom positioning with slide animations */
2fixed inset-x-0 bottom-0
3/* Rounded top corners only */
4rounded-t-[10px]
5/* Slide animation classes */
6data-[state=open]:slide-in-from-bottomDesktop Dialog Experience
Desktop users receive a traditional centered modal with:
- Centered positioning with maximum width constraints
- Subtle zoom and fade animations
- Backdrop blur effects for modern aesthetics
- Optimal focus management
The desktop styling emphasizes:
1/* Centered positioning */
2left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%]
3/* Maximum width constraints */
4w-full max-w-lg
5/* Refined animations */
6data-[state=open]:zoom-in-95Enhanced User Experience Benefits
This adaptive approach delivers significant UX improvements:
Mobile Users Benefit From
- Larger interaction targets that work well with touch
- Content that doesn't compete with virtual keyboards
- Familiar bottom-sheet patterns from native mobile apps
- Gesture-friendly close mechanisms
Desktop Users Enjoy
- Focused content that doesn't dominate the entire screen
- Precise mouse interaction with appropriately sized targets
- Professional appearance that matches desktop software conventions
- Keyboard navigation that follows expected patterns
Accessibility Considerations
The component maintains accessibility across both presentations:
- Proper focus trapping keeps keyboard users within the modal content
- ARIA labels provide context for screen readers
- High contrast ratios ensure visibility in both light and dark themes
- Keyboard shortcuts work consistently across device types
- Focus management returns users to appropriate trigger elements on close
Complete Implementation Code
Here's the full implementation of the responsive dialog/drawer component:
1"use client";
2
3import * as React from "react";
4import * as DialogPrimitive from "@radix-ui/react-dialog";
5import { X } from "lucide-react";
6
7import { cn } from "@/lib/utils";
8import { useIsMobile } from "@/hooks/use-mobile";
9
10const Dialog = DialogPrimitive.Root;Integration and Usage
Using the component requires minimal changes to existing code:
1<Dialog>
2 <DialogTrigger>Open Modal</DialogTrigger>
3 <DialogContent>
4 <DialogHeader>
5 <DialogTitle>Responsive Modal</DialogTitle>
6 <DialogDescription>
7 This modal adapts to your screen size automatically.
8 </DialogDescription>
9 </DialogHeader>
10 The component automatically detects screen size and applies appropriate styling without requiring additional props or configuration.
Performance and Bundle Considerations
The implementation adds minimal overhead while delivering maximum flexibility:
- Single component reduces bundle size compared to separate dialog/drawer libraries
- Conditional rendering prevents unnecessary DOM elements
- Efficient CSS classes minimize runtime style calculations
- Shared Radix primitives reduce overall dependency weight
Customization Options
The component supports extensive customization while maintaining responsive behavior:
Styling Flexibility
- Tailwind classes can be overridden through className props
- Custom animations can replace defaults
- Brand colors integrate seamlessly through CSS custom properties
- Spacing and sizing adapt to design system requirements
Behavioral Modifications
- Breakpoint thresholds can be adjusted for specific use cases
- Animation durations and easing can be customized
- Close behavior can be modified for different interaction patterns
- Content scrolling can be configured per device type
Best Practices and Recommendations
When implementing responsive modals, consider these guidelines:
Content Strategy
- Keep mobile content concise and scannable
- Use progressive disclosure for complex forms
- Prioritize primary actions in easily reachable locations
- Test with actual devices rather than browser responsive modes
Performance Optimization
- Lazy load modal content when possible
- Implement proper cleanup for animation listeners
- Consider preloading critical modal assets
- Monitor bundle size impact of responsive components
Testing Approaches
- Verify behavior across multiple device categories
- Test with various screen orientations
- Validate accessibility with assistive technologies
- Check performance impact on lower-end devices
Conclusion
Responsive dialog and drawer components represent a significant improvement over traditional one-size-fits-all modals. By adapting presentation to device capabilities, we create more intuitive and accessible user experiences. The implementation combines modern React patterns with thoughtful UX design to deliver components that feel native on every device.
This approach demonstrates how thoughtful component design can eliminate the need for separate mobile and desktop implementations while actually improving the user experience on both platforms. As responsive design continues evolving, components like this show the path toward truly adaptive user interfaces that work seamlessly across the full spectrum of modern devices.