Responsive Dialog

A dialog component that adapts to screen size - side dialog on desktop, drawer on mobile.

npx shadcn@latest add https://shuip.plvo.dev/r/responsive-dialog.json
pnpm dlx shadcn@latest add https://shuip.plvo.dev/r/responsive-dialog.json
bun x shadcn@latest add https://shuip.plvo.dev/r/responsive-dialog.json
'use client';
import * as React from 'react';
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from '@/components/ui/drawer';
import {
SideDialog,
SideDialogClose,
SideDialogContent,
SideDialogDescription,
SideDialogFooter,
SideDialogHeader,
SideDialogTitle,
SideDialogTrigger,
} from '@/components/ui/shuip/side-dialog';
type ResponsiveDialogPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'left' | 'right';
type ResponsiveDialogSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
type ResponsiveDialogBreakpoint = 'sm' | 'md' | 'lg' | 'xl' | number;
export interface ResponsiveDialogProps {
open?: boolean;
onOpenChange?: (open: boolean) => void;
position?: ResponsiveDialogPosition;
size?: ResponsiveDialogSize;
breakpoint?: ResponsiveDialogBreakpoint;
children?: React.ReactNode;
}
export interface ResponsiveDialogTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
asChild?: boolean;
children: React.ReactNode;
}
export interface ResponsiveDialogContentProps extends React.HTMLAttributes<HTMLDivElement> {
showCloseButton?: boolean;
children: React.ReactNode;
}
export interface ResponsiveDialogHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
}
export interface ResponsiveDialogTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {
children: React.ReactNode;
}
export interface ResponsiveDialogDescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {
children: React.ReactNode;
}
export interface ResponsiveDialogFooterProps extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
}
export interface ResponsiveDialogCloseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
asChild?: boolean;
children?: React.ReactNode;
}
// Helper function to convert breakpoint to pixels
const getBreakpointValue = (breakpoint: ResponsiveDialogBreakpoint): number => {
if (typeof breakpoint === 'number') {
return breakpoint;
}
const breakpoints = {
sm: 640,
md: 768,
lg: 1024,
xl: 1280,
};
return breakpoints[breakpoint];
};
// Custom hook for responsive breakpoint detection
const useCustomBreakpoint = (breakpoint: ResponsiveDialogBreakpoint) => {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);
React.useEffect(() => {
const breakpointValue = getBreakpointValue(breakpoint);
const mql = window.matchMedia(`(max-width: ${breakpointValue - 1}px)`);
const onChange = () => {
setIsMobile(window.innerWidth < breakpointValue);
};
mql.addEventListener('change', onChange);
setIsMobile(window.innerWidth < breakpointValue);
return () => mql.removeEventListener('change', onChange);
}, [breakpoint]);
return !!isMobile;
};
// Context for managing responsive state
const ResponsiveDialogContext = React.createContext<{
isMobile: boolean;
}>({
isMobile: false,
});
export function ResponsiveDialog({
open,
onOpenChange,
position = 'bottom-right',
size = 'sm',
breakpoint = 'md',
children,
}: ResponsiveDialogProps) {
const isMobile = useCustomBreakpoint(breakpoint);
return (
<ResponsiveDialogContext.Provider value={{ isMobile }}>
{isMobile ? (
<Drawer open={open} onOpenChange={onOpenChange}>
{children}
</Drawer>
) : (
<SideDialog open={open} onOpenChange={onOpenChange} position={position} size={size}>
{children}
</SideDialog>
)}
</ResponsiveDialogContext.Provider>
);
}
export function ResponsiveDialogTrigger({ asChild, children, ...props }: ResponsiveDialogTriggerProps) {
const { isMobile } = React.useContext(ResponsiveDialogContext);
if (isMobile) {
return (
<DrawerTrigger asChild={asChild} {...props}>
{children}
</DrawerTrigger>
);
}
return (
<SideDialogTrigger asChild={asChild} {...props}>
{children}
</SideDialogTrigger>
);
}
export function ResponsiveDialogContent({
showCloseButton = true,
className,
children,
...props
}: ResponsiveDialogContentProps) {
const { isMobile } = React.useContext(ResponsiveDialogContext);
if (isMobile) {
return (
<DrawerContent className={className} {...props}>
{children}
</DrawerContent>
);
}
return (
<SideDialogContent showCloseButton={showCloseButton} className={className} {...props}>
{children}
</SideDialogContent>
);
}
export function ResponsiveDialogHeader({ className, children, ...props }: ResponsiveDialogHeaderProps) {
const { isMobile } = React.useContext(ResponsiveDialogContext);
if (isMobile) {
return (
<DrawerHeader className={className} {...props}>
{children}
</DrawerHeader>
);
}
return (
<SideDialogHeader className={className} {...props}>
{children}
</SideDialogHeader>
);
}
export function ResponsiveDialogTitle({ className, children, ...props }: ResponsiveDialogTitleProps) {
const { isMobile } = React.useContext(ResponsiveDialogContext);
if (isMobile) {
return (
<DrawerTitle className={className} {...props}>
{children}
</DrawerTitle>
);
}
return (
<SideDialogTitle className={className} {...props}>
{children}
</SideDialogTitle>
);
}
export function ResponsiveDialogDescription({ className, children, ...props }: ResponsiveDialogDescriptionProps) {
const { isMobile } = React.useContext(ResponsiveDialogContext);
if (isMobile) {
return (
<DrawerDescription className={className} {...props}>
{children}
</DrawerDescription>
);
}
return (
<SideDialogDescription className={className} {...props}>
{children}
</SideDialogDescription>
);
}
export function ResponsiveDialogFooter({ className, children, ...props }: ResponsiveDialogFooterProps) {
const { isMobile } = React.useContext(ResponsiveDialogContext);
if (isMobile) {
return (
<DrawerFooter className={className} {...props}>
{children}
</DrawerFooter>
);
}
return (
<SideDialogFooter className={className} {...props}>
{children}
</SideDialogFooter>
);
}
export function ResponsiveDialogClose({ asChild, children, ...props }: ResponsiveDialogCloseProps) {
const { isMobile } = React.useContext(ResponsiveDialogContext);
if (isMobile) {
return (
<DrawerClose asChild={asChild} {...props}>
{children}
</DrawerClose>
);
}
return (
<SideDialogClose asChild={asChild} {...props}>
{children}
</SideDialogClose>
);
}
Loading...

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

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

