a11y: aria-label on the 3 icon-only buttons in the main shell
Three icon-only buttons in the always-visible UI had no programmatic accessible name:
- the "+" add-streamer button (no id, no title, no aria-label — entire button was unnamed)
- the bulk-remove X button next to the Streamer section title (had a localized title, but title is not a reliable accessible-name source — many screen readers don't expose it)
- the VOD-filter clear X button above the VOD grid (same — title-only)
For all three the visible text is just a glyph ("+", "x"), so the accessible name has to come from somewhere else. Added:
- new locale key static.streamerAddAriaLabel ("Streamer hinzufuegen" / "Add streamer") and an id on the "+" button so renderer-texts can localize it
- new setAriaLabel(id, value) helper in renderer-texts mirroring the existing setTitle/setPlaceholder pattern
- aria-label calls for all three buttons, in addition to the existing title (so the tooltip stays for sighted users)
The two existing X buttons reuse their existing title strings as aria-label — no new translation work, just exposing the already-present text via the right ARIA attribute.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2df8d72a61
commit
3ec88a7800
@ -248,7 +248,7 @@
|
||||
<div class="header-actions">
|
||||
<div class="header-search">
|
||||
<input type="text" id="newStreamer" placeholder="Streamer hinzufugen..." onkeypress="if(event.key==='Enter')addStreamer()">
|
||||
<button onclick="addStreamer()">+</button>
|
||||
<button id="btnAddStreamer" type="button" onclick="addStreamer()" aria-label="Add streamer" title="Add streamer">+</button>
|
||||
</div>
|
||||
<button class="btn-icon" onclick="refreshVODs()">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg>
|
||||
|
||||
@ -177,6 +177,7 @@ const UI_TEXT_DE = {
|
||||
downloadPathNotWritable: 'Download-Ordner ist nicht beschreibbar. Waehle einen anderen Ordner oder pruefe die Schreibrechte.',
|
||||
streamerSectionTitle: 'Streamer',
|
||||
streamerListFilterPlaceholder: 'Filtern...',
|
||||
streamerAddAriaLabel: 'Streamer hinzufuegen',
|
||||
streamerBulkRemoveTitle: 'Alle entfernen (oder gefilterte)',
|
||||
streamerBulkRemoveAll: 'Alle {count} Streamer aus der Liste entfernen?',
|
||||
streamerBulkRemoveFiltered: 'Die {count} passenden Streamer aus der Liste entfernen?',
|
||||
|
||||
@ -177,6 +177,7 @@ const UI_TEXT_EN = {
|
||||
downloadPathNotWritable: 'Download folder is not writable. Pick another folder or grant write permission.',
|
||||
streamerSectionTitle: 'Streamer',
|
||||
streamerListFilterPlaceholder: 'Filter...',
|
||||
streamerAddAriaLabel: 'Add streamer',
|
||||
streamerBulkRemoveTitle: 'Remove all (or filtered)',
|
||||
streamerBulkRemoveAll: 'Remove all {count} streamers from the list?',
|
||||
streamerBulkRemoveFiltered: 'Remove the {count} matching streamer(s) from the list?',
|
||||
|
||||
@ -42,6 +42,11 @@ function setTitle(id: string, value: string): void {
|
||||
if (node) node.setAttribute('title', value);
|
||||
}
|
||||
|
||||
function setAriaLabel(id: string, value: string): void {
|
||||
const node = document.getElementById(id);
|
||||
if (node) node.setAttribute('aria-label', value);
|
||||
}
|
||||
|
||||
function setLanguage(lang: string): LanguageCode {
|
||||
currentLanguage = lang === 'en' ? 'en' : 'de';
|
||||
UI_TEXT = UI_TEXTS[currentLanguage];
|
||||
@ -176,6 +181,9 @@ function applyLanguageToStaticUI(): void {
|
||||
setText('streamerSectionTitleText', UI_TEXT.static.streamerSectionTitle);
|
||||
setPlaceholder('streamerListFilter', UI_TEXT.static.streamerListFilterPlaceholder);
|
||||
setTitle('btnStreamerBulkRemove', UI_TEXT.static.streamerBulkRemoveTitle);
|
||||
setAriaLabel('btnStreamerBulkRemove', UI_TEXT.static.streamerBulkRemoveTitle);
|
||||
setAriaLabel('btnAddStreamer', UI_TEXT.static.streamerAddAriaLabel);
|
||||
setTitle('btnAddStreamer', UI_TEXT.static.streamerAddAriaLabel);
|
||||
setText('metadataCacheMinutesLabel', UI_TEXT.static.metadataCacheMinutesLabel);
|
||||
setText('filenameTemplatesTitle', UI_TEXT.static.filenameTemplatesTitle);
|
||||
setText('vodTemplateLabel', UI_TEXT.static.vodTemplateLabel);
|
||||
@ -282,6 +290,7 @@ function applyLanguageToStaticUI(): void {
|
||||
setPlaceholder('newStreamer', UI_TEXT.static.streamerPlaceholder);
|
||||
setPlaceholder('vodFilterInput', UI_TEXT.vods.filterPlaceholder);
|
||||
setTitle('vodFilterClearBtn', UI_TEXT.vods.filterClearTitle);
|
||||
setAriaLabel('vodFilterClearBtn', UI_TEXT.vods.filterClearTitle);
|
||||
setText('vodSortLabel', UI_TEXT.vods.sortLabel);
|
||||
if (typeof refreshVodSortSelectLabels === 'function') {
|
||||
refreshVodSortSelectLabels();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user