# Modal

## Introduction

The Modal component is a dialog overlay that appears on top of the main content, demanding user attention and interaction. Built on Joy UI's Modal, it is used for displaying critical information, capturing user input, or requiring confirmation before proceeding. Modals block interaction with the underlying page until dismissed, making them ideal for important actions that require focused attention.

```tsx
<>
  <Button onClick={() => setOpen(true)}>Open Modal</Button>
  <Modal open={open} onClose={() => setOpen(false)}>
    <ModalDialog>
      <ModalClose />
      <DialogTitle>Modal Title</DialogTitle>
      <DialogContent>This is the modal content. You can place any content here.</DialogContent>
      <DialogActions>
        <Button variant="solid" onClick={() => setOpen(false)}>
          Confirm
        </Button>
        <Button variant="plain" color="neutral" onClick={() => setOpen(false)}>
          Cancel
        </Button>
      </DialogActions>
    </ModalDialog>
  </Modal>
</>
```

| Field                        | Description | Default |
| ---------------------------- | ----------- | ------- |
| Controls resolved at runtime | —           | —       |

> ⚠️ **Usage Warning** ⚠️
>
> Modals interrupt the user's current workflow and should be used sparingly.
>
> - Use only when user confirmation or required input is absolutely necessary
> - For simple information display, consider using Alert or Toast instead
> - Complex multi-step forms should be placed on separate pages
> - Avoid using modals for content that users need to reference while interacting with the page

## Usage

```tsx
import { Modal, ModalDialog, ModalClose, DialogTitle, DialogContent, DialogActions, Button } from '@ceed/cds';

function MyComponent() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>Open Modal</Button>
      <Modal open={open} onClose={() => setOpen(false)}>
        <ModalDialog>
          <ModalClose />
          <DialogTitle>Modal Title</DialogTitle>
          <DialogContent>Place your content here.</DialogContent>
          <DialogActions>
            <Button onClick={() => setOpen(false)}>Close</Button>
          </DialogActions>
        </ModalDialog>
      </Modal>
    </>
  );
}
```

### ModalFrame Usage

`ModalFrame` is a convenience component that combines `ModalDialog` + `ModalClose` + `DialogTitle` + `DialogContent` into a single composable unit.
It provides a concise way to build modals with a title, close button, and content area.

```tsx
import { Modal, ModalFrame } from '@ceed/cds';

function DetailModal({ open, onClose }) {
  return (
    <Modal open={open} onClose={onClose}>
      <ModalFrame title="Detail" onClose={onClose}>
        Content goes here.
      </ModalFrame>
    </Modal>
  );
}
```

> **Note**: Connect the same handler to both `Modal`'s `onClose` and `ModalFrame`'s `onClose`.
> `Modal` handles backdrop click and ESC key, while `ModalFrame` handles the X button click.

## Examples

### Basic Modal

The basic modal with a simple Sheet for custom layouts.

```tsx
<>
  <Button onClick={() => setOpen(true)}>Open Basic Modal</Button>
  <Modal aria-labelledby="modal-title" aria-describedby="modal-desc" open={open} onClose={() => setOpen(false)} sx={{
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center'
  }}>
  <Sheet variant="outlined" sx={{
    maxWidth: 500,
    borderRadius: 'md',
    p: 3,
    boxShadow: 'lg'
  }}>
  <ModalClose variant="plain" sx={{
    m: 1
  }} />
  <Typography component="h2" id="modal-title" level="h4" textColor="inherit" fontWeight="lg" mb={2}>
    This is the modal title
  </Typography>
  <Typography id="modal-desc" textColor="text.tertiary">
    Make sure to use <code>aria-labelledby</code> on the modal dialog with an optional{' '}
    <code>aria-describedby</code> attribute.
  </Typography>
</Sheet>
</Modal>
</>
```

### Modal Dialog

Use ModalDialog for structured dialogs with title, content, and actions.

```tsx
<>
  <Button onClick={() => setOpen(true)}>Open Form Modal</Button>
  <Modal open={open} onClose={() => setOpen(false)}>
    <ModalDialog>
      <ModalClose />
      <DialogTitle>Create new project</DialogTitle>
      <DialogContent>
        Fill in the information of the project.
        <form onSubmit={(event: React.FormEvent<HTMLFormElement>) => {
          event.preventDefault();
          setOpen(false);
        }}>
        <Stack spacing={4}>
          <FormControl>
            <FormLabel>Name</FormLabel>
            <Input required />
          </FormControl>
          <FormControl>
            <FormLabel>Description</FormLabel>
            <Input required />
          </FormControl>
          <Button type="submit">Submit</Button>
        </Stack>
      </form>
    </DialogContent>
  </ModalDialog>
</Modal>
</>
```

