Use Dialog to display contextual information, tasks, or workflows that appear over the user interface. Depending on the kind of dialog, further interactions may be blocked until the dialog is acknowledged.
Options
Title
Dialog is labeled with a title to provide context to the user. Use the title prop to provide a title for the dialog.
If a dialog does not have a visible heading element, an aria-label or aria-labelledby prop must be passed instead to identify the element to assistive technology.
A description can be supplied to the dialog via the description prop.
description.tsx
<DialogRoot> <Button variant="outline">Edit username</Button> <Dialog title="Edit username" description="Make changes to your username."> <TextField label="Username" defaultValue="@mehdibha_" className="w-full" /> </Dialog></DialogRoot>
Type
Dialogs can be rendered as modals, popovers, or drawers using the type prop.
By default, dialogs are displayed as drawers on mobile. You can override this behavior by setting the mobileType prop.
By default, dialogs are dismissable allowing users to click outside to close the dialog. You can disable this behavior by setting the isDismissable prop.
Use the type="drawer" prop on the <Dialog> element to make a drawer dialog.
Placement
drawer.tsx
"use client";import React from "react";import type { Key } from "react-aria-components";import { Button } from "@/registry/ui/default/core/button";import { DialogRoot, Dialog } from "@/registry/ui/default/core/dialog";import { Item } from "@/registry/ui/default/core/list-box";import { Select } from "@/registry/ui/default/core/select";import { Switch } from "@/registry/ui/default/core/switch";export default function Demo() { const [placement, setPlacement] = React.useState<Key>("top"); const [swipeable, setSwipeable] = React.useState<boolean>(true); return ( <div className="flex w-full items-center"> <div className="flex flex-1 items-center justify-center"> <DialogRoot> <Button variant="outline">Open drawer</Button> <Dialog type="drawer" title="Help" description="For help accessing your account, please contact support." /> </DialogRoot> </div> <div className="space-y-4 rounded-md border p-4"> <Select label="Placement" selectedKey={placement} onSelectionChange={setPlacement} > <Item id="top">Top</Item> <Item id="bottom">Bottom</Item> </Select> <Switch isSelected={swipeable} onChange={setSwipeable}> Swipeable </Switch> </div> </div> );}
Alert Dialog
Use the role="alertdialog" prop on the <Dialog> element to make an alert dialog.
If the isDismissable prop is not explicitly set, the dialog will be not dismissable.
alert-dialog.tsx
"use client";import React from "react";import { Button } from "@/registry/ui/default/core/button";import { DialogRoot, Dialog, DialogFooter,} from "@/registry/ui/default/core/dialog";export default function Demo() { return ( <DialogRoot> <Button variant="danger">Delete project</Button> <Dialog title="Delete project" description="Are you sure you want to delete this project? This action is permanent and cannot be undone." role="alertdialog" // isDissmissible={false} > {({ close }) => ( <> <DialogFooter> <Button variant="outline" size={{ initial: "lg", sm: "md" }} onPress={close} > Cancel </Button> <Button variant="danger" size={{ initial: "lg", sm: "md" }} onPress={close} > Delete project </Button> </DialogFooter> </> )} </Dialog> </DialogRoot> );}
Controlled
Use the isOpen and onOpenChange props to control the dialog's open state.
controlled.tsx
"use client";import React from "react";import { Button } from "@/registry/ui/default/core/button";import { DialogRoot, Dialog, DialogFooter,} from "@/registry/ui/default/core/dialog";import { TextField } from "@/registry/ui/default/core/text-field";export default function Demo() { return ( <DialogRoot> <Button variant="outline">Edit Profile</Button> <Dialog title="Edit profile" description="Make changes to your profile."> {({ close }) => ( <> <div className="space-y-4"> <TextField autoFocus label="Name" defaultValue="Mehdi" /> <TextField label="Username" defaultValue="@mehdibha_" /> </div> <DialogFooter> <Button variant="outline" size={{ initial: "lg", sm: "md" }} onPress={close} > Cancel </Button> <Button variant="primary" size={{ initial: "lg", sm: "md" }} onPress={close} > Save changes </Button> </DialogFooter> </> )} </Dialog> </DialogRoot> );}
Composition
If you need to customize things further, you can drop down to the composition level.
composition.tsx
import React from "react";import { Button } from "@/registry/ui/default/core/button";import { DialogRoot, Dialog } from "@/registry/ui/default/core/dialog";import { TextField } from "@/registry/ui/default/core/text-field";export default function Demo() { return ( <DialogRoot> <Button variant="outline">Edit username</Button> <Dialog title="Edit username"> <TextField label="Username" defaultValue="@mehdibha_" /> </Dialog> </DialogRoot> );}