---
type: ai-agent-documentation
version: 2.0
component: Dialog
status: stable
audience: ai-coding-agents-only
human-readable: false
category: overlay
framework-support:
- vanilla: true
- react: true
- vue: true
- angular: true
- svelte: true
---
# Component: Dialog
DEFINITION: The Dialog component provides accessible, modal overlays for user interaction, such as confirmations, forms, or alerts. It traps focus and manages keyboard interactions.
## Installation
```bash
npm install @pm7/core
```
### CSS & JavaScript Import
REQUIRED: Import both the CSS and the main JavaScript file.
```javascript
// ES modules
import '@pm7/core/dist/pm7.css';
import '@pm7/core'; // Imports and initializes all components, including global dialog functions
// HTML
```
## Required Structure
The Dialog component requires a main container with a unique `data-pm7-dialog` ID, and three distinct sections marked by `data-pm7-header`, `data-pm7-body`, and `data-pm7-footer` attributes.
```html
Dialog Title
Dialog content goes here.
```
### Structural Rules
- **ALWAYS**: The main dialog container MUST have a unique `data-pm7-dialog="your-id"` attribute.
- **ALWAYS**: A dialog MUST contain exactly one `div` with `data-pm7-header`, one `div` with `data-pm7-body`, and one `div` with `data-pm7-footer`.
- **ALWAYS**: Use `window.openDialog('your-id')` to open the dialog and `window.closeDialog('your-id')` to close it.
- **NEVER**: Manually apply `display: none` or `display: block` to control dialog visibility.
## JavaScript API
### Initialization
Dialogs are automatically initialized when the `pm7.js` script is loaded and they are present in the DOM. For dynamically added dialogs, `window.PM7.init()` must be called.
### Global Functions
```javascript
// Available globally after pm7.js is loaded
window.openDialog(id: string);
window.closeDialog(id: string);
window.closeAllDialogs();
```
| Function | Parameters | Return Type | Description |
|---|---|---|---|
| `window.openDialog` | `id: string` | `void` | Opens the dialog with the specified `data-pm7-dialog` ID. |
| `window.closeDialog` | `id: string` | `void` | Closes the dialog with the specified `data-pm7-dialog` ID. |
| `window.closeAllDialogs` | `(none)` | `void` | Closes all currently open dialogs. |
### Events
| Event | When | Detail | Bubbles |
|---|---|---|---|---|
| `pm7:dialog:open` | After a dialog opens | `{ dialogId: string }` | YES |
| `pm7:dialog:close` | After a dialog closes | `{ dialogId: string }` | YES |
## Attributes
See /docs/ATTRIBUTES.md for cross-component attribute relationships.
| Attribute | Component(s) | Values | Required | Effect |
|---|---|---|---|---|
| `data-pm7-dialog` | Dialog | unique string ID | YES | Initializes Dialog component; used for `openDialog`/`closeDialog`. |
| `data-pm7-dialog-size` | Dialog | `sm`, `md`, `lg`, `xl`, `full` | NO | Sets the width of the dialog. |
| `data-pm7-show-close` | Dialog | presence | NO | Displays a close (X) button in the dialog header. |
| `data-pm7-no-escape` | Dialog | presence | NO | Prevents closing the dialog with the ESC key. |
| `data-pm7-no-overlay-close` | Dialog | presence | NO | Prevents closing the dialog by clicking the overlay. |
| `data-pm7-header` | Dialog | presence | YES | Marks the header section of a dialog. |
| `data-pm7-body` | Dialog | presence | YES | Marks the body section of a dialog. |
| `data-pm7-footer` | Dialog | presence | YES | Marks the footer section of a dialog. |
| `data-state` | Dialog | `open`, `closed` | AUTO | Managed by JS to reflect component's open/closed state. |
| `aria-modal` | Dialog | `true` | AUTO | Indicates that an element is a modal dialog and disables interaction with other content. |
| `role` | Dialog | `dialog` | AUTO | Defines the purpose or nature of an element. |
## CSS Classes
| Class | Auto-Applied | Purpose |
|---|---|---|
| `.pm7-dialog` | YES | Base styling for the dialog content. |
| `.pm7-dialog-overlay` | YES | Styles the backdrop behind the dialog. |
| `.pm7-dialog-container` | YES | Positions the dialog centrally. |
| `.pm7-dialog-header` | YES | Styles the header section. |
| `.pm7-dialog-body` | YES | Styles the main content area. |
| `.pm7-dialog-footer` | YES | Styles the action button area. |
| `.pm7-dialog-close` | YES | Styles the auto-generated close button (if `data-pm7-show-close` is used). |
## Patterns
### Pattern: Basic Confirmation Dialog
```html
Confirm Deletion
Are you sure you want to delete this item? This action cannot be undone.
```
### Pattern: Dialog with Form Input
```html
Edit Your Profile
```
### Pattern: Alert Dialog (Non-dismissible by ESC/Overlay)
```html
Nesting dialogs breaks focus management, accessibility, and can lead to unexpected visual stacking issues.
// Use separate dialogs and open them sequentially if needed.
// For example, close the first dialog before opening the second.
```
### NEVER: Use duplicate `data-pm7-dialog` IDs
```html
...
...
Dialog functions (`openDialog`, `closeDialog`) rely on unique IDs to target specific dialogs. Duplicates will cause unpredictable behavior.
...
...
```
### NEVER: Conditionally render dialogs without `null` check in frameworks
```jsx
// NEVER (React example)
function MyDialog({ isOpen }) {
// This will cause issues as the dialog element is always in the DOM
return (
...
);
}
// BECAUSE
PM7 Dialogs are designed to be added/removed from the DOM. Simply hiding them with CSS breaks their lifecycle and focus management.
// INSTEAD
function MyDialog({ isOpen }) {
if (!isOpen) return null; // CRITICAL: Render null when not open
return (
...
);
}
```
## React Integration
> **📚 Framework Integration Guide**: For Vue, Angular, and other framework integrations, see the comprehensive [Framework Integration Guide](https://raw.githubusercontent.com/patrickmast/pm7-ui/main/README-Framework-Integration.md)
### ⚠️ CRITICAL: Event Handling in React
PM7-UI dialogs require special handling in React due to event system conflicts:
1. **NEVER use React event handlers (onClick) on PM7 internal elements**
- React's synthetic events conflict with PM7's event handling
- Use `dangerouslySetInnerHTML` with lowercase `onclick` attributes instead
2. **The onclick vs onClick Problem**
- React filters out lowercase HTML attributes like `onclick`
- Only PascalCase attributes like `onClick` are passed through
- Solution: Use `dangerouslySetInnerHTML` for buttons in dialogs
3. **Use Global Functions for Event Handling**
```jsx
// Define global functions in your app initialization
useEffect(() => {
window.handleDialogCancel = () => {
window.closeDialog('my-dialog');
// Update your React state here
};
}, []);
```
### Complete React Example
```jsx
function App() {
const [showDialog, setShowDialog] = useState(false);
const [dialogContent, setDialogContent] = useState('');
// Initialize PM7 and global functions
useEffect(() => {
window.PM7?.initFramework();
// Global functions for dialog buttons
window.handleDialogCancel = () => {
window.closeDialog('my-dialog');
setShowDialog(false);
};
window.handleDialogConfirm = () => {
window.closeDialog('my-dialog');
setShowDialog(false);
// Process the dialog result
};
}, []);
// Manage dialog visibility
useEffect(() => {
if (showDialog) {
window.openDialog('my-dialog');
}
}, [showDialog]);
return (
<>
{/* Dialog must always be rendered, PM7 controls visibility */}
Dialog Title
{dialogContent}
Cancel
`
}}
/>
>
);
}
```
### Key Points for React:
- Always render the dialog in the DOM (PM7 handles visibility)
- Use `dangerouslySetInnerHTML` for footer buttons with `onclick`
- Define global functions for event handling
- Synchronize React state with PM7 dialog state
- See [Framework Integration Guide](../../../../../../README-Framework-Integration.md) for more details
## Rules
### ALWAYS
- **ALWAYS**: Provide a unique `data-pm7-dialog` ID for every dialog.
- **ALWAYS**: Include `data-pm7-header`, `data-pm7-body`, and `data-pm7-footer` sections.
- **ALWAYS**: Use `window.openDialog()` and `window.closeDialog()` to control dialog visibility.
- **ALWAYS**: In frameworks like React/Vue, conditionally render the dialog component (return `null` when not open) to ensure proper DOM management.
### NEVER
- **NEVER**: Nest one dialog inside another.
- **NEVER**: Use duplicate `data-pm7-dialog` IDs.
- **NEVER**: Manually control dialog visibility using CSS `display` properties.
- **NEVER**: Forget to call `window.PM7.init()` if you add dialogs to the DOM dynamically after initial page load.
- **NEVER**: Use React onClick handlers on PM7 dialog buttons (use `dangerouslySetInnerHTML` with `onclick` instead).
## CSS Variables
### Component-Specific Variables
Dialog does not define its own CSS variables. All styling is controlled through global PM7 design tokens.
### Required Global Variables
| Variable | Light Mode | Dark Mode | Usage in Dialog |
|----------|------------|-----------|-----------------|
| `--pm7-background` | `#ffffff` | `#121212` | Dialog content background |
| `--pm7-foreground` | `#000000` | `#e0e0e0` | Dialog title and body text |
| `--pm7-muted` | `#f5f5f5` | `#2d2d2d` | Footer background, close button hover |
| `--pm7-muted-foreground` | `#333333` | `#e6e6e6` | Dialog description text, close button icon |
| `--pm7-border` | `#e0e0e0` | `#444` | Dialog border, footer separator |
| `--pm7-radius-lg` | `0.75rem` | `0.75rem` | Dialog border radius |
| `--pm7-ring` | `#1C86EF` | `#3b9eff` | Focus ring for close button |
| `--pm7-spacing-4` | `1rem` | `1rem` | Close button position, mobile padding |
| `--pm7-spacing-6` | `1.5rem` | `1.5rem` | Header/body padding |
| `--pm7-error` | `#ef4444` | `#ef4444` | Alert dialog header background |
| `--pm7-error-foreground` | `#ffffff` | `#ffffff` | Alert dialog header text |
| `--pm7-success` | `#22c55e` | `#22c55e` | Success dialog header background |
| `--pm7-success-foreground` | `#ffffff` | `#ffffff` | Success dialog header text |
| `--pm7-primary` | `#1C86EF` | `#3b9eff` | Loading spinner color |
### Customization Example
```css
/* Custom branded dialog */
.my-app {
--pm7-background: #f8f9fa;
--pm7-foreground: #212529;
--pm7-muted: #e9ecef;
--pm7-border: #dee2e6;
--pm7-radius-lg: 1rem;
}
/* Dark mode overrides */
.my-app.dark {
--pm7-background: #1a1a1a;
--pm7-foreground: #f8f9fa;
--pm7-muted: #2d2d2d;
--pm7-border: #495057;
}
```
## Cross-Component Dependencies
### Works With
- **Button**: Often used in dialog footers for actions (Save, Cancel, Delete)
- **Menu**: Can trigger dialogs from menu items via `onclick` handlers
- **Toast**: Show toast notifications after dialog actions complete
- **Input**: Form elements frequently used in dialog bodies
### Conflicts With
- **Tooltip**: NEVER use tooltips on dialog triggers or inside dialogs (focus management conflicts)
- **Sidebar**: Both use modal overlays - avoid opening simultaneously
## Accessibility
- **Focus**: Dialogs implement a focus trap, ensuring keyboard focus remains within the open dialog.
- **Keyboard**: `Escape` key closes the dialog (unless `data-pm7-no-escape` is present). `Tab` and `Shift+Tab` navigate within the dialog.
- **ARIA**: Dialogs automatically apply `role="dialog"`, `aria-modal="true"`, and manage `aria-labelledby` and `aria-describedby` if a title/description is present.
- **Screen reader**: Fully accessible to screen readers, announcing the modal nature and content.
## Complete Example: User Profile Management
SCENARIO: A user can view and edit their profile details through a dialog.
```html