### Variants

Modal dialogs support different visual variants.

#### Plain Variant

```tsx
<>
  <Button onClick={() => setOpen(true)}>Plain Variant</Button>
  <Modal open={open} onClose={() => setOpen(false)}>
    <ModalDialog variant="plain">
      <ModalClose />
      <DialogTitle>Modal Dialog</DialogTitle>
      <DialogContent>This is a `plain` modal dialog.</DialogContent>
    </ModalDialog>
  </Modal>
</>
```

#### Outlined Variant

```tsx
<>
  <Button onClick={() => setOpen(true)}>Outlined Variant</Button>
  <Modal open={open} onClose={() => setOpen(false)}>
    <ModalDialog variant="outlined">
      <ModalClose />
      <DialogTitle>Modal Dialog</DialogTitle>
      <DialogContent>This is an `outlined` modal dialog.</DialogContent>
    </ModalDialog>
  </Modal>
</>
```

#### Soft Variant

```tsx
<>
  <Button onClick={() => setOpen(true)}>Soft Variant</Button>
  <Modal open={open} onClose={() => setOpen(false)}>
    <ModalDialog variant="soft">
      <ModalClose />
      <DialogTitle>Modal Dialog</DialogTitle>
      <DialogContent>This is a `soft` modal dialog.</DialogContent>
    </ModalDialog>
  </Modal>
</>
```

#### Solid Variant

```tsx
<>
  <Button onClick={() => setOpen(true)}>Solid Variant</Button>
  <Modal open={open} onClose={() => setOpen(false)}>
    <ModalDialog variant="solid">
      <ModalClose />
      <DialogTitle>Modal Dialog</DialogTitle>
      <DialogContent>This is a `solid` modal dialog.</DialogContent>
    </ModalDialog>
  </Modal>
</>
```

### Alert Dialog

For critical confirmations that require explicit user decision.

```tsx
<>
  <Button color="danger" onClick={() => setOpen(true)}>
    Delete Item
  </Button>
  <Modal open={open} onClose={() => setOpen(false)}>
    <ModalDialog variant="outlined" role="alertdialog">
      <DialogTitle>
        <WarningRoundedIcon />
        Confirmation
      </DialogTitle>
      <Divider />
      <DialogContent>Are you sure you want to discard all of your notes?</DialogContent>
      <DialogActions>
        <Button variant="solid" color="danger" onClick={() => setOpen(false)}>
          Discard notes
        </Button>
        <Button variant="plain" color="neutral" onClick={() => setOpen(false)}>
          Cancel
        </Button>
      </DialogActions>
    </ModalDialog>
  </Modal>
</>
```

### Layouts

#### Fullscreen Layout

For complex content that requires maximum screen space.

```tsx
<>
  <Button onClick={() => setOpen(true)}>Open Fullscreen Modal</Button>
  <Modal open={open} onClose={() => setOpen(false)}>
    <ModalDialog layout="fullscreen">
      <ModalClose />
      <DialogTitle>Fullscreen Modal</DialogTitle>
      <DialogContent>This modal takes up the entire screen.</DialogContent>
      <DialogActions>
        <Button variant="solid" onClick={() => setOpen(false)}>
          Save
        </Button>
      </DialogActions>
    </ModalDialog>
  </Modal>
</>
```

### Nested Modals

Modals can be stacked on top of each other when necessary.

```tsx
<>
  <Button onClick={() => setFirstOpen(true)}>Open First Modal</Button>
  <Modal open={firstOpen} onClose={() => setFirstOpen(false)}>
    <ModalDialog>
      <ModalClose />
      <DialogTitle>First Modal</DialogTitle>
      <DialogContent>This is the first modal. Click the button below to open a nested modal.</DialogContent>
      <DialogActions>
        <Button onClick={() => setSecondOpen(true)}>Open Nested Modal</Button>
      </DialogActions>
    </ModalDialog>
  </Modal>
  <Modal open={secondOpen} onClose={() => setSecondOpen(false)}>
    <ModalDialog>
      <ModalClose />
      <DialogTitle>Nested Modal</DialogTitle>
      <DialogContent>This is a nested modal on top of the first one.</DialogContent>
      <DialogActions>
        <Button onClick={() => setSecondOpen(false)}>Close</Button>
      </DialogActions>
    </ModalDialog>
  </Modal>
</>
```

