@magic-spells/dialog-panel
Version:
A lightweight, customizable Dialog Panel web component for creating accessible and responsive modal dialogs.
193 lines (145 loc) • 4.95 kB
Markdown
A lightweight, customizable Web Component for creating accessible modal dialogs. Ideal for dialogs, alerts, cart panels, or content panels with smooth animations and accessibility features.
[**Live Demo**](https://magic-spells.github.io/dialog-panel/demo/)
- No dependencies
- Lightweight
- Follows accessibility best practices with proper ARIA attributes
- Smooth animations
- Focus management and keyboard navigation
- WAI-ARIA compliant modal dialog behavior
```bash
npm install @magic-spells/dialog-panel
```
```javascript
// Add to your JavaScript file
import '@magic-spells/dialog-panel';
```
Or include directly in your HTML:
```html
<script src="https://unpkg.com/@magic-spells/dialog-panel"></script>
```
```html
<button
id="show-dialog-button"
aria-haspopup="dialog"
aria-controls="demo-dialog"
aria-expanded="false">
Open Dialog
</button>
<dialog-panel
id="demo-dialog"
role="dialog"
aria-modal="true"
aria-labelledby="dialog-title"
aria-describedby="dialog-description"
aria-hidden="true">
<dialog-overlay></dialog-overlay>
<dialog-content>
<button aria-label="Close dialog" data-action="hide-dialog">
×
</button>
<div>
<h2 id="dialog-title">Dialog Title</h2>
<p id="dialog-description">
This is a demonstration of the dialog panel component. Add
your content here.
</p>
</div>
</dialog-content>
</dialog-panel>
<script>
const button = document.getElementById('show-dialog-button');
const dialog = document.getElementById('demo-dialog');
button.addEventListener('click', () => dialog.show());
</script>
```
- The dialog is initially hidden (`aria-hidden="true"`)
- Clicking the button triggers the `show()` method, making the dialog visible
- When opened, sets `aria-modal="true"` to indicate modal behavior
- Clicking the overlay or a close button (`data-action="hide-dialog"`) triggers the `hide()` method
- Keyboard focus is automatically trapped within the dialog when open
- Pressing ESC closes the dialog
- Focus returns to the trigger button when closed
## Customization
### Styling
#### Using CSS Custom Properties
You can style the Dialog Panel by overriding the CSS custom properties:
```css
:root {
/* Layout */
--dp-panel-z-index: 100;
/* Overlay */
--dp-overlay-background: rgba(0, 0, 0, 0.7);
--dp-overlay-backdrop-filter: blur(5px) saturate(120%);
/* Content */
--dp-content-background:
/* Animation */
--dp-transition-duration: 400ms;
--dp-transition-timing: cubic-bezier(0.4, 0, 0.2, 1);
}
```
For more advanced customization, you can import the SCSS directly:
```scss
// Option 1: Import the compiled CSS
@import '@magic-spells/dialog-panel/css';
// Option 2: Import the SCSS and override variables
@use '@magic-spells/dialog-panel/scss' with (
$overlay-background: rgba(0, 0, 0, 0.7),
$overlay-backdrop-filter: blur(5px) saturate(120%),
$content-background:
$transition-duration: 400ms,
$transition-timing: cubic-bezier(0.4, 0, 0.2, 1)
);
// Option 3: Import specific parts
@use '@magic-spells/dialog-panel/scss/variables' with (
$panel-z-index: 100
);
@use '@magic-spells/dialog-panel/scss/dialog-panel';
```
You can also style the elements directly:
```css
dialog-panel {
/* Customize your dialog panel */
}
dialog-overlay {
background-color: rgba(0, 0, 0, 0.5);
}
```
- `show(triggerEl)`: Opens the dialog panel. Returns false if the action was prevented.
- `hide()`: Closes the dialog panel. Returns false if the action was prevented.
The dialog panel emits the following events that you can listen for:
- `beforeShow`: Fired before the dialog starts to show. Cancelable - you can call `preventDefault()` to prevent the dialog from opening.
- `show`: Fired when the dialog has been shown (after transitions).
- `beforeHide`: Fired before the dialog starts to hide. Cancelable - you can call `preventDefault()` to prevent the dialog from closing.
- `hide`: Fired when the dialog has started hiding (transition begins).
- `afterHide`: Fired when the dialog has completed its hide transition.
Each event provides a `detail` object with the `triggerElement` that initiated the action (if any).
Example usage:
```javascript
const dialog = document.getElementById('my-dialog');
// Prevent dialog from closing based on some condition
dialog.addEventListener('beforeHide', (e) => {
if (someFormIsUnsaved) {
e.preventDefault(); // Prevents the dialog from closing
// Show a confirmation message instead
}
});
// Do something after the dialog is fully hidden
dialog.addEventListener('afterHide', () => {
console.log('Dialog is now fully hidden');
// Clean up or reset form fields, etc.
});
```
This component works in all modern browsers that support Web Components.
MIT