Dialog

A focused surface for decisions that need attention.

pnpm dlx shadcn@latest add @uiarc/dialog
Live · 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/dialog

Adds 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.
/components/dialog/markdown

The full library index for assistants is at /llms.txt.