# DialogFrame

## Introduction

DialogFrame is a compound component that provides a structured container for dialog content, including title, body, and action buttons. It's designed to be used within a Modal component to create consistent, accessible dialog interfaces for confirmations, forms, and informational displays. DialogFrame handles the layout and styling of dialog elements while the parent Modal manages the overlay and open/close behavior.

```tsx
<DialogFrame
  title="Dialog Title"
  children="Dialog Content"
  actions={actions}
/>
```

| Field      | Description | Default          |
| ---------- | ----------- | ---------------- |
| title      | —           | "Dialog Title"   |
| children   | —           | "Dialog Content" |
| fullscreen | —           | —                |
| actions    | —           | actions          |

> ⚠️ **Usage Warning** ⚠️
>
> Dialogs interrupt the user's workflow:
>
> - **Confirmations only**: Use dialogs for important decisions that need confirmation
> - **Keep it brief**: Dialog content should be scannable and actionable
> - **Consider alternatives**: Use Toast for feedback, Alert for inline messages
> - **Wrap with Modal**: DialogFrame should be used inside a Modal component for proper behavior

## Usage

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

function ConfirmationDialog({ open, onClose, onConfirm }) {
  return (
    <Modal open={open} onClose={onClose}>
      <DialogFrame
        title="Confirm Action"
        actions={
          <>
            <Button variant="plain" color="neutral" onClick={onClose}>
              Cancel
            </Button>
            <Button onClick={onConfirm}>Confirm</Button>
          </>
        }
      >
        Are you sure you want to proceed with this action?
      </DialogFrame>
    </Modal>
  );
}
```

## Examples

### Playground

Interactive example with title, content, and action buttons.

```tsx
<DialogFrame
  title="Dialog Title"
  children="Dialog Content"
  actions={actions}
/>
```

### Fullscreen

Fullscreen mode for complex content or mobile views.

```tsx
<DialogFrame
  title="Dialog Title"
  children={<Stack>Fullscreen</Stack>}
  actions={actions}
  fullscreen
/>
```

### With Input (KeyDown Handling)

Dialog with form inputs and keyboard event handling.

```tsx
<DialogFrame {...args} title="Dialog Title" actions={<Button variant="plain">Action</Button>}>
Dialog Content
<Input />
</DialogFrame>
```

### Standalone Usage

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

> ⚠️ **Important** ⚠️
>
> When using DialogFrame without Modal, the parent container **must** provide explicit `width` and `height` values.
> DialogFrame 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
}}>
<DialogFrame {...args} title="Standalone Dialog" actions={<>
  <Button variant="plain" color="neutral">
    Cancel
  </Button>
  <Button variant="plain">Confirm</Button>
</>}>
DialogFrame used without Modal. The parent container must provide explicit width and height.
</DialogFrame>
</Box>
```

```tsx
import { DialogFrame, Button, Box } from '@ceed/cds';

// Standalone usage requires explicit container dimensions
function EmbeddedDialog() {
  return (
    <Box sx={{ width: 480, height: 300 }}>
      <DialogFrame
        title="Settings"
        actions={
          <>
            <Button variant="plain" color="neutral">
              Cancel
            </Button>
            <Button>Save</Button>
          </>
        }
      >
        This dialog is embedded directly in the page layout.
      </DialogFrame>
    </Box>
  );
}
```

## When to Use

### ✅ Good Use Cases

- **Confirmations**: Delete, submit, or irreversible action confirmations
- **Simple forms**: Login, quick input, or single-field forms
- **Alerts**: Important information that requires acknowledgment
- **Choices**: Binary or limited-option decisions
- **Terms acceptance**: Legal agreements that need explicit consent

### ❌ When Not to Use

- **Complex forms**: Use a dedicated page for multi-step forms
- **Notifications**: Use Toast for non-blocking feedback
- **Inline messages**: Use Alert for contextual information
- **Frequent interactions**: Don't interrupt common workflows
- **Large content**: Use a page or InsetDrawer for lengthy content