### ModalFrame

ModalFrame is a convenience component that automatically provides a title, close button, and content area.

#### ModalFrame Playground

```tsx
<>
  <Button onClick={() => setOpen(true)}>Open ModalFrame</Button>
  <Modal open={open} onClose={() => setOpen(false)}>
    <ModalFrame title="ModalFrame Title" onClose={() => setOpen(false)}>
      <Typography>
        ModalFrame automatically composes ModalDialog, ModalClose, DialogTitle, and DialogContent. You only need
        to provide a title, onClose handler, and children.
      </Typography>
    </ModalFrame>
  </Modal>
</>
```

#### titleStartDecorator

Display an icon or decorative element before the title.

```tsx
<>
  <Button onClick={() => setOpen(true)}>With Decorator</Button>
  <Modal open={open} onClose={() => setOpen(false)}>
    <ModalFrame title="Details" titleStartDecorator={<InfoOutlinedIcon />} onClose={() => setOpen(false)}>
      <Typography>
        Use the <code>titleStartDecorator</code> prop to display an icon or element before the title.
      </Typography>
    </ModalFrame>
  </Modal>
</>
```

#### Form Content

An inline form pattern where the submit button lives inside the content area.

```tsx
<>
  <Button onClick={() => setOpen(true)}>Form in ModalFrame</Button>
  <Modal open={open} onClose={() => setOpen(false)}>
    <ModalFrame title="Create Project" onClose={() => setOpen(false)}>
      <form onSubmit={(event: React.FormEvent<HTMLFormElement>) => {
        event.preventDefault();
        setOpen(false);
      }}>
      <Stack spacing={2}>
        <FormControl>
          <FormLabel>Name</FormLabel>
          <Input required />
        </FormControl>
        <FormControl>
          <FormLabel>Description</FormLabel>
          <Input required />
        </FormControl>
        <Button type="submit">Submit</Button>
      </Stack>
    </form>
  </ModalFrame>
</Modal>
</>
```

#### Sizes

Compare sm / md / lg sizes side by side.

```tsx
<Stack direction="row" spacing={2}>
  <Button size="sm" onClick={() => setOpenSm(true)}>
    Small
  </Button>
  <Button size="md" onClick={() => setOpenMd(true)}>
    Medium
  </Button>
  <Button size="lg" onClick={() => setOpenLg(true)}>
    Large
  </Button>
  <Modal open={openSm} onClose={() => setOpenSm(false)}>
    <ModalFrame title="Small ModalFrame" size="sm" onClose={() => setOpenSm(false)}>
      <Typography>This is a small ModalFrame.</Typography>
    </ModalFrame>
  </Modal>
  <Modal open={openMd} onClose={() => setOpenMd(false)}>
    <ModalFrame title="Medium ModalFrame" size="md" onClose={() => setOpenMd(false)}>
      <Typography>This is a medium ModalFrame.</Typography>
    </ModalFrame>
  </Modal>
  <Modal open={openLg} onClose={() => setOpenLg(false)}>
    <ModalFrame title="Large ModalFrame" size="lg" onClose={() => setOpenLg(false)}>
      <Typography>This is a large ModalFrame.</Typography>
    </ModalFrame>
  </Modal>
</Stack>
```

#### Custom Content

A layout example suited for displaying detailed information.

```tsx
<>
  <Button onClick={() => setOpen(true)}>Custom Content</Button>
  <Modal open={open} onClose={() => setOpen(false)}>
    <ModalFrame title="Order Details" onClose={() => setOpen(false)}>
      <Stack spacing={2}>
        <Box>
          <Typography level="title-sm">Order ID</Typography>
          <Typography level="body-sm">ORD-2024-00123</Typography>
        </Box>
        <Divider />
        <Box>
          <Typography level="title-sm">Customer</Typography>
          <Typography level="body-sm">John Doe</Typography>
        </Box>
        <Divider />
        <Box>
          <Typography level="title-sm">Status</Typography>
          <Typography level="body-sm" color="success">
            Completed
          </Typography>
        </Box>
      </Stack>
    </ModalFrame>
  </Modal>
</>
```

#### Standalone

ModalFrame can be used without a Modal wrapper for embedding dialog-style layouts directly within a page.

