Skip to content

Commit 52184aa

Browse files
committed
Fix security modal display conflict and add accessibility features
- Remove duplicate display:flex from inline style (conflicted with display:none) - Add ARIA attributes: role=dialog, aria-modal, aria-labelledby - Add id to modal heading for screen reader announcement - Implement Escape key handler to close modal - Add focus trap to cycle Tab/Shift+Tab within modal - Auto-focus Cancel button when modal opens - Return focus to API key input when modal closes - Store handlers on modal element for proper cleanup
1 parent 3024697 commit 52184aa

1 file changed

Lines changed: 47 additions & 4 deletions

File tree

public/index.html

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -799,9 +799,9 @@ <h1>StellarMind</h1>
799799
</div>
800800

801801
<!-- ═══ SECURITY WARNING MODAL ═══ -->
802-
<div id="security-modal" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);z-index:100;display:flex;align-items:center;justify-content:center;">
802+
<div id="security-modal" role="dialog" aria-modal="true" aria-labelledby="security-modal-title" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);z-index:100;align-items:center;justify-content:center;">
803803
<div style="background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:24px;max-width:420px;box-shadow:0 20px 60px rgba(0,0,0,0.5);">
804-
<h3 style="font-size:16px;font-weight:700;margin-bottom:12px;color:var(--red);">🔐 API Key Security Warning</h3>
804+
<h3 id="security-modal-title" style="font-size:16px;font-weight:700;margin-bottom:12px;color:var(--red);">🔐 API Key Security Warning</h3>
805805
<div style="font-size:12px;color:var(--text-secondary);line-height:1.7;margin-bottom:16px;">
806806
<p style="margin-bottom:10px;"><strong>Your API key will be:</strong></p>
807807
<ul style="margin-left:16px;margin-bottom:10px;">
@@ -1315,11 +1315,54 @@ <h3 style="font-size:16px;font-weight:700;margin-bottom:12px;color:var(--red);">
13151315
alert('Please enter a valid Anthropic API key starting with sk-ant-');
13161316
return;
13171317
}
1318-
document.getElementById('security-modal').style.display = 'flex';
1318+
const modal = document.getElementById('security-modal');
1319+
modal.style.display = 'flex';
1320+
1321+
// Escape key handler — stored on modal so closeSecurityModal can remove it
1322+
modal._escHandler = function(e) {
1323+
if (e.key === 'Escape') closeSecurityModal();
1324+
};
1325+
document.addEventListener('keydown', modal._escHandler);
1326+
1327+
// Focus trap: collect focusable elements inside the modal
1328+
modal._trapHandler = function(e) {
1329+
if (e.key !== 'Tab') return;
1330+
const focusable = Array.from(modal.querySelectorAll(
1331+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
1332+
)).filter(el => !el.disabled);
1333+
if (!focusable.length) return;
1334+
const first = focusable[0];
1335+
const last = focusable[focusable.length - 1];
1336+
if (e.shiftKey) {
1337+
if (document.activeElement === first) { e.preventDefault(); last.focus(); }
1338+
} else {
1339+
if (document.activeElement === last) { e.preventDefault(); first.focus(); }
1340+
}
1341+
};
1342+
document.addEventListener('keydown', modal._trapHandler);
1343+
1344+
// Focus the Cancel button (first actionable control)
1345+
const cancelBtn = modal.querySelector('button');
1346+
if (cancelBtn) cancelBtn.focus();
13191347
}
13201348

13211349
function closeSecurityModal() {
1322-
document.getElementById('security-modal').style.display = 'none';
1350+
const modal = document.getElementById('security-modal');
1351+
modal.style.display = 'none';
1352+
1353+
// Remove Escape and focus-trap handlers
1354+
if (modal._escHandler) {
1355+
document.removeEventListener('keydown', modal._escHandler);
1356+
modal._escHandler = null;
1357+
}
1358+
if (modal._trapHandler) {
1359+
document.removeEventListener('keydown', modal._trapHandler);
1360+
modal._trapHandler = null;
1361+
}
1362+
1363+
// Return focus to the API key input
1364+
const input = document.getElementById('api-key-input');
1365+
if (input) input.focus();
13231366
}
13241367

13251368
function confirmApiKeySubmission() {

0 commit comments

Comments
 (0)