## Common Use Cases

### Delete Confirmation

```tsx
function DeleteConfirmation({ itemName, open, onClose, onDelete }) {
  return (
    <Modal open={open} onClose={onClose}>
      <DialogFrame
        title="Delete Item"
        actions={
          <>
            <Button variant="plain" color="neutral" onClick={onClose}>
              Cancel
            </Button>
            <Button color="danger" onClick={onDelete}>
              Delete
            </Button>
          </>
        }
      >
        <Typography>
          Are you sure you want to delete <strong>{itemName}</strong>?
        </Typography>
        <Typography level="body-sm" color="neutral" sx={{ mt: 1 }}>
          This action cannot be undone.
        </Typography>
      </DialogFrame>
    </Modal>
  );
}
```

### Form Dialog

```tsx
function QuickAddDialog({ open, onClose, onSubmit }) {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');

  const handleSubmit = () => {
    onSubmit({ name, email });
    setName('');
    setEmail('');
    onClose();
  };

  return (
    <Modal open={open} onClose={onClose}>
      <DialogFrame
        title="Add New User"
        actions={
          <>
            <Button variant="plain" color="neutral" onClick={onClose}>
              Cancel
            </Button>
            <Button onClick={handleSubmit} disabled={!name || !email}>
              Add User
            </Button>
          </>
        }
      >
        <Stack gap={2}>
          <FormControl>
            <FormLabel>Name</FormLabel>
            <Input value={name} onChange={(e) => setName(e.target.value)} placeholder="Enter name" autoFocus />
          </FormControl>
          <FormControl>
            <FormLabel>Email</FormLabel>
            <Input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Enter email" />
          </FormControl>
        </Stack>
      </DialogFrame>
    </Modal>
  );
}
```

### Unsaved Changes Warning

```tsx
function UnsavedChangesDialog({ open, onClose, onDiscard, onSave }) {
  return (
    <Modal open={open} onClose={onClose}>
      <DialogFrame
        title="Unsaved Changes"
        actions={
          <>
            <Button variant="plain" color="neutral" onClick={onClose}>
              Cancel
            </Button>
            <Button variant="outlined" color="danger" onClick={onDiscard}>
              Discard
            </Button>
            <Button onClick={onSave}>Save Changes</Button>
          </>
        }
      >
        <Typography>You have unsaved changes. Would you like to save them before leaving?</Typography>
      </DialogFrame>
    </Modal>
  );
}
```

### Information Dialog

```tsx
function InfoDialog({ open, onClose, title, message }) {
  return (
    <Modal open={open} onClose={onClose}>
      <DialogFrame title={title} actions={<Button onClick={onClose}>Got it</Button>}>
        <Typography>{message}</Typography>
      </DialogFrame>
    </Modal>
  );
}
```

### Terms Acceptance

```tsx
function TermsDialog({ open, onClose, onAccept }) {
  const [accepted, setAccepted] = useState(false);

  return (
    <Modal open={open} onClose={onClose}>
      <DialogFrame
        title="Terms and Conditions"
        actions={
          <>
            <Button variant="plain" color="neutral" onClick={onClose}>
              Decline
            </Button>
            <Button onClick={onAccept} disabled={!accepted}>
              Accept
            </Button>
          </>
        }
      >
        <Box sx={{ maxHeight: 300, overflow: 'auto', mb: 2 }}>
          <Typography level="body-sm">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit...
            {/* Terms content */}
          </Typography>
        </Box>
        <Checkbox
          label="I have read and agree to the terms and conditions"
          checked={accepted}
          onChange={(e) => setAccepted(e.target.checked)}
        />
      </DialogFrame>
    </Modal>
  );
}
```

### Loading State Dialog

