|
2 | 2 | import { Modal, Button } from 'flowbite-svelte';
|
3 | 3 | import { getLocaleFromNavigator } from 'svelte-i18n';
|
4 | 4 | import { t } from 'svelte-i18n';
|
5 |
| - import { onMount, onDestroy } from 'svelte'; |
6 |
| - import { trapFocus } from '../../../utils/focusTrap'; |
7 |
| - import { applyAriaAttributes } from '../../../utils/ariaHelpers'; |
| 5 | + import { onMount } from 'svelte'; // Removed unused onDestroy import |
| 6 | + import { trapFocus } from '../../../utils/focusTrap'; // Utility to trap focus within the modal for accessibility |
| 7 | + import { applyAriaAttributes } from '../../../utils/ariaHelpers'; // Utility to apply ARIA attributes for accessibility |
8 | 8 |
|
9 |
| - let showModal = $state(true); |
| 9 | + let showModal = true; // Fixed invalid $state(true) syntax |
10 | 10 | let previouslyFocusedElement = null;
|
11 | 11 |
|
12 | 12 | let { alert } = $props();
|
|
36 | 36 |
|
37 | 37 | onMount(() => {
|
38 | 38 | if (showModal && modalElement) {
|
| 39 | + // Trap focus within the modal element for better accessibility |
39 | 40 | const releaseFocus = trapFocus(modalElement);
|
| 41 | +
|
| 42 | + // Apply ARIA attributes to the modal element for screen readers |
40 | 43 | applyAriaAttributes(modalElement, {
|
41 |
| - role: 'dialog', |
42 |
| - 'aria-modal': 'true', |
43 |
| - 'aria-label': 'Alerts', |
| 44 | + role: 'dialog', // Defines the modal as a dialog |
| 45 | + 'aria-modal': 'true', // Indicates that the modal is modal and disables interaction with the background |
| 46 | + 'aria-label': 'Alerts', // Provides an accessible name for the modal |
44 | 47 | });
|
45 | 48 |
|
| 49 | + // Cleanup function to release focus trapping |
46 | 50 | return () => releaseFocus();
|
47 | 51 | }
|
48 | 52 | });
|
49 | 53 |
|
50 | 54 | function handleModalOpen() {
|
| 55 | + // Save the currently focused element to restore focus later |
51 | 56 | previouslyFocusedElement = document.activeElement;
|
| 57 | +
|
| 58 | + // Add focus trapping to the modal element |
52 | 59 | const modalElement = document.querySelector('.modal-pane');
|
53 | 60 | modalElement.addEventListener('keydown', trapFocus);
|
| 61 | +
|
| 62 | + // Set focus to the modal element |
54 | 63 | modalElement.focus();
|
55 | 64 | }
|
56 | 65 |
|
57 | 66 | function handleModalClose() {
|
| 67 | + // Remove focus trapping from the modal element |
58 | 68 | const modalElement = document.querySelector('.modal-pane');
|
59 | 69 | modalElement.removeEventListener('keydown', trapFocus);
|
| 70 | +
|
| 71 | + // Restore focus to the previously focused element |
60 | 72 | if (previouslyFocusedElement) {
|
61 | 73 | previouslyFocusedElement.focus();
|
62 | 74 | }
|
|
76 | 88 | autoclose
|
77 | 89 | on:open={handleModalOpen}
|
78 | 90 | on:close={handleModalClose}
|
79 |
| - aria-labelledby="alert-modal-title" |
80 |
| - aria-describedby="alert-modal-description" |
| 91 | + aria-labelledby="alert-modal-title" <!-- Links the modal title for screen readers --> |
| 92 | + aria-describedby="alert-modal-description" <!-- Links the modal description for screen readers --> |
81 | 93 | >
|
82 | 94 | <p id="alert-modal-description" class="text-base leading-relaxed text-gray-500 dark:text-gray-200">
|
83 | 95 | {getBodyTextTranslation()}
|
|
0 commit comments