Loading...
'use client';
import { zodResolver } from '@hookform/resolvers/zod';
import React from 'react';
import { useForm } from 'react-hook-form';
import z from 'zod';
import {
ResponsiveDialog,
ResponsiveDialogClose,
ResponsiveDialogContent,
ResponsiveDialogDescription,
ResponsiveDialogFooter,
ResponsiveDialogHeader,
ResponsiveDialogTitle,
ResponsiveDialogTrigger,
} from '@/components/block/shuip/responsive-dialog';
import { Button } from '@/components/ui/button';
import { Form } from '@/components/ui/form';
import { InputField } from '@/components/ui/shuip/react-hook-form/input-field';
import { SubmitButton } from '@/components/ui/shuip/submit-button';
export default function ResponsiveDialogExample() {
return (
<div className='space-y-4'>
<h3 className='text-lg font-semibold'>Basic Responsive Dialog</h3>
<div className='flex flex-wrap gap-2'>
<ResponsiveDialog>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Open Dialog</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Responsive Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>
This dialog adapts to your screen size. On desktop, it's a side dialog. On mobile, it's a drawer.
</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
<div className='p-4'>
<p className='text-sm text-muted-foreground'>
Try resizing your browser window or switching to mobile view to see the responsive behavior.
</p>
</div>
<ResponsiveDialogFooter>
<ResponsiveDialogClose asChild>
<Button variant='outline'>Close</Button>
</ResponsiveDialogClose>
<Button>Continue</Button>
</ResponsiveDialogFooter>
</ResponsiveDialogContent>
</ResponsiveDialog>
</div>
<div className='space-y-2'>
<h3 className='text-lg font-semibold'>Different Positions (Desktop only)</h3>
<div className='flex flex-wrap gap-2'>
<ResponsiveDialog position='top-left'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Top Left</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Top Left Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>Positioned at top left on desktop.</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
<ResponsiveDialog position='top-right'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Top Right</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Top Right Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>Positioned at top right on desktop.</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
<ResponsiveDialog position='bottom-left'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Bottom Left</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Bottom Left Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>Positioned at bottom left on desktop.</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
<ResponsiveDialog position='bottom-right'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Bottom Right</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Bottom Right Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>Positioned at bottom right on desktop.</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
<ResponsiveDialog position='left'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Left</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Left Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>Positioned at left side on desktop.</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
<ResponsiveDialog position='right'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Right</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Right Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>Positioned at right side on desktop.</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
</div>
</div>
<div className='space-y-2'>
<h3 className='text-lg font-semibold'>Different Sizes (Desktop only)</h3>
<div className='flex flex-wrap gap-2'>
<ResponsiveDialog size='xs'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Extra Small</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>XS Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>Extra small dialog size.</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
<ResponsiveDialog size='sm'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Small</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Small Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>Small dialog size (default).</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
<ResponsiveDialog size='md'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Medium</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Medium Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>Medium dialog size.</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
<ResponsiveDialog size='lg'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Large</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Large Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>Large dialog size for more content.</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
<ResponsiveDialog size='xl'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Extra Large</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>XL Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>Extra large dialog size.</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
<ResponsiveDialog size='2xl'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>2X Large</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>2XL Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>2X large dialog size for extensive content.</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
</div>
</div>
<div className='space-y-2'>
<h3 className='text-lg font-semibold'>Custom Breakpoints</h3>
<div className='flex flex-wrap gap-2'>
<ResponsiveDialog breakpoint='sm'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Breakpoint SM (640px)</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Small Breakpoint</ResponsiveDialogTitle>
<ResponsiveDialogDescription>
This dialog switches to mobile mode at 640px and below.
</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
<ResponsiveDialog breakpoint='md'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Breakpoint MD (768px)</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Medium Breakpoint</ResponsiveDialogTitle>
<ResponsiveDialogDescription>
This dialog switches to mobile mode at 768px and below (default).
</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
<ResponsiveDialog breakpoint='lg'>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Breakpoint LG (1024px)</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Large Breakpoint</ResponsiveDialogTitle>
<ResponsiveDialogDescription>
This dialog switches to mobile mode at 1024px and below.
</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
<ResponsiveDialog breakpoint={900}>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Custom 900px</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Custom Breakpoint</ResponsiveDialogTitle>
<ResponsiveDialogDescription>
This dialog switches to mobile mode at exactly 900px and below.
</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
</ResponsiveDialogContent>
</ResponsiveDialog>
</div>
</div>
<h3 className='text-lg font-semibold'>Form Example</h3>
<ResponsiveDialogFormExample />
</div>
);
}
const formSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
});
function ResponsiveDialogFormExample() {
const [open, setOpen] = React.useState(false);
const form = useForm({
resolver: zodResolver(formSchema),
});
const onSubmit = async (data: z.infer<typeof formSchema>) => {
alert(JSON.stringify(data));
setOpen(false);
form.reset();
};
return (
<ResponsiveDialog open={open} onOpenChange={setOpen}>
<ResponsiveDialogTrigger asChild>
<Button variant='outline'>Open Dialog</Button>
</ResponsiveDialogTrigger>
<ResponsiveDialogContent>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<ResponsiveDialogHeader>
<ResponsiveDialogTitle>Responsive Dialog</ResponsiveDialogTitle>
<ResponsiveDialogDescription>
This dialog adapts to your screen size. On desktop, it's a side dialog. On mobile, it's a drawer.
</ResponsiveDialogDescription>
</ResponsiveDialogHeader>
<div className='space-y-4 px-4'>
<InputField register={form.register('name')} name='name' label='Name' />
<InputField register={form.register('email')} name='email' label='Email' />
</div>
<ResponsiveDialogFooter>
<ResponsiveDialogClose asChild>
<Button variant='outline'>Close</Button>
</ResponsiveDialogClose>
<SubmitButton className='max-md:w-full'>Submit</SubmitButton>
</ResponsiveDialogFooter>
</form>
</Form>
</ResponsiveDialogContent>
</ResponsiveDialog>
);
}

Props

Prop

Type

On this page