From ce6670e35b2ef02308c1a1d644990e96656a26fb Mon Sep 17 00:00:00 2001 From: Eric Wagoner Date: Wed, 24 Dec 2025 10:47:38 -0500 Subject: [PATCH] Fix focus trap to only include visible focusable elements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- index.html | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 23ada4e..4eb9d48 100644 --- a/index.html +++ b/index.html @@ -1157,10 +1157,12 @@ document.getElementById('mainContent').setAttribute('inert', ''); // Focus first focusable element in modal - const focusable = modal.querySelectorAll('button, input, select, textarea, [tabindex]:not([tabindex="-1"])'); - if (focusable.length > 0) { - setTimeout(() => focusable[0].focus(), 50); - } + setTimeout(() => { + const focusable = getFocusableElements(modal); + if (focusable.length > 0) { + focusable[0].focus(); + } + }, 50); // Add event listener for Escape key 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) { if (!activeModalId) return; const modal = document.getElementById(activeModalId); @@ -1194,7 +1203,7 @@ // Trap focus on 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; const first = focusable[0];