Modal

Use modals sparingly to display content that requires user attention or action before continuing. Built with Radix UI Dialog for full accessibility.

Interactive Examples

Click the buttons below to open the modals:

import * as Dialog from '@radix-ui/react-dialog';
import { X } from 'lucide-react';

const [isOpen, setIsOpen] = useState(false);

<Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
  <Dialog.Trigger asChild>
    <button className="btn btn-primary">Open modal</button>
  </Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Overlay className="radix-dialog-overlay" />
    <Dialog.Content className="radix-dialog-content">
      <div className="radix-dialog-header">
        <Dialog.Title className="radix-dialog-title">
          Are you sure?
        </Dialog.Title>
        <Dialog.Close asChild>
          <button className="radix-dialog-close" aria-label="Close">
            <X size={20} />
          </button>
        </Dialog.Close>
      </div>
      <div className="radix-dialog-body">
        <p>This action cannot be undone.</p>
      </div>
      <div className="radix-dialog-footer">
        <Dialog.Close asChild>
          <button className="btn btn-secondary">Cancel</button>
        </Dialog.Close>
        <button className="btn btn-primary">Delete</button>
      </div>
    </Dialog.Content>
  </Dialog.Portal>
</Dialog.Root>

When to Use Modals

Use modals for:

  • Confirming destructive actions (delete, cancel)
  • Important warnings that need acknowledgment
  • Session timeout warnings
  • Simple forms that don't need a new page

Don't use modals for:

  • Long content that requires scrolling
  • Complex forms with many fields
  • Information users might want to reference
  • Marketing messages or promotions

Usage Guidelines

Do

  • Provide a clear title describing the purpose
  • Include a close button and escape key dismissal
  • Keep content brief and focused
  • Use clear action labels on buttons

Don't

  • Don't open modals without user action
  • Don't stack multiple modals
  • Don't use for non-essential information
  • Don't make the modal uncloseable

Accessibility

  • Built with Radix UI Dialog for full WAI-ARIA compliance
  • Focus automatically moves to the dialog when opened
  • Focus is trapped within the dialog while open
  • Escape key closes the dialog
  • Focus returns to trigger element when closed
  • Background content is automatically hidden from screen readers
  • Click outside to close (optional)

CSS Classes

/* Radix Dialog */
.radix-dialog-overlay { }
.radix-dialog-content { }
.radix-dialog-header { }
.radix-dialog-title { }
.radix-dialog-close { }
.radix-dialog-body { }
.radix-dialog-footer { }

Installation

npm install @radix-ui/react-dialog lucide-react