Fix focus trap to only include visible focusable elements

- Add getFocusableElements helper function
- Exclude input[type="hidden"] from selector
- Filter out elements where offsetParent is null (hidden)
- Filter out disabled elements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2025-12-24 10:47:38 -05:00
parent 0421fd9833
commit ce6670e35b

View File

@@ -1157,10 +1157,12 @@
document.getElementById('mainContent').setAttribute('inert', ''); document.getElementById('mainContent').setAttribute('inert', '');
// Focus first focusable element in modal // Focus first focusable element in modal
const focusable = modal.querySelectorAll('button, input, select, textarea, [tabindex]:not([tabindex="-1"])'); setTimeout(() => {
if (focusable.length > 0) { const focusable = getFocusableElements(modal);
setTimeout(() => focusable[0].focus(), 50); if (focusable.length > 0) {
} focusable[0].focus();
}
}, 50);
// Add event listener for Escape key // Add event listener for Escape key
document.addEventListener('keydown', handleModalKeydown); document.addEventListener('keydown', handleModalKeydown);
@@ -1181,6 +1183,13 @@
} }
} }
function getFocusableElements(container) {
const elements = container.querySelectorAll('button, input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])');
return Array.from(elements).filter(el => {
return el.offsetParent !== null && !el.disabled;
});
}
function handleModalKeydown(e) { function handleModalKeydown(e) {
if (!activeModalId) return; if (!activeModalId) return;
const modal = document.getElementById(activeModalId); const modal = document.getElementById(activeModalId);
@@ -1194,7 +1203,7 @@
// Trap focus on Tab // Trap focus on Tab
if (e.key === 'Tab') { if (e.key === 'Tab') {
const focusable = modal.querySelectorAll('button, input, select, textarea, [tabindex]:not([tabindex="-1"])'); const focusable = getFocusableElements(modal);
if (focusable.length === 0) return; if (focusable.length === 0) return;
const first = focusable[0]; const first = focusable[0];