feat: add ARIA labels to icon-only buttons and key inputs for accessibility

Co-authored-by: Horizontal42 <75383519+Horizontal42@users.noreply.github.com>
This commit is contained in:
google-labs-jules[bot] 2026-07-08 09:08:41 +00:00
parent 1b61ec35cc
commit 8e4c084ba0
3 changed files with 17 additions and 11 deletions

3
.jules/palette.md Normal file
View file

@ -0,0 +1,3 @@
## 2024-05-18 - Missing ARIA labels on dynamic icon buttons and inputs
**Learning:** Icon-only buttons (like ☰, +, ⚙) and inputs missing explicit labels (`#doc-title`, `#search-input`) were lacking ARIA labels across the application, significantly hurting screen reader accessibility. This includes dynamically generated elements like document tab pin icons.
**Action:** Always verify that every icon-only interactive element and text input field without an explicit `<label>` has an `aria-label` attribute. Also, remember to dynamically update the `aria-label` when placeholders are dynamically loaded in code like `src/main.ts`.

View file

@ -9,31 +9,31 @@
<div id="app"> <div id="app">
<aside id="sidebar" class="hidden"> <aside id="sidebar" class="hidden">
<div id="doc-list"></div> <div id="doc-list"></div>
<button id="new-doc" title="New document">+</button> <button id="new-doc" title="New document" aria-label="New document">+</button>
</aside> </aside>
<main id="content"> <main id="content">
<div id="titlebar" data-tauri-drag-region> <div id="titlebar" data-tauri-drag-region>
<button id="toggle-sidebar" title="Documents (Ctrl+B)">☰</button> <button id="toggle-sidebar" title="Documents (Ctrl+B)" aria-label="Documents">☰</button>
<input id="doc-title" spellcheck="false" autocomplete="off" /> <input id="doc-title" spellcheck="false" autocomplete="off" aria-label="Document title" />
<span class="spacer" data-tauri-drag-region></span> <span class="spacer" data-tauri-drag-region></span>
<button id="open-search" title="Search all sheets (Ctrl+F)">🔍︎</button> <button id="open-search" title="Search all sheets (Ctrl+F)" aria-label="Search all sheets">🔍︎</button>
<button id="open-settings" title="Settings">⚙</button> <button id="open-settings" title="Settings" aria-label="Settings">⚙</button>
<div id="win-controls"> <div id="win-controls">
<button id="win-min" title="Minimize">─</button> <button id="win-min" title="Minimize" aria-label="Minimize">─</button>
<button id="win-close" title="Hide to tray">✕</button> <button id="win-close" title="Hide to tray" aria-label="Hide to tray">✕</button>
</div> </div>
</div> </div>
<div id="editor-wrap"> <div id="editor-wrap">
<div id="editor"></div> <div id="editor"></div>
<div id="results"></div> <div id="results"></div>
<div id="col-divider" title="Drag to resize"></div> <div id="col-divider" title="Drag to resize" aria-label="Drag to resize results column"></div>
</div> </div>
<div id="statusbar"> <div id="statusbar">
<span id="rates-info" title=""></span> <span id="rates-info" title=""></span>
<span id="market-info" title="" style="display:none"></span> <span id="market-info" title="" style="display:none"></span>
<span class="spacer"></span> <span class="spacer"></span>
<div id="export-wrap"> <div id="export-wrap">
<button id="export-btn" title="Export">⤓</button> <button id="export-btn" title="Export" aria-label="Export">⤓</button>
<div id="export-menu" class="hidden"> <div id="export-menu" class="hidden">
<button data-action="image" data-i18n="exportImage">Copy as image</button> <button data-action="image" data-i18n="exportImage">Copy as image</button>
<button data-action="copy" data-i18n="exportCopy">Copy sheet</button> <button data-action="copy" data-i18n="exportCopy">Copy sheet</button>
@ -151,7 +151,7 @@
</div> </div>
<div id="search-overlay" class="hidden"> <div id="search-overlay" class="hidden">
<div class="search-box"> <div class="search-box">
<input id="search-input" type="text" autocomplete="off" spellcheck="false" /> <input id="search-input" type="text" autocomplete="off" spellcheck="false" aria-label="Search sheets" />
<div id="search-results"></div> <div id="search-results"></div>
</div> </div>
</div> </div>

View file

@ -110,6 +110,7 @@ function renderDocList(): void {
b.className = cls; b.className = cls;
b.textContent = text; b.textContent = text;
b.title = title; b.title = title;
b.setAttribute("aria-label", title);
b.addEventListener("click", (e) => { e.stopPropagation(); cb(); }); b.addEventListener("click", (e) => { e.stopPropagation(); cb(); });
return b; return b;
}; };
@ -241,7 +242,9 @@ function applySettings(): void {
document.documentElement.style.setProperty("--editor-font-size", `${settings.fontSize}px`); document.documentElement.style.setProperty("--editor-font-size", `${settings.fontSize}px`);
$("#editor-wrap").style.setProperty("--results-width", `${settings.resultsWidth}%`); $("#editor-wrap").style.setProperty("--results-width", `${settings.resultsWidth}%`);
setLang(settings.language); setLang(settings.language);
$<HTMLInputElement>("#search-input").placeholder = t("searchPlaceholder"); const searchInput = $<HTMLInputElement>("#search-input");
searchInput.placeholder = t("searchPlaceholder");
searchInput.setAttribute("aria-label", t("searchPlaceholder"));
engine.updateSettings({ engine.updateSettings({
precision: settings.precision, precision: settings.precision,
groupSeparator: settings.groupSeparator, groupSeparator: settings.groupSeparator,