Components
Dialog
Blocks the page until dismissed. Reserve for decisions that shouldn't be interrupted; anything else can be a side sheet or inline form.
When to usefor a focused decision that can't be deferred — a form the user must finish or a confirmation before continuing.
Import
import {
Dialog, DialogTrigger, DialogContent,
DialogHeader, DialogTitle, DialogDescription,
DialogFooter, DialogClose,
} from "@ravnhq/efni/dialog"Default
<Dialog>
<DialogTrigger render={<Button variant="outline">Rename mission</Button>} />
<DialogContent>
<DialogHeader>
<DialogTitle>Rename mission</DialogTitle>
<DialogDescription>Choose a short, unique name.</DialogDescription>
</DialogHeader>
<Input defaultValue="MB-4472" />
<DialogFooter>
<DialogClose render={<Button variant="outline">Cancel</Button>} />
<Button>Save</Button>
</DialogFooter>
</DialogContent>
</Dialog>Accessibility
| Key | Action |
|---|---|
| Escape | Close the dialog. |
| Tab / Shift+Tab | Focus is trapped inside the dialog. |
- Always give the dialog a
DialogTitle— Base UI wiresaria-labelledbyto it. UseDialogDescriptionfor context. - Focus returns to the trigger when the dialog closes.
- The overlay dismisses on click by default; disable that when data can be lost.
Guidelines
Do
- Lead with a verb in the title — Rename mission, Delete operator.
- Put the primary action on the right, secondary/cancel on the left.
- Keep the body scannable in one screen — if it doesn't fit, use a Sheet.
Don't
- Don't stack dialogs — chain steps in a single one or hand off to a Sheet.
- Don't use a dialog for transient success — that's Toast.
- Don't let the primary action be Close — the primary is what the user came to do.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Whether the dialog is currently open. |
onOpenChange | ((open: boolean, eventDetails: DialogRoot.ChangeEventDetails) => void) | — | Event handler called when the dialog is opened or closed. |
defaultOpen | boolean | false | Whether the dialog is initially open. To render a controlled dialog, use the open prop instead. |
DialogTrigger.render | React.ReactElement | ComponentRenderFn<RenderFunctionProps, State> | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
DialogClose.render | React.ReactElement | ComponentRenderFn<RenderFunctionProps, State> | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
DialogContent.showCloseButton | boolean | true | Render the corner close button. |
…props | DialogPrimitive.Root.Props | — | Everything Dialog passes to the element it renders. |
DialogContent | HTMLAttributes<HTMLDivElement> | — | Content root; native div attributes pass through. |