apps/eclipse/content/design-system/components/dialog.mdx
import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, DialogClose, Button, Input } from "@prisma/eclipse";
Basic Dialog
The Dialog component displays content in a modal overlay that requires user interaction.
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription
} from "@prisma/eclipse";
import { Button } from "@prisma/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>
);
}
Dialog with Footer
Add action buttons in the footer for user interactions:
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
DialogClose,
Button
} from "@prisma/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>
);
}
Form Dialog
Use Dialog for forms and data input:
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
Button,
Input
} from "@prisma/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>
);
}
Controlled Dialog
Control the dialog's open state programmatically:
import { useState } from "react";
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
Button
} from "@prisma/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>
);
}
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)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)DialogTitle for accessibility (required by screen readers)DialogDescription to provide additional contextDialogClose with asChild to make buttons closeablemax-w-lg is the default)The Dialog component is perfect for:
The Dialog component follows WAI-ARIA best practices:
DialogTitle as accessible nameDialogDescription as accessible descriptionThe Dialog component uses Tailwind CSS classes and supports customization:
max-w-lg width, p-6 padding, rounded cornersCustomize by passing className props to any component:
<DialogContent className="max-w-2xl">
</DialogContent>