Responsive Dialog
A dialog component that adapts to screen size - side dialog on desktop, drawer on mobile.
Installation
npx shadcn@latest add https://shuip.xyz/r/responsive-dialog.json
Preview
Basic Responsive Dialog
Different Positions (Desktop only)
Different Sizes (Desktop only)
Custom Breakpoints
Form Example
About
ResponsiveDialog
is a smart dialog component that automatically adapts to the user's screen size:
- Desktop (≥1024px): Renders as a
SideDialog
with flexible positioning - Mobile (<1024px): Renders as a
Drawer
for better mobile UX
Unlike traditional dialogs that force the same experience across all devices, ResponsiveDialog
provides the optimal interface for each screen size while maintaining a consistent API.
Built-in features
- Automatic responsive behavior: Switches between side dialog and drawer based on screen size
- 6 positions (desktop): Choose from
top-left
,top-right
,bottom-left
,bottom-right
,left
,right
- Flexible sizes (desktop): Predefined sizes (
xs
,sm
,md
,lg
,xl
,2xl
) - Mobile-optimized: Uses native drawer with swipe gestures on mobile
- Lightweight: Combines existing components without additional overhead
- Accessible: Inherits accessibility features from both SideDialog and Drawer
Installation
Usage
Basic responsive dialog
<ResponsiveDialog><ResponsiveDialogTrigger asChild><Button>Open Dialog</Button></ResponsiveDialogTrigger><ResponsiveDialogContent><ResponsiveDialogHeader><ResponsiveDialogTitle>Settings</ResponsiveDialogTitle><ResponsiveDialogDescription>Manage your preferences and account settings.</ResponsiveDialogDescription></ResponsiveDialogHeader><ResponsiveDialogFooter><ResponsiveDialogClose asChild><Button variant="outline">Cancel</Button></ResponsiveDialogClose><Button>Save</Button></ResponsiveDialogFooter></ResponsiveDialogContent></ResponsiveDialog>
Different positions (desktop only)
Desktop positions are ignored on mobile where the drawer behavior takes precedence:
// Notification from bottom-right<ResponsiveDialog position="bottom-right"><ResponsiveDialogTrigger asChild><Button>Show Notification</Button></ResponsiveDialogTrigger><ResponsiveDialogContent><ResponsiveDialogHeader><ResponsiveDialogTitle>Success!</ResponsiveDialogTitle><ResponsiveDialogDescription>Your changes have been saved.</ResponsiveDialogDescription></ResponsiveDialogHeader></ResponsiveDialogContent></ResponsiveDialog>// User menu from top-right<ResponsiveDialog position="top-right" size="sm"><ResponsiveDialogTrigger asChild><Button variant="ghost" size="icon"><User className="size-4" /></Button></ResponsiveDialogTrigger><ResponsiveDialogContent><ResponsiveDialogHeader><ResponsiveDialogTitle>Account</ResponsiveDialogTitle></ResponsiveDialogHeader><div className="space-y-2"><Button variant="ghost" className="w-full justify-start">Profile Settings</Button><Button variant="ghost" className="w-full justify-start">Sign out</Button></div></ResponsiveDialogContent></ResponsiveDialog>
Custom breakpoints
Control when the dialog switches between desktop and mobile modes:
// Use predefined breakpoints<ResponsiveDialog breakpoint="sm"> {/* Switches at 640px */}<ResponsiveDialogTrigger asChild><Button>Small Breakpoint</Button></ResponsiveDialogTrigger><ResponsiveDialogContent><ResponsiveDialogHeader><ResponsiveDialogTitle>Mobile at 640px</ResponsiveDialogTitle><ResponsiveDialogDescription>This dialog becomes a drawer on screens smaller than 640px.</ResponsiveDialogDescription></ResponsiveDialogHeader></ResponsiveDialogContent></ResponsiveDialog>// Use custom pixel values<ResponsiveDialog breakpoint={900}><ResponsiveDialogTrigger asChild><Button>Custom Breakpoint</Button></ResponsiveDialogTrigger><ResponsiveDialogContent><ResponsiveDialogHeader><ResponsiveDialogTitle>Custom at 900px</ResponsiveDialogTitle><ResponsiveDialogDescription>Switches to mobile mode at exactly 900px and below.</ResponsiveDialogDescription></ResponsiveDialogHeader></ResponsiveDialogContent></ResponsiveDialog>
Different sizes (desktop only)
Size props affect the desktop side dialog appearance:
// Small dialog for quick actions<ResponsiveDialog size="xs"><ResponsiveDialogTrigger asChild><Button variant="outline">Quick Action</Button></ResponsiveDialogTrigger><ResponsiveDialogContent><ResponsiveDialogHeader><ResponsiveDialogTitle>Confirm</ResponsiveDialogTitle><ResponsiveDialogDescription>Are you sure?</ResponsiveDialogDescription></ResponsiveDialogHeader></ResponsiveDialogContent></ResponsiveDialog>// Large dialog for complex content<ResponsiveDialog position="left" size="lg"><ResponsiveDialogTrigger asChild><Button variant="outline">Navigation Menu</Button></ResponsiveDialogTrigger><ResponsiveDialogContent><ResponsiveDialogHeader><ResponsiveDialogTitle>Navigation</ResponsiveDialogTitle></ResponsiveDialogHeader><nav className="space-y-2"><Link href="/dashboard">Dashboard</Link><Link href="/projects">Projects</Link><Link href="/settings">Settings</Link></nav></ResponsiveDialogContent></ResponsiveDialog>
Common use cases
Mobile-first navigation
<ResponsiveDialog position="left" size="lg"><ResponsiveDialogTrigger asChild><Button variant="outline" size="icon"><Menu className="size-4" /></Button></ResponsiveDialogTrigger><ResponsiveDialogContent><ResponsiveDialogHeader><ResponsiveDialogTitle>Menu</ResponsiveDialogTitle></ResponsiveDialogHeader><nav className="space-y-3"><Link href="/home" className="block p-2 hover:bg-muted rounded">Home</Link><Link href="/about" className="block p-2 hover:bg-muted rounded">About</Link><Link href="/contact" className="block p-2 hover:bg-muted rounded">Contact</Link></nav></ResponsiveDialogContent></ResponsiveDialog>
Examples
Default
Basic Responsive Dialog
Different Positions (Desktop only)
Different Sizes (Desktop only)
Custom Breakpoints
Form Example
Props
Name | Type | Description |
---|---|---|
boolean | Whether the dialog is open. Use with onOpenChange for controlled component. | |
(open: boolean) => void | Callback fired when the dialog open state changes. | |
'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'left' | 'right' | Position of the dialog on desktop. Default is "bottom-right". Ignored on mobile. | |
'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | Size of the dialog on desktop. Default is "sm". Ignored on mobile. | |
'sm' | 'md' | 'lg' | 'xl' | number | Breakpoint at which the dialog switches to mobile mode. Default is "md" (768px). Can be a predefined breakpoint or custom pixel value. |