메인 콘텐츠로 이동

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 Escape key 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.Close action so users can dismiss the dialog.

Accessibility

  • Focus is trapped inside the dialog while open. On close, focus returns to the trigger element.
  • Escape closes the dialog by default.
  • Opening the dialog moves focus to the first focusable element inside the content area.
  • Dialog.Title is linked via aria-labelledby and Dialog.Description via aria-describedby, providing context for screen readers.
  • Background content receives aria-hidden="true" while the dialog is open, preventing screen readers from accessing it.
  • When modal is false, 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)

PropTypeDefaultDescription
openboolean-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.
defaultOpenbooleanfalseInitial open state for uncontrolled usage. The component manages open/close internally.
modalbooleantrueWhen `true`, traps focus inside the dialog and blocks background interaction with an overlay. Set to `false` for non-modal usage.

Dialog.Trigger

PropTypeDefaultDescription
render*ReactElement-The element to render as the trigger button. Receives `onClick` handler and `aria-expanded` via prop merging.

Dialog.Content

PropTypeDefaultDescription
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

PropTypeDefaultDescription
renderReactElement-The element to render as the close action. Receives `onClick` handler to close the dialog via prop merging.

Dialog.Title

PropTypeDefaultDescription
children*ReactNode-Title text displayed at the top of the dialog. Linked to the dialog via `aria-labelledby` for screen readers.

Dialog.Description

PropTypeDefaultDescription
children*ReactNode-Description text providing context for the dialog action. Linked via `aria-describedby` for screen readers.