Modals & Dialogs

Interactive modal dialogs, confirmation dialogs, and drawer components with comprehensive examples

WCAG AA CompliantInteractive ExamplesCopy-Paste Ready

Interactive Modal Examples

Basic Modals

Dialog Variants

Drawer Positions

Selected: Right Position

Drawer will slide in from the right side

Smooth Animation
User Context

Basic Modal

Basic Modal

import { Modal, ModalHeader, ModalBody, ModalFooter } from "~/components/ui";

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

  return (
    <>
      <button onClick={() => setIsOpen(true)}>Open Modal</button>

      <Modal isOpen={isOpen} onClose={() => setIsOpen(false)}>
        <ModalHeader onClose={() => setIsOpen(false)}>
          Modal Title
        </ModalHeader>
        <ModalBody>
          <p>Modal content goes here...</p>
        </ModalBody>
        <ModalFooter>
          <SecondaryButton onClick={() => setIsOpen(false)}>
            Cancel
          </SecondaryButton>
          <PrimaryButton onClick={() => setIsOpen(false)}>
            Confirm
          </PrimaryButton>
        </ModalFooter>
      </Modal>
    </>
  );
}

Confirmation Dialog

Confirmation Dialog

import { Dialog } from "~/components/ui";

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

  const handleDelete = () => {
    // Delete logic here
    console.log("Item deleted");
    setIsOpen(false);
  };

  return (
    <>
      <DangerButton onClick={() => setIsOpen(true)}>
        Delete Item
      </DangerButton>

      <Dialog
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        onConfirm={handleDelete}
        title="Confirm Deletion"
        message="Are you sure you want to delete this item? This action cannot be undone."
        confirmText="Delete"
        cancelText="Cancel"
        variant="danger"
      />
    </>
  );
}

Drawer/Sidebar

Drawer/Sidebar

import { Drawer, DrawerHeader, DrawerBody } from "~/components/ui";

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

  return (
    <>
      <button onClick={() => setIsOpen(true)}>Open Menu</button>

      <Drawer isOpen={isOpen} onClose={() => setIsOpen(false)} position="right">
        <DrawerHeader onClose={() => setIsOpen(false)}>
          Navigation Menu
        </DrawerHeader>
        <DrawerBody>
          <nav className="space-y-2">
            <a href="/dashboard" className="block px-4 py-2 hover:bg-gray-100 rounded">
              Dashboard
            </a>
            <a href="/settings" className="block px-4 py-2 hover:bg-gray-100 rounded">
              Settings
            </a>
          </nav>
        </DrawerBody>
      </Drawer>
    </>
  );
}

Advanced Modal Examples

Loading & Progress

Show progress indicators and loading states

Multi-Step Wizards

Guided multi-step processes

Image Gallery

Interactive image viewing with navigation

Settings & Config

Configuration panels and preferences

Modal Features & Best Practices

Focus Management

Automatic focus trapping within modals and proper focus restoration when closed.

Keyboard Navigation

Full keyboard support with Escape key to close and Tab navigation within modals.

Accessibility

WCAG AA compliant with proper ARIA labels, roles, and screen reader support.

Responsive Design

Mobile-first approach with touch-friendly interactions and adaptive layouts.

✅ Do's

  • Use modals for focused, important actions or information
  • Always provide clear, descriptive modal titles
  • Include proper close buttons (X) and keyboard shortcuts
  • Keep modal content focused and avoid information overload
  • Use appropriate dialog variants for different contexts

❌ Don'ts

  • Don't use modals for navigation or primary app content
  • Avoid nested modals (one modal at a time)
  • Don't make modals too wide or too tall for mobile screens
  • Avoid auto-opening modals without user interaction
  • Don't use modals for simple confirmations - use inline dialogs