Components
Dialog
A modal window for a short, focused task - with focus trapping, focus return and a labelled close button.
Loading...
Installation
npx shadcn@latest add @fujin/dialogUsage
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"<Dialog>
<DialogTrigger render={<Button variant="outline">Edit profile</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Edit profile</DialogTitle>
<DialogDescription>Update your name and username.</DialogDescription>
</DialogHeader>
{/* fields */}
<DialogFooter>
<DialogClose render={<Button variant="outline" />}>Cancel</DialogClose>
<Button type="submit">Save changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>Forms: keep what the user typed
Base UI unmounts the popup when the dialog closes, so uncontrolled inputs are reset every time it reopens. If closing by accident (Esc, a stray click on the backdrop) should not cost the user their input, keep the draft in state outside the dialog, as the demo does:
const [open, setOpen] = React.useState(false)
const [draft, setDraft] = React.useState(profile)
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent>
<form
onSubmit={(event) => {
event.preventDefault()
save(draft)
setOpen(false)
}}
>
<Input
value={draft.name}
onValueChange={(name) => setDraft({ ...draft, name })}
/>
</form>
</DialogContent>
</Dialog>Opening from a menu
Control the dialog and open it from the menu item's onClick. Nesting the
Dialog inside DropdownMenuContent unmounts it as soon as the menu closes.
const [open, setOpen] = React.useState(false)
<DropdownMenuItem onClick={() => setOpen(true)}>Rename...</DropdownMenuItem>
<Dialog open={open} onOpenChange={setOpen}>...</Dialog>What's different from shadcn/ui
renderreplacesasChild, from Base UI.- The close button is a 32px
Button(shadcn's is a 16px icon), so it clears the WCAG 2.5.8 24px minimum target size, and it has a solid focus ring. - The popup is capped at the viewport height and scrolls internally, so a long form never pushes the footer off-screen.
API Reference
Prop
Type
Every other prop is forwarded to the Base UI Dialog.