> ⚠️ **Important** ⚠️
>
> When using ModalFrame without Modal, the parent container **must** provide explicit `width` and `height` values.
> ModalFrame inherits its dimensions from `ModalDialog`, which normally receives sizing from the Modal overlay.
> Without these constraints, the component will not render with correct dimensions.

```tsx
<Box sx={{
  width: 480,
  height: 300
}}>
<ModalFrame title="Standalone ModalFrame" onClose={() => console.log('close')}>
  <Typography>
    ModalFrame used without Modal. The parent container must provide explicit width and height.
  </Typography>
</ModalFrame>
</Box>
```

## When to Use

### ✅ Good Use Cases

- **Destructive actions**: Confirming deletion, discarding changes, or other irreversible operations
- **Critical decisions**: Actions that have significant consequences requiring explicit consent
- **Focused input**: Short forms where distraction-free input is beneficial (login, quick edit)
- **Blocking notifications**: System errors or warnings that require acknowledgment
- **Media preview**: Viewing images, videos, or documents in a focused overlay

### ❌ When Not to Use

- **Long forms**: Multi-step wizards or complex forms belong on dedicated pages
- **Reference content**: Information users need while working on the page
- **Frequent interactions**: Actions performed repeatedly shouldn't require modal confirmation
- **Non-critical information**: Success messages or tips should use Toast or inline feedback
- **Mobile navigation**: Consider using full-page transitions instead on mobile devices

## Common Use Cases

### Confirmation Dialog

Confirm destructive or significant actions before executing them.

```tsx
function DeleteConfirmation({ item, onDelete, onCancel }) {
  return (
    <Modal open onClose={onCancel}>
      <ModalDialog variant="outlined" role="alertdialog">
        <DialogTitle>
          <WarningRoundedIcon />
          Delete {item.name}?
        </DialogTitle>
        <Divider />
        <DialogContent>
          This action cannot be undone. All data associated with this item will be permanently removed.
        </DialogContent>
        <DialogActions>
          <Button variant="solid" color="danger" onClick={onDelete}>
            Delete
          </Button>
          <Button variant="plain" color="neutral" onClick={onCancel}>
            Cancel
          </Button>
        </DialogActions>
      </ModalDialog>
    </Modal>
  );
}
```

### Form Modal

Capture user input in a focused dialog.

```tsx
function CreateProjectModal({ open, onClose, onCreate }) {
  const handleSubmit = (event) => {
    event.preventDefault();
    const formData = new FormData(event.target);
    onCreate({
      name: formData.get('name'),
      description: formData.get('description'),
    });
  };

  return (
    <Modal open={open} onClose={onClose}>
      <ModalDialog>
        <ModalClose />
        <DialogTitle>Create New Project</DialogTitle>
        <form onSubmit={handleSubmit}>
          <DialogContent>
            <Stack spacing={2}>
              <FormControl required>
                <FormLabel>Project Name</FormLabel>
                <Input name="name" placeholder="Enter project name" />
              </FormControl>
              <FormControl>
                <FormLabel>Description</FormLabel>
                <Textarea name="description" minRows={3} placeholder="Enter description" />
              </FormControl>
            </Stack>
          </DialogContent>
          <DialogActions>
            <Button type="submit" variant="solid">
              Create
            </Button>
            <Button variant="plain" color="neutral" onClick={onClose}>
              Cancel
            </Button>
          </DialogActions>
        </form>
      </ModalDialog>
    </Modal>
  );
}
```

### Information Modal

Display detailed information that requires user acknowledgment.

```tsx
function TermsModal({ open, onAccept, onDecline }) {
  return (
    <Modal open={open}>
      <ModalDialog sx={{ maxWidth: 600, maxHeight: '80vh', overflow: 'auto' }}>
        <DialogTitle>Terms of Service</DialogTitle>
        <DialogContent>
          <Typography level="body-sm">
            Please read and accept the following terms and conditions before proceeding...
          </Typography>
          {/* Terms content */}
        </DialogContent>
        <DialogActions>
          <Button variant="solid" onClick={onAccept}>
            Accept
          </Button>
          <Button variant="plain" color="neutral" onClick={onDecline}>
            Decline
          </Button>
        </DialogActions>
      </ModalDialog>
    </Modal>
  );
}
```

### Image Preview Modal

Display images or media in a focused overlay.

