Dialog
A modal dialog that interrupts the user's flow with important content and requires a response.
Overview
Dialog is a compound component that renders a modal overlay that traps focus and blocks interaction with the rest of the page until the user dismisses it. Use Dialog for confirmations, forms, or content that requires an explicit user decision.
- Composed with a compound API:
Dialog,Dialog.Trigger,Dialog.Content,Dialog.Title,Dialog.Description,Dialog.Close - Focus is trapped inside while the dialog is open.
- Pressing the
Escapekey closes the dialog by default. - Three content sizes are supported:
small,medium,large. - Supports both controlled (
open+onOpenChange) and uncontrolled (defaultOpen) usage.
Guidelines
- Use Dialog for actions requiring explicit user confirmation — deleting records, discarding unsaved changes, or submitting irreversible operations.
- For non-blocking supplementary content, use Popover instead.
- Always include at least one
Dialog.Closeaction so users can dismiss the dialog.
Accessibility
- Focus is trapped inside the dialog while open. On close, focus returns to the trigger element.
Escapecloses the dialog by default.- Opening the dialog moves focus to the first focusable element inside the content area.
Dialog.Titleis linked viaaria-labelledbyandDialog.Descriptionviaaria-describedby, providing context for screen readers.- Background content receives
aria-hidden="true"while the dialog is open, preventing screen readers from accessing it. - When
modalisfalse, the dialog becomes non-modal — focus is not trapped and background interaction is allowed.
Import
import { Dialog } from "@cocso-ui/react";Default
A dialog with a title, description, and action buttons.
"use client";
import { Button, Dialog } from "@cocso-ui/react";
export default function DialogDefault() {
return (
<div className="p-4">
<Dialog>
<Dialog.Trigger render={<Button />}>Open Dialog</Dialog.Trigger>
<Dialog.Content>
<Dialog.Title>Confirm Action</Dialog.Title>
<Dialog.Description>
Are you sure you want to proceed? This action cannot be undone.
</Dialog.Description>
<div className="mt-4 flex justify-end gap-2">
<Dialog.Close render={<Button variant="secondary" />}>Cancel</Dialog.Close>
<Dialog.Close render={<Button variant="primary" />}>Confirm</Dialog.Close>
</div>
</Dialog.Content>
</Dialog>
</div>
);
}Size
The
size prop on Dialog.Content controls the maximum width of the dialog panel."use client";
import { Button, Dialog } from "@cocso-ui/react";
export default function DialogSizes() {
return (
<div className="flex flex-wrap gap-3 p-4">
{(["small", "medium", "large"] as const).map((size) => (
<Dialog key={size}>
<Dialog.Trigger render={<Button variant="secondary" />}>{size}</Dialog.Trigger>
<Dialog.Content size={size}>
<Dialog.Title>Dialog — {size}</Dialog.Title>
<Dialog.Description>This is a {size} dialog.</Dialog.Description>
<div className="mt-4 flex justify-end">
<Dialog.Close render={<Button variant="primary" />}>Close</Dialog.Close>
</div>
</Dialog.Content>
</Dialog>
))}
</div>
);
}API Reference
Dialog (Root Container)
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | - | Controlled open state. Use together with `onOpenChange` for full control over visibility. |
onOpenChange | (open: boolean) => void | - | Callback invoked when the dialog should open or close. Receives the new boolean state. |
defaultOpen | boolean | false | Initial open state for uncontrolled usage. The component manages open/close internally. |
modal | boolean | true | When `true`, traps focus inside the dialog and blocks background interaction with an overlay. Set to `false` for non-modal usage. |
Dialog.Trigger
| Prop | Type | Default | Description |
|---|---|---|---|
render* | ReactElement | - | The element to render as the trigger button. Receives `onClick` handler and `aria-expanded` via prop merging. |
Dialog.Content
| Prop | Type | Default | Description |
|---|---|---|---|
size | "small" | "medium" | "large" | "medium" | Controls the maximum width of the dialog panel. `small` (400px) for confirmations, `medium` (560px) for forms, `large` (720px) for complex content. |
Dialog.Close
| Prop | Type | Default | Description |
|---|---|---|---|
render | ReactElement | - | The element to render as the close action. Receives `onClick` handler to close the dialog via prop merging. |
Dialog.Title
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | - | Title text displayed at the top of the dialog. Linked to the dialog via `aria-labelledby` for screen readers. |
Dialog.Description
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | - | Description text providing context for the dialog action. Linked via `aria-describedby` for screen readers. |