Fix focus trapping using inert attribute

- Wrap main content in container with id="mainContent"
- Set inert attribute on background when modal opens
- Remove inert when modal closes
- This properly prevents all keyboard/mouse interaction with background

🤖 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:40:38 -05:00
parent 44d0f7a257
commit c55a8e08c4

View File

@@ -635,6 +635,7 @@
</style>
</head>
<body>
<div id="mainContent">
<a href="#inventoryList" class="visually-hidden" id="skipLink" style="position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden;" onfocus="this.style.cssText='position:fixed;top:10px;left:10px;z-index:9999;background:var(--forest);color:white;padding:10px 20px;border-radius:8px;text-decoration:none;font-weight:500;';" onblur="this.style.cssText='position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden;';">Skip to inventory</a>
<div class="loading-overlay" id="loadingOverlay" role="status" aria-live="polite" aria-label="Loading">
<div class="loading-spinner" aria-hidden="true"></div>
@@ -708,6 +709,7 @@
</button>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
</div><!-- end mainContent -->
<!-- PIN Modal -->
<div class="modal-overlay" id="pinModal" role="dialog" aria-modal="true" aria-labelledby="pinModalTitle">
@@ -1151,13 +1153,16 @@
const modal = document.getElementById(id);
modal.classList.add('active');
// Make background content inert (unfocusable)
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);
}
// Add event listeners for focus trap and Escape
// Add event listener for Escape key
document.addEventListener('keydown', handleModalKeydown);
}
@@ -1166,6 +1171,9 @@
document.removeEventListener('keydown', handleModalKeydown);
activeModalId = null;
// Remove inert from background content
document.getElementById('mainContent').removeAttribute('inert');
// Restore focus to previously focused element
if (previouslyFocusedElement) {
previouslyFocusedElement.focus();