Dialog
A focused surface for decisions that need attention.
pnpm dlx shadcn@latest add @uiarc/dialogLive · keyboard ready
- Confirmations and decisions that must interrupt, such as Delete project.
- Short forms like rename or invite that fit in one focused panel.
- Flows where the dialog title changes between steps and should crossfade in place.
- Use drawer for long forms or detail panels that keep the page in context.
- Use bottom-sheet for mobile-first secondary tasks with snap heights.
- Use popover for light, non-modal content anchored to a trigger.
Installation
Add Dialog with the shadcn CLI, or copy the source by hand.
pnpm dlx shadcn@latest add @uiarc/dialogAdds the component and its local dependencies, and installs @radix-ui/react-dialog, motion, lucide-react. First time? Add the @uiarc registry to components.json, or use the full URL:
example.tsx
import { Dialog, DialogClose, DialogContent, DialogTrigger } from "@/registry/components/dialog/dialog";import { Button } from "@/registry/components/button/button"; export function RenameProject() { return ( <Dialog> <DialogTrigger asChild><Button>Rename</Button></DialogTrigger> <DialogContent title="Rename project" description="This changes the URL too."> <input defaultValue="Arc" aria-label="Project name" /> <DialogClose asChild><Button>Save</Button></DialogClose> </DialogContent> </Dialog> );}Confirm with a custom cancel
example.tsx
<Dialog open={open} onOpenChange={setOpen}> <DialogContent title="Delete project?" description="This cannot be undone."> <DialogClose asChild><Button variant="secondary">Cancel</Button></DialogClose> <Button onClick={remove}>Delete</Button> </DialogContent></Dialog>API reference
4 parts. The first is the root.
Dialog
Root that tracks open state so the content can animate out. Controlled or uncontrolled.
PropTypeDefaultDescription
openboolean–Controlled open state.defaultOpenbooleanfalseInitial open state when uncontrolled.onOpenChange(open: boolean) => void–Called when the dialog opens or closes....propsComponentPropsWithoutRef<typeof DialogPrimitive.Root>–Other Radix Dialog root props, such as modal.DialogTrigger
Radix Dialog.Trigger. Use asChild to wrap your own button.
PropTypeDefaultDescription
...propsComponentPropsWithoutRef<typeof DialogPrimitive.Trigger>–Radix trigger props, including asChild.DialogContent
Portaled overlay and panel with a titled header and built-in close button.
PropTypeDefaultDescription
titleRequiredstring–Dialog title, rendered as Radix Dialog.Title. Changes crossfade while open.descriptionstring–Optional supporting line, rendered as Dialog.Description.childrenRequiredReactNode–Body content, usually a form or actions....propsComponentPropsWithoutRef<typeof DialogPrimitive.Content>–Radix content props such as className, onEscapeKeyDown, and onPointerDownOutside.DialogClose
Radix Dialog.Close for custom cancel or confirm buttons.
PropTypeDefaultDescription
...propsComponentPropsWithoutRef<typeof DialogPrimitive.Close>–Radix close props, including asChild.- Escape
- Closes the dialog and returns focus to the trigger.
- TaborShift+Tab
- Cycles focus within the dialog.
- Radix renders role="dialog" with aria-modal, traps focus, and restores it to the trigger on close.
- title and description are wired to aria-labelledby and aria-describedby.
- The close button carries aria-label="Close dialog".
- The overlay fades while the panel rises 8px and scales from 0.96 on a smooth spring; closing is shorter and retargets from the current state.
- Title and description changes rise in with a soft blur.
- Reduced motion uses a plain opacity fade, including the CSS keyframe fallback for bare Radix roots.
- The panel is min(100vw minus a 32px gutter, 440px) wide and centered, so it fits phones without extra CSS.
- Height caps at the viewport minus a gutter and the panel scrolls beyond that.
- The overlay uses a 7px backdrop blur, which can cost frames on low-end devices over busy pages.
- Content renders in a portal only while open and unmounts after the exit animation.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Use for decisions that must interrupt: confirmations, short forms. Use drawer for side panels, bottom-sheet for mobile-first secondary tasks, popover for light non-modal content.
- Always compose Dialog > DialogTrigger + DialogContent. Wrap your own buttons with asChild.
The full library index for assistants is at /llms.txt.