Dialog
A modal dialog component for displaying content that requires user interaction, built on Radix UI with smooth animations and accessibility features.
Usage
Basic Dialog
The Dialog component displays content in a modal overlay that requires user interaction.
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription
} from "@prisma-docs/eclipse";
import { Button } from "@prisma-docs/eclipse";
export function BasicDialog() {
return (
<Dialog>
<DialogTrigger asChild>
<Button>Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Welcome</DialogTitle>
<DialogDescription>
This is a basic dialog example. Click outside or press escape to close.
</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>
);
}Live Example:
Dialog with Footer
Add action buttons in the footer for user interactions:
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
DialogClose,
Button
} from "@prisma-docs/eclipse";
export function DialogWithFooter() {
return (
<Dialog>
<DialogTrigger asChild>
<Button>Delete Account</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you absolutely sure?</DialogTitle>
<DialogDescription>
This action cannot be undone. This will permanently delete your account
and remove your data from our servers.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose asChild>
<Button variant="outline">Cancel</Button>
</DialogClose>
<Button variant="destructive">Delete Account</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}Live Example:
Form Dialog
Use Dialog for forms and data input:
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
Button,
Input
} from "@prisma-docs/eclipse";
export function FormDialog() {
return (
<Dialog>
<DialogTrigger asChild>
<Button>Edit Profile</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Edit profile</DialogTitle>
<DialogDescription>Make changes to your profile here. Click save when you're done.</DialogDescription>
</DialogHeader>
<div className="grid gap-4 py-4">
<div className="grid grid-cols-4 items-center gap-4">
<label htmlFor="name" className="text-right text-sm">
Name
</label>
<Input
id="name"
defaultValue="Pedro Duarte"
className="col-span-3 focus-visible:outline-none"
/>
</div>
<div className="grid grid-cols-4 items-center gap-4">
<label htmlFor="username" className="text-right text-sm">
Username
</label>
<Input
id="username"
defaultValue="@peduarte"
className="col-span-3 focus-visible:outline-none"
/>
</div>
</div>
<DialogFooter>
<Button type="submit">Save changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}Live Example:
Controlled Dialog
Control the dialog's open state programmatically:
import { useState } from "react";
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
Button
} from "@prisma-docs/eclipse";
export function ControlledDialog() {
const [open, setOpen] = useState(false);
const handleSubmit = () => {
// Perform some action
console.log("Action performed");
setOpen(false);
};
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button>Open Controlled Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Controlled Dialog</DialogTitle>
<DialogDescription>
This dialog's state is controlled by React state.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<Button variant="outline" onClick={() => setOpen(false)}>
Cancel
</Button>
<Button onClick={handleSubmit}>
Confirm
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}Component Props
Dialog
open- Controlled open state (boolean, optional)onOpenChange- Callback when open state changes (function, optional)defaultOpen- Default open state for uncontrolled usage (boolean, optional)modal- Whether the dialog is modal (boolean, default: true)children- Dialog components (ReactNode, required)
DialogTrigger
asChild- Merge props onto child element instead of rendering a button (boolean, default: false)children- Trigger element (ReactNode, required)
DialogContent
className- Additional CSS classes (string, optional)children- Dialog content (ReactNode, required)- All standard div props
DialogHeader
className- Additional CSS classes (string, optional)children- Header content, typically DialogTitle and DialogDescription (ReactNode, required)
DialogFooter
className- Additional CSS classes (string, optional)children- Footer content, typically action buttons (ReactNode, required)
DialogTitle
className- Additional CSS classes (string, optional)children- Title text (ReactNode, required)
DialogDescription
className- Additional CSS classes (string, optional)children- Description text (ReactNode, required)
DialogClose
asChild- Merge props onto child element (boolean, default: false)children- Close button element (ReactNode, required)
Features
- ✅ Modal overlay with backdrop
- ✅ Smooth enter/exit animations
- ✅ Automatic close button (X icon)
- ✅ Click outside to close
- ✅ Press Escape to close
- ✅ Focus trap when open
- ✅ Scroll lock on body
- ✅ Keyboard accessible
- ✅ ARIA compliant
- ✅ Controlled or uncontrolled
- ✅ Portal rendering
- ✅ Based on Radix UI Dialog
Best Practices
- Always include a
DialogTitlefor accessibility (required by screen readers) - Use
DialogDescriptionto provide additional context - Place destructive actions (like delete) on the right side of the footer
- Use
DialogClosewithasChildto make buttons closeable - Keep dialog content concise and focused
- Use controlled state when you need to perform actions before closing
- For forms, consider using the dialog's close functionality after successful submission
- Limit dialog width for better readability (
max-w-lgis the default)
Common Use Cases
The Dialog component is perfect for:
- Confirmation dialogs - Confirm destructive or important actions
- Form inputs - Collect user information without navigation
- Alerts and notifications - Display important messages requiring acknowledgment
- Content preview - Show detailed information about items
- Settings and preferences - Quick access to configuration options
- Login/Signup modals - Authentication flows
- Delete confirmations - Prevent accidental deletions
- Image or media viewers - Display full-size content
Accessibility
The Dialog component follows WAI-ARIA best practices:
- Uses proper ARIA roles and attributes
- Supports keyboard navigation (Tab, Shift+Tab, Escape)
- Traps focus within the dialog when open
- Returns focus to trigger element when closed
- Announces dialog content to screen readers
- Uses
DialogTitleas accessible name - Uses
DialogDescriptionas accessible description
Styling
The Dialog component uses Tailwind CSS classes and supports customization:
- Content:
max-w-lgwidth,p-6padding, rounded corners - Overlay: Black backdrop with 80% opacity
- Animations: Fade in/out with zoom and slide effects
- Close button: Positioned top-right with hover effects
- Header: Centered on mobile, left-aligned on desktop
- Footer: Stacked on mobile, horizontal on desktop
Customize by passing className props to any component:
<DialogContent className="max-w-2xl">
{/* Wider dialog */}
</DialogContent>CodeBlock
A syntax-highlighted code block component with copy functionality and tab support for displaying code examples.
Dropdown Menu
A dropdown menu component for displaying contextual actions, navigation items, and options with support for nested menus, checkboxes, radio groups, and keyboard navigation.