summaryrefslogtreecommitdiffstats
path: root/themes/danix-xyz-hacker/assets
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-04-17 09:25:33 +0200
committerDanilo M. <danix@danix.xyz>2026-04-17 09:25:33 +0200
commit7992d01ce2f196031592c50821104bedc9ca75f8 (patch)
tree31e13fd9b2034f4fd664504b71627c9be39e557d /themes/danix-xyz-hacker/assets
parent68c5ddcbe358df8bbbc1a40b9a596c60e19c21d7 (diff)
downloaddanixxyz-7992d01ce2f196031592c50821104bedc9ca75f8.tar.gz
danixxyz-7992d01ce2f196031592c50821104bedc9ca75f8.zip
feat: enhance modal focus trap with JavaScript and ARIA attributes
Implements focus trap function that cycles Tab/Shift+Tab within modal boundaries, adds ARIA attributes (role, aria-modal, aria-labelledby) for accessibility compliance, and integrates focus initialization on modal display. - Focus trap prevents tab escape from modal dialog - ARIA attributes: role=dialog, aria-modal=true, aria-labelledby linking title - Backdrop marked aria-hidden=true to exclude from accessibility tree - Close buttons have aria-label for screen readers - Focus initialization calls createFocusTrap on modal show Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Diffstat (limited to 'themes/danix-xyz-hacker/assets')
-rw-r--r--themes/danix-xyz-hacker/assets/js/form-components.js36
1 files changed, 36 insertions, 0 deletions
diff --git a/themes/danix-xyz-hacker/assets/js/form-components.js b/themes/danix-xyz-hacker/assets/js/form-components.js
index 35a5f27..ffa4260 100644
--- a/themes/danix-xyz-hacker/assets/js/form-components.js
+++ b/themes/danix-xyz-hacker/assets/js/form-components.js
@@ -89,3 +89,39 @@ export function renderToastContainer(Alpine) {
}
};
}
+
+// Focus Trap for Modals - Week 5
+function createFocusTrap(modalElement) {
+ const focusableElements = modalElement.querySelectorAll(
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
+ );
+
+ if (focusableElements.length === 0) return;
+
+ const firstElement = focusableElements[0];
+ const lastElement = focusableElements[focusableElements.length - 1];
+
+ modalElement.addEventListener('keydown', (e) => {
+ if (e.key !== 'Tab') return;
+
+ if (e.shiftKey) {
+ // Shift + Tab
+ if (document.activeElement === firstElement) {
+ e.preventDefault();
+ lastElement.focus();
+ }
+ } else {
+ // Tab
+ if (document.activeElement === lastElement) {
+ e.preventDefault();
+ firstElement.focus();
+ }
+ }
+ });
+
+ // Set initial focus
+ firstElement.focus();
+}
+
+// Export for use in Alpine.js
+window.createFocusTrap = createFocusTrap;