Dialog
Modal dialog component built on Radix Dialog. Use it for confirmations, forms, and focused tasks.
Focused modal tasksLink to section
The Dialog component renders a modal overlay for focused tasks that need the user’s attention.
Use it for:
- confirmations
- short forms
- destructive decisions
- focused create or edit flows
- tasks that should not navigate away from the current page
Dialog is built on Radix Dialog and styled with PyColors tokens such as bg-card, border-border, and text-card-foreground.
Core idea
Dialog is for focused decisions or tasks. If the flow becomes long, navigational, or multi-step, use a Sheet or a dedicated page.
ImportLink to section
import { Dialog } from "@pycolors/ui";Basic usageLink to section
Use Dialog for a focused form or short task that should stay in context.
import {
Button,
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
DialogClose,
Input,
} from "@pycolors/ui";
export function EditProfileDialog() {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="outline" size="sm">
Open dialog
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Edit profile</DialogTitle>
<DialogDescription>
Update your account details. Changes are saved on submit.
</DialogDescription>
</DialogHeader>
<div className="mt-4 grid gap-3">
<Input label="Name" placeholder="Patrice" />
<Input label="Email" placeholder="patrice@pycolors.com" />
</div>
<DialogFooter>
<DialogClose asChild>
<Button variant="secondary">Cancel</Button>
</DialogClose>
<Button>Save</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}When to use DialogLink to section
Use Dialog when the user must complete, confirm, or cancel a focused task.
Confirmation
Confirm risky or irreversible actions before they happen.
Short form
Edit a small piece of data without leaving the current page.
Focused task
Keep the user focused on one bounded action with clear choices.
Destructive confirmationLink to section
Use Dialog for destructive actions that require explicit user intent.
import {
Button,
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
DialogClose,
} from "@pycolors/ui";
export function DeleteDialog() {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="destructive" size="sm">
Delete…
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Delete project</DialogTitle>
<DialogDescription>
This action can’t be undone. This will permanently delete the project and its data.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose asChild>
<Button variant="secondary">Cancel</Button>
</DialogClose>
<Button variant="destructive">Delete</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}Destructive flow rule
The destructive action should be explicit, visually distinct, and placed after the safer option.
Usage patternsLink to section
Trigger with a semantic elementLink to section
Use DialogTrigger asChild with a Button or another semantic trigger.
Provide clear contextLink to section
Every dialog should have a DialogTitle and a useful DialogDescription.
Keep the content focusedLink to section
A dialog should usually contain one task, one form, or one decision.
Place actions in the footerLink to section
Keep cancel and confirm actions in DialogFooter for predictable placement.
Close only when the task is complete or canceledLink to section
Do not close the dialog automatically if submission fails. Show the error in context.
Dialog vs Sheet vs Dropdown MenuLink to section
| Situation | Use |
|---|---|
| Confirm destructive action | Dialog |
| Short focused form | Dialog |
| Create or edit a small record | Dialog |
| Advanced filters | Sheet |
| Side workflow or details panel | Sheet |
| Row actions or small contextual menu | DropdownMenu |
| Long multi-step flow | Page or Sheet |
Decision rule
Dialog blocks the page for one focused task. Sheet extends the page for side workflows. DropdownMenu exposes quick actions.
APILink to section
ComponentsLink to section
| Component | Description |
|---|---|
Dialog | Root container |
DialogTrigger | Trigger element, usually with asChild |
DialogContent | Modal surface, overlay, and close behavior |
DialogHeader | Title and description stack helper |
DialogFooter | Action row helper |
DialogTitle | Accessible dialog title |
DialogDescription | Supporting text |
DialogClose | Close control, usually wrapping a Button with asChild |
Props
Dialog components extend their respective Radix Dialog props.
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Root>
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Trigger>
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Close>AccessibilityLink to section
- Dialog is built on Radix Dialog primitives.
- Focus is trapped inside the dialog while open.
- Focus is restored to the trigger when the dialog closes.
- Escape should close the dialog unless the flow requires careful custom handling.
- Every dialog needs a clear
DialogTitle. - Use
DialogDescriptionto explain the task or risk. - Avoid nested dialogs.
- Do not use Dialog for long navigational flows.
Accessibility rule
A dialog without a clear title is not a complete dialog. The title gives assistive technology users the context they need.
Prefer / avoidLink to section
Prefer
- one task per dialog
- clear title and short description
- semantic trigger with
asChild - cancel and confirm actions in the footer
- inline error feedback for failed submissions
Avoid
- long multi-step workflows
- nested dialogs
- dialogs without titles
- closing on submit errors
- using Dialog for simple row actions
Product copy guidelinesLink to section
Dialog copy should be direct and specific.
Create project
Give your project a name. You can change these details later.
Edit profile
Update your account details. Changes are saved when you submit.
Delete project
This action can’t be undone. This will permanently delete the project and its data.