UNPKG

ksk-core

Version:

Core design system components and styles for Kickstart projects

261 lines (192 loc) 7.94 kB
# Dialog Component A fully accessible modal dialog component with advanced animations, focus management, and keyboard navigation. ## Files Structure ``` Dialog/ ├── Dialog.astro # Main component markup and props ├── Dialog.scss # Component styles with animations ├── Dialog.js # JavaScript functionality and accessibility ├── index.js # Export file for clean imports └── README.md # This documentation ``` ## Features ### Accessibility ✨ - **Focus Management**: Automatically focuses first interactive element and traps focus within dialog - **Keyboard Navigation**: ESC to close, Tab to cycle through focusable elements - **Screen Reader Support**: Proper ARIA roles, labels, and live region announcements - **Focus Restoration**: Returns focus to triggering element when closed - **Background Scroll Prevention**: Prevents body scrolling while dialog is open ### Animations 🎨 - **Smooth Transitions**: Backdrop fade with blur effect - **Spring-like Animation**: Dialog scales and slides in with modern easing - **Reduced Motion Support**: Respects user's motion preferences - **Progressive Enhancement**: Graceful fallbacks for older browsers ### Responsive Design 📱 - **Container Queries**: Advanced responsive behavior - **Mobile Optimized**: Fullscreen on small screens when needed - **Dark Mode Support**: Automatic dark theme adaptation - **High Contrast**: Enhanced visibility for accessibility ## Props | Prop | Type | Default | Description | | --------------------- | ------------------------------------------------ | ------------ | ---------------------------------- | | `id` | `string` | **required** | Unique identifier for the dialog | | `title` | `string` | `undefined` | Optional dialog title | | `size` | `'small' \| 'medium' \| 'large' \| 'fullscreen'` | `'medium'` | Dialog size variant | | `variant` | `'default' \| 'alert' \| 'confirmation'` | `'default'` | Visual style variant | | `closeOnOutsideClick` | `boolean` | `true` | Allow closing by clicking backdrop | | `closeOnEscape` | `boolean` | `true` | Allow closing with ESC key | | `showCloseButton` | `boolean` | `true` | Show the X close button | | `class` | `string` | `undefined` | Additional CSS classes | ## Usage ### Basic Usage ```astro --- import Dialog from '../components/Dialog/Dialog.astro'; import Button from '../components/Button.astro'; --- <!-- Trigger Button --> <Button data-dialog-trigger="my-dialog">Open Dialog</Button> <!-- Dialog Component --> <Dialog id="my-dialog" title="My Dialog"> <p>This is the dialog content.</p> <Fragment slot="actions"> <Button data-dialog-close="my-dialog" variant="outline">Cancel</Button> <Button data-dialog-close="my-dialog" variant="primary">Confirm</Button> </Fragment> </Dialog> ``` ### Different Sizes ```astro <!-- Small Dialog --> <Dialog id="small-dialog" title="Small Dialog" size="small"> <p>Small dialog content</p> </Dialog> <!-- Large Dialog --> <Dialog id="large-dialog" title="Large Dialog" size="large"> <p>Large dialog with more space</p> </Dialog> <!-- Fullscreen Dialog --> <Dialog id="fullscreen-dialog" title="Fullscreen" size="fullscreen"> <p>Takes up most of the viewport</p> </Dialog> ``` ### Variants ```astro <!-- Alert Dialog --> <Dialog id="alert-dialog" title="Warning" variant="alert"> <p>This is an important alert message.</p> </Dialog> <!-- Confirmation Dialog --> <Dialog id="confirm-dialog" title="Confirm Delete" variant="confirmation"> <p>Are you sure you want to delete this item?</p> </Dialog> ``` ### Form Dialog ```astro <Dialog id="form-dialog" title="Contact Form" size="medium"> <form id="contact-form"> <FormField label="Name" name="name" required> <input type="text" name="name" autofocus /> </FormField> <FormField label="Email" name="email" required> <input type="email" name="email" /> </FormField> <Textarea label="Message" name="message" required /> </form> <Fragment slot="actions"> <Button data-dialog-close="form-dialog" variant="outline">Cancel</Button> <Button type="submit" variant="primary">Send</Button> </Fragment> </Dialog> ``` ## JavaScript API The dialog component automatically initializes, but you can also control it programmatically: ### Import the Manager ```javascript import { DialogManager } from "../components/Dialog/Dialog.js"; // Or use the global instance const dialogManager = window.DialogManager; ``` ### Methods ```javascript // Open a dialog dialogManager.open("my-dialog"); // Close a dialog dialogManager.close("my-dialog"); // Close all open dialogs dialogManager.closeAll(); // Check if a dialog is open if (dialogManager.isOpen("my-dialog")) { console.log("Dialog is open"); } ``` ### Events Listen for dialog events: ```javascript document.addEventListener("dialog:open", (e) => { console.log("Dialog opened:", e.detail.dialogId); }); document.addEventListener("dialog:close", (e) => { console.log("Dialog closed:", e.detail.dialogId); }); ``` ## Data Attributes ### Triggers - `data-dialog-trigger="dialog-id"` - Opens the specified dialog ### Close Buttons - `data-dialog-close="dialog-id"` - Closes the specified dialog ### Configuration - `data-close-outside="true|false"` - Override closeOnOutsideClick prop - `data-close-escape="true|false"` - Override closeOnEscape prop ## CSS Custom Properties You can customize the dialog appearance using CSS custom properties: ```css :root { /* Colors */ --color-primary: #3b82f6; --color-gray-100: #f3f4f6; --color-gray-200: #e5e7eb; --color-gray-300: #d1d5db; --color-gray-400: #9ca3af; --color-gray-500: #6b7280; --color-gray-700: #374151; --color-gray-800: #1f2937; --color-gray-900: #111827; /* Warning colors */ --color-warning: #f59e0b; --color-warning-light: #fef3c7; --color-warning-dark: #92400e; /* Danger colors */ --color-danger: #ef4444; --color-danger-light: #fee2e2; --color-danger-dark: #991b1b; } ``` ## Browser Support ### Modern Features - **Backdrop Filter**: Blur effect (graceful fallback to solid background) - **Container Queries**: Advanced responsive behavior (fallback to media queries) - **CSS :has()**: Advanced selectors (fallback to JavaScript classes) ### Accessibility Standards - **WCAG 2.1 AA Compliant** - **Keyboard Navigation**: Full keyboard support - **Screen Readers**: Proper ARIA implementation - **High Contrast Mode**: Enhanced visibility - **Reduced Motion**: Respects user preferences ## Performance - **Lazy Loading**: JavaScript only loads when needed - **Event Delegation**: Efficient event handling - **Mutation Observer**: Handles dynamic content - **Memory Management**: Proper cleanup and garbage collection ## Best Practices 1. **Always provide a title** for screen reader users 2. **Use semantic actions** in the actions slot 3. **Include proper form labels** in form dialogs 4. **Test keyboard navigation** thoroughly 5. **Consider mobile experience** for all sizes 6. **Provide clear close options** for users ## Migration from Old Dialog If you're upgrading from the previous dialog implementation: 1. **Update imports**: Change to `import Dialog from '../components/Dialog/Dialog.astro'` 2. **Update main.js**: Import from `../components/Dialog/Dialog.js` 3. **No breaking changes**: All existing props and usage patterns remain the same