```tsx
function ImagePreviewModal({ image, open, onClose }) {
  return (
    <Modal open={open} onClose={onClose}>
      <ModalDialog layout="center" sx={{ p: 0, overflow: 'hidden' }}>
        <ModalClose sx={{ top: 8, right: 8, zIndex: 1 }} />
        <img src={image.src} alt={image.alt} style={{ maxWidth: '90vw', maxHeight: '90vh', objectFit: 'contain' }} />
      </ModalDialog>
    </Modal>
  );
}
```

### Loading Modal

Block user interaction during async operations.

```tsx
function LoadingModal({ open, message }) {
  return (
    <Modal open={open}>
      <ModalDialog>
        <Stack spacing={2} alignItems="center" sx={{ py: 2 }}>
          <CircularProgress />
          <Typography>{message || 'Processing...'}</Typography>
        </Stack>
      </ModalDialog>
    </Modal>
  );
}
```

## Component Structure

Modal uses a composition pattern with multiple sub-components:

```tsx
<Modal>
  {/* Overlay and backdrop */}
  <ModalDialog>
    {/* Dialog container */}
    <ModalClose /> {/* Close button (optional) */}
    <DialogTitle>
      {/* Header */}
      Title
    </DialogTitle>
    <DialogContent>
      {/* Body */}
      Content goes here
    </DialogContent>
    <DialogActions>
      {/* Footer */}
      <Button>Action</Button>
    </DialogActions>
  </ModalDialog>
</Modal>
```

## Component Roles

| Component         | Role                                                            | When to Use                                                      |
| ----------------- | --------------------------------------------------------------- | ---------------------------------------------------------------- |
| **Modal**         | Overlay backdrop, open/close state management                   | Always required as the outermost wrapper                         |
| **ModalDialog**   | Dialog container (variant/size/layout)                          | When you need direct control over layout                         |
| **ModalClose**    | Close (X) button in the top-right corner                        | When users should be able to close via a button                  |
| **ModalOverflow** | Scrollable area                                                 | When content exceeds the viewport                                |
| **ModalFrame**    | Combines ModalDialog + ModalClose + DialogTitle + DialogContent | When you only need a title + close + content (no action buttons) |
| **DialogTitle**   | Header area (styled padding)                                    | When composing manually                                          |
| **DialogContent** | Body area (styled padding)                                      | When composing manually                                          |
| **DialogActions** | Footer action button area                                       | When confirm/cancel buttons are needed                           |

## Choosing the Right Component

### ModalFrame vs DialogFrame

|                    | ModalFrame                                      | DialogFrame                             |
| ------------------ | ----------------------------------------------- | --------------------------------------- |
| Close (X) button   | Built-in                                        | None                                    |
| Title decorator    | `titleStartDecorator`                           | None                                    |
| Action button area | None                                            | `actions` prop (required)               |
| Fullscreen         | `layout="fullscreen"`                           | `fullscreen` prop                       |
| Best for           | Information display, detail views, inline forms | Confirm/cancel dialogs, decision-making |

### Use ModalFrame when

- You need an informational modal with a close button (detail views, previews)
- The form's submit button lives inside the content area
- You need an icon next to the title

### Use DialogFrame when

- Explicit action buttons (confirm/cancel) must be pinned to the bottom
- User decisions are required (delete confirmation, save confirmation)
- Only explicit choices should be allowed without a close (X) button

### Use manual composition when

- You need a custom layout that doesn't fit the ModalFrame/DialogFrame pattern
- You want to use both ModalClose and DialogActions together

## Props and Customization

### Modal Props

| Prop                   | Type          | Default | Description                      |
| ---------------------- | ------------- | ------- | -------------------------------- |
| `open`                 | `boolean`     | `false` | Controls modal visibility        |
| `onClose`              | `function`    | -       | Callback when modal should close |
| `disableEscapeKeyDown` | `boolean`     | `false` | Disable closing on Escape key    |
| `keepMounted`          | `boolean`     | `false` | Keep modal in DOM when closed    |
| `container`            | `HTMLElement` | -       | Portal container element         |

### ModalDialog Props