```tsx
function ProcessingDialog({ open, status, onClose }) {
  const isProcessing = status === 'processing';
  const isSuccess = status === 'success';
  const isError = status === 'error';

  return (
    <Modal open={open} onClose={isProcessing ? undefined : onClose}>
      <DialogFrame
        title={isProcessing ? 'Processing...' : isSuccess ? 'Success!' : 'Error'}
        actions={!isProcessing && <Button onClick={onClose}>{isSuccess ? 'Done' : 'Try Again'}</Button>}
      >
        <Box sx={{ textAlign: 'center', py: 2 }}>
          {isProcessing && <CircularProgress />}
          {isSuccess && <CheckCircleIcon color="success" sx={{ fontSize: 48 }} />}
          {isError && <ErrorIcon color="error" sx={{ fontSize: 48 }} />}
          <Typography sx={{ mt: 2 }}>
            {isProcessing && 'Please wait while we process your request...'}
            {isSuccess && 'Your request has been processed successfully.'}
            {isError && 'Something went wrong. Please try again.'}
          </Typography>
        </Box>
      </DialogFrame>
    </Modal>
  );
}
```

### Selection Dialog

```tsx
function SelectOptionDialog({ open, onClose, options, onSelect }) {
  return (
    <Modal open={open} onClose={onClose}>
      <DialogFrame
        title="Select an Option"
        actions={
          <Button variant="plain" color="neutral" onClick={onClose}>
            Cancel
          </Button>
        }
      >
        <List>
          {options.map((option) => (
            <ListItem key={option.value}>
              <ListItemButton
                onClick={() => {
                  onSelect(option.value);
                  onClose();
                }}
              >
                <ListItemDecorator>{option.icon}</ListItemDecorator>
                <ListItemContent>
                  <Typography level="title-sm">{option.label}</Typography>
                  <Typography level="body-xs">{option.description}</Typography>
                </ListItemContent>
              </ListItemButton>
            </ListItem>
          ))}
        </List>
      </DialogFrame>
    </Modal>
  );
}
```

## Props and Customization

### Key Props

| Prop         | Type                             | Default | Description                            |
| ------------ | -------------------------------- | ------- | -------------------------------------- |
| `title`      | `string`                         | -       | Dialog title displayed in the header   |
| `children`   | `ReactNode`                      | -       | Dialog body content                    |
| `actions`    | `ReactNode`                      | -       | Action buttons displayed in the footer |
| `fullscreen` | `boolean`                        | `false` | Enable fullscreen mode                 |
| `onKeyDown`  | `(event: KeyboardEvent) => void` | -       | Keyboard event handler                 |

### Structure

DialogFrame provides a three-part layout:

```tsx
<DialogFrame
  title="Header"      // Top: Title section
  actions={...}       // Bottom: Action buttons
>
  {/* Middle: Content area */}
</DialogFrame>
```

### With Modal

DialogFrame should be wrapped in Modal for proper behavior:

```tsx
<Modal open={open} onClose={onClose}>
  <DialogFrame title="Title" actions={actions}>
    Content
  </DialogFrame>
</Modal>
```

### Action Button Patterns

```tsx
// Confirmation (Cancel + Confirm)
<DialogFrame
  actions={
    <>
      <Button variant="plain" color="neutral" onClick={onClose}>
        Cancel
      </Button>
      <Button onClick={onConfirm}>Confirm</Button>
    </>
  }
/>

// Destructive action
<DialogFrame
  actions={
    <>
      <Button variant="plain" color="neutral" onClick={onClose}>
        Cancel
      </Button>
      <Button color="danger" onClick={onDelete}>Delete</Button>
    </>
  }
/>

// Single action (acknowledgment)
<DialogFrame
  actions={
    <Button onClick={onClose}>OK</Button>
  }
/>

// Three options
<DialogFrame
  actions={
    <>
      <Button variant="plain" color="neutral" onClick={onCancel}>Cancel</Button>
      <Button variant="outlined" onClick={onSecondary}>Don't Save</Button>
      <Button onClick={onPrimary}>Save</Button>
    </>
  }
/>
```

### Fullscreen Mode

