Add dialog accessibility semantics

Screen readers got no signal that a dialog opened — not one modal carried
role="dialog" — and several close buttons had no accessible name.

- The 6 static tool windows (Brain, Theme, Prompt, Rename session, Cookbook,
  Settings) now carry role="dialog" + an accessible name. They are dockable,
  tiling windows, so they are non-modal dialogs (intentionally no aria-modal).
- The four unlabelled close buttons (theme, prompt, cookbook, settings) get an
  aria-label so they no longer read as just "heavy multiplication x".
- styledConfirm / styledPrompt ARE blocking modals: they get role="dialog" +
  aria-modal="true" + aria-labelledby/aria-describedby, and now manage focus —
  restore focus to the triggering element on close and trap Tab within the
  dialog (they already moved focus in on open).

tests/test_dialog_aria.py pins the roles, labels, and focus management.
This commit is contained in:
Collin
2026-06-01 23:41:25 -04:00
committed by GitHub
parent 77611f0491
commit c90a7a19a5
3 changed files with 89 additions and 13 deletions
+10 -10
View File
@@ -242,7 +242,7 @@
</script>
<!-- Memory Management Modal -->
<div id="memory-modal" class="modal hidden">
<div class="modal-content memory-modal-content" style="background:var(--bg)">
<div class="modal-content memory-modal-content" role="dialog" aria-label="Brain" style="background:var(--bg)">
<div class="modal-header">
<h4><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-2px;margin-right:6px"><path d="M12 5a3 3 0 1 0-5.997.125 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588A4 4 0 1 0 12 18Z"/><path d="M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.526 5.77 4 4 0 0 1-.556 6.588A4 4 0 1 1 12 18Z"/><path d="M15 13a4.5 4.5 0 0 1-3-4 4.5 4.5 0 0 1-3 4"/></svg>Brain</h4>
<button class="close-btn" id="close-memory-modal" aria-label="Close memory modal"></button>
@@ -432,14 +432,14 @@
<!-- Theme Popup (floating panel) -->
<div id="theme-modal" class="modal hidden">
<div id="theme-popup" class="modal-content admin-modal-content" style="background:var(--bg)">
<div id="theme-popup" class="modal-content admin-modal-content" role="dialog" aria-label="Theme" style="background:var(--bg)">
<div class="modal-header theme-popup-header" id="theme-popup-header">
<h4><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-2px;margin-right:6px"><circle cx="12" cy="12" r="10"/><path d="M12 2a7 7 0 0 0 0 20 4 4 0 0 1 0-8 4 4 0 0 0 0-8"/><circle cx="8" cy="9" r="1.5" fill="currentColor"/><circle cx="15" cy="14" r="1.5" fill="currentColor"/><circle cx="9" cy="15" r="1.5" fill="currentColor"/></svg>Theme</h4>
<button type="button" class="theme-opacity-wrap theme-opacity-toggle hidden" id="theme-opacity-wrap" title="Fade this window to preview the page behind it" aria-pressed="false">
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
<span class="theme-opacity-label">Peek</span>
</button>
<button class="close-btn" id="close-theme-popup">&#x2716;</button>
<button class="close-btn" id="close-theme-popup" aria-label="Close theme">&#x2716;</button>
</div>
<!-- Theme tabs -->
<div class="admin-tabs" id="theme-tabs">
@@ -1115,10 +1115,10 @@
<!-- Character (custom preset) modal -->
<div id="custom-preset-modal" class="modal hidden">
<div class="modal-content preset-modal-content" style="background:var(--bg)">
<div class="modal-content preset-modal-content" role="dialog" aria-label="Prompt" style="background:var(--bg)">
<div class="modal-header">
<h4><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-2px;margin-right:6px"><path d="m18 2 4 4"/><path d="m17 7 3-3"/><path d="M19 9 8.7 19.3c-1 1-2.5 1-3.4 0l-.6-.6c-1-1-1-2.5 0-3.4L15 5"/><path d="m9 11 4 4"/><path d="m5 19-3 3"/><path d="m14 4 6 6"/></svg>Prompt</h4>
<button class="close-btn" id="close-custom-preset"></button>
<button class="close-btn" id="close-custom-preset" aria-label="Close prompt"></button>
</div>
<div class="modal-body preset-modal-body">
<div id="char-fields-wrap">
@@ -1262,7 +1262,7 @@
<!-- Rename Session Modal -->
<div id="rename-session-modal" class="modal hidden">
<div class="modal-content" style="width: 400px;">
<div class="modal-content" role="dialog" aria-label="Rename session" style="width: 400px;">
<div class="modal-header">
<h4>Rename Session</h4>
<button class="close-btn" id="close-rename-session" aria-label="Close rename session modal"></button>
@@ -1288,10 +1288,10 @@
<!-- Cookbook Modal -->
<div id="cookbook-modal" class="modal hidden">
<div class="modal-content" style="width: min(780px, 92vw); height: 94vh; max-height: 94vh; background: var(--bg);">
<div class="modal-content" role="dialog" aria-label="Cookbook" style="width: min(780px, 92vw); height: 94vh; max-height: 94vh; background: var(--bg);">
<div class="modal-header">
<h4 style="margin:0;margin-right:auto"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-2px;margin-right:6px"><path d="M12 7v14"/><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/></svg>Cookbook</h4>
<button class="close-btn" id="close-cookbook-modal"></button>
<button class="close-btn" id="close-cookbook-modal" aria-label="Close cookbook"></button>
</div>
<div class="modal-body cookbook-body"></div>
</div>
@@ -1299,14 +1299,14 @@
<!-- Settings Modal (all users) -->
<div id="settings-modal" class="modal hidden">
<div class="modal-content settings-modal-content">
<div class="modal-content settings-modal-content" role="dialog" aria-label="Settings">
<div class="modal-header">
<h4><span style="vertical-align:-1px;margin-right:6px;font-size:15px">&#x2699;</span>Settings</h4>
<button type="button" class="theme-opacity-wrap theme-opacity-toggle hidden" id="settings-opacity-wrap" title="Fade this window to preview the page behind it" aria-pressed="false">
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
<span class="theme-opacity-label">Peek</span>
</button>
<button class="close-btn"></button>
<button class="close-btn" aria-label="Close settings"></button>
</div>
<div class="admin-toggle-sub" style="padding:0 12px 8px;opacity:0.6;font-size:11px;">Toggle on/off visibility of tools and modules across the interface.</div>
<div class="settings-layout">