| Prop      | Type                                                           | Default      | Description  |
| --------- | -------------------------------------------------------------- | ------------ | ------------ |
| `variant` | `'plain' \| 'outlined' \| 'soft' \| 'solid'`                   | `'outlined'` | Visual style |
| `color`   | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'neutral'`  | Color scheme |
| `size`    | `'sm' \| 'md' \| 'lg'`                                         | `'md'`       | Dialog size  |
| `layout`  | `'center' \| 'fullscreen'`                                     | `'center'`   | Layout mode  |

### ModalFrame Props

| Prop                  | Type         | Default | Description                                |
| --------------------- | ------------ | ------- | ------------------------------------------ |
| `title`               | `ReactNode`  | -       | Title displayed in the header              |
| `children`            | `ReactNode`  | -       | Body content                               |
| `titleStartDecorator` | `ReactNode`  | -       | Icon or element displayed before the title |
| `onClose`             | `() => void` | -       | Callback when the close button is clicked  |

ModalFrame accepts all ModalDialog props (`variant`, `color`, `size`, `layout`, `sx`, etc.).

### Custom Styling

```tsx
<Modal
  open={open}
  onClose={onClose}
  sx={{
    // Customize backdrop
    '& .MuiModal-backdrop': {
      backdropFilter: 'blur(4px)',
    },
  }}
>
  <ModalDialog
    sx={{
      minWidth: 400,
      maxWidth: 600,
      borderRadius: 'xl',
      boxShadow: 'xl',
    }}
  >
    {/* Content */}
  </ModalDialog>
</Modal>
```

## Accessibility

Modal components include comprehensive accessibility features:

### ARIA Attributes

- `role="dialog"` is automatically applied to ModalDialog
- Use `role="alertdialog"` for confirmation dialogs requiring user response
- `aria-labelledby` connects to DialogTitle
- `aria-describedby` connects to DialogContent

```tsx
<Modal open={open} onClose={onClose} aria-labelledby="modal-title" aria-describedby="modal-description">
  <ModalDialog>
    <DialogTitle id="modal-title">Accessible Title</DialogTitle>
    <DialogContent id="modal-description">This content is read by screen readers.</DialogContent>
  </ModalDialog>
</Modal>
```

### Keyboard Navigation

- **Escape**: Closes the modal (unless `disableEscapeKeyDown` is true)
- **Tab**: Cycles through focusable elements within the modal
- **Focus trapping**: Focus is automatically trapped within the modal

### Screen Reader Support

- Modal announces its presence when opened
- ModalClose should include `aria-label` for screen readers

```tsx
<ModalClose aria-label="Close dialog" />
```

## Best Practices

### ✅ Do

1. **Provide clear actions**: Always include explicit action buttons for user decisions

```tsx
// ✅ Good: Clear action buttons
<DialogActions>
  <Button variant="solid" color="danger">
    Delete
  </Button>
  <Button variant="plain">Cancel</Button>
</DialogActions>
```

2. **Use appropriate variants**: Match the visual style to the action severity

```tsx
// ✅ Good: Danger color for destructive actions
<ModalDialog color="danger" variant="outlined">
```

3. **Keep content focused**: Modals should contain only essential information

4. **Handle close events**: Always provide multiple ways to close (X button, backdrop click, Escape key)

### ❌ Don't

1. **Don't nest complex navigation**: Avoid wizards or multi-step flows in modals

```tsx
// ❌ Bad: Complex multi-step wizard in modal
<ModalDialog>
  <Stepper activeStep={step}>
    <Step>Step 1</Step>
    <Step>Step 2</Step>
    <Step>Step 3</Step>
  </Stepper>
</ModalDialog>
```

2. **Don't overuse modals**: Frequent interruptions frustrate users

3. **Don't hide important errors in modals**: Use inline validation for form errors

4. **Don't make modals too large**: If content requires scrolling extensively, use a dedicated page

## Performance Considerations

### Lazy Loading

For modals with heavy content, consider lazy loading:

```tsx
const HeavyContent = lazy(() => import('./HeavyContent'));

function OptimizedModal({ open, onClose }) {
  return (
    <Modal open={open} onClose={onClose}>
      <ModalDialog>
        <Suspense fallback={<CircularProgress />}>
          <HeavyContent />
        </Suspense>
      </ModalDialog>
    </Modal>
  );
}
```

### Keep Mounted

Use `keepMounted` only when the modal needs to preserve state between openings:

```tsx
// Only use when necessary
<Modal keepMounted open={open} onClose={onClose}>
  {/* Content that needs to maintain state */}
</Modal>
```

### Avoid Unnecessary Re-renders

Memoize modal content when it depends on complex data:

```tsx
const modalContent = useMemo(() => <ComplexContent data={data} />, [data]);

<Modal open={open} onClose={onClose}>
  <ModalDialog>{modalContent}</ModalDialog>
</Modal>;
```

Modal is a powerful component for focused user interactions. Use it thoughtfully to maintain a smooth user experience while capturing important decisions and inputs.