```tsx
// Fullscreen for complex content or mobile
<Modal open={open} onClose={onClose}>
  <DialogFrame fullscreen title="Edit Profile">
    <Box sx={{ p: 2 }}>{/* Large form or content */}</Box>
  </DialogFrame>
</Modal>
```

## Accessibility

DialogFrame inherits accessibility features from Modal:

### ARIA Attributes

- Dialog has `role="dialog"` via Modal
- Title provides `aria-labelledby`
- Focus is trapped within the dialog
- Background is marked as `aria-hidden`

### Keyboard Navigation

- **Escape**: Close the dialog (via Modal)
- **Tab**: Navigate between focusable elements
- **Enter**: Activate focused button

### Focus Management

```tsx
// Auto-focus first input
<DialogFrame title="Add Item">
  <Input autoFocus placeholder="Item name" />
</DialogFrame>

// Focus returns to trigger when closed
<Button onClick={() => setOpen(true)}>Open Dialog</Button>
<Modal open={open} onClose={() => setOpen(false)}>
  <DialogFrame>...</DialogFrame>
</Modal>
```

### Screen Reader Support

```tsx
// Title provides context
<DialogFrame title="Confirm Deletion">{/* Content is read after title */}</DialogFrame>
```

## Best Practices

### ✅ Do

1. **Use clear, action-oriented titles**: Tell users what they're confirming

```tsx
// ✅ Good: Specific title
<DialogFrame title="Delete Account" />
<DialogFrame title="Save Changes" />
```

2. **Provide clear button labels**: Use verbs that describe the action

```tsx
// ✅ Good: Clear action buttons
<Button color="danger">Delete</Button>
<Button>Save Changes</Button>
```

3. **Keep content concise**: Users should quickly understand and decide

```tsx
// ✅ Good: Brief, scannable content
<DialogFrame title="Delete Project">
  <Typography>This will permanently delete the project and all its data.</Typography>
</DialogFrame>
```

4. **Always provide a cancel option**: Let users safely exit

```tsx
// ✅ Good: Cancel button available
<DialogFrame
  actions={
    <>
      <Button variant="plain" color="neutral" onClick={onClose}>
        Cancel
      </Button>
      <Button onClick={onConfirm}>Confirm</Button>
    </>
  }
/>
```

### ❌ Don't

1. **Don't use for notifications**: Use Toast instead

```tsx
// ❌ Bad: Dialog for simple feedback
<DialogFrame title="Success">
  <Typography>Item saved!</Typography>
</DialogFrame>;

// ✅ Good: Use Toast
showToast({ message: 'Item saved!' });
```

2. **Don't include too much content**: Use a page for complex forms

```tsx
// ❌ Bad: Complex form in dialog
<DialogFrame title="Create Account">{/* 20+ form fields */}</DialogFrame>
```

3. **Don't use vague button labels**: Be specific about actions

```tsx
// ❌ Bad: Unclear actions
<Button>OK</Button>
<Button>Cancel</Button>

// ✅ Good: Clear actions
<Button>Delete Account</Button>
<Button variant="plain">Keep Account</Button>
```

4. **Don't block critical workflows**: Important features should be accessible

## Performance Considerations

### Lazy Load Dialog Content

For dialogs with heavy content:

```tsx
function HeavyDialog({ open, onClose }) {
  return (
    <Modal open={open} onClose={onClose}>
      <DialogFrame title="Data Preview">{open && <HeavyDataComponent />}</DialogFrame>
    </Modal>
  );
}
```

### Memoize Handlers

```tsx
const handleConfirm = useCallback(() => {
  performAction();
  onClose();
}, [performAction, onClose]);

const handleCancel = useCallback(() => {
  onClose();
}, [onClose]);
```

### Conditionally Render

Unmount dialog completely when not needed:

```tsx
{
  open && (
    <Modal open={open} onClose={onClose}>
      <DialogFrame>...</DialogFrame>
    </Modal>
  );
}
```

DialogFrame provides a consistent structure for dialog content. Combine it with Modal for proper overlay behavior, keep content concise and actionable, and always provide clear options for users to proceed or cancel.
