fix: resolve all Svelte a11y warnings

- Associate labels with controls in CaptionSettingsPanel (9 warnings)
- Add tabindex and keyboard handlers to dialog overlays (8 warnings)
- Add <track> to video element for caption accessibility
- Add keyboard support to resize handle separator

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-22 13:30:27 -04:00
parent 3eebe01d63
commit 9d1f1cfcf3
7 changed files with 116 additions and 36 deletions

View File

@@ -45,8 +45,9 @@
<div class="scroll-area">
<!-- Font Family -->
<div class="control">
<label>Font</label>
<label for="caption-font">Font</label>
<select
id="caption-font"
value={settings.fontFamily}
onchange={(e) => update({ fontFamily: (e.target as HTMLSelectElement).value })}
>
@@ -61,19 +62,20 @@
<label>
Font Size
<span class="value">{settings.fontSize}px</span>
<input
type="range" min="12" max="36" step="1"
value={settings.fontSize}
oninput={(e) => update({ fontSize: parseInt((e.target as HTMLInputElement).value, 10) })}
/>
</label>
<input
type="range" min="12" max="36" step="1"
value={settings.fontSize}
oninput={(e) => update({ fontSize: parseInt((e.target as HTMLInputElement).value, 10) })}
/>
</div>
<!-- Text Color + Bold -->
<div class="control row">
<label>Text Color</label>
<label for="caption-text-color">Text Color</label>
<div class="row-controls">
<input
id="caption-text-color"
type="color" value={settings.textColor}
oninput={(e) => update({ textColor: (e.target as HTMLInputElement).value })}
/>
@@ -87,10 +89,10 @@
<!-- Dimmed Text Color -->
<div class="control">
<label>Dimmed Text</label>
<label for="caption-dimmed-auto">Dimmed Text</label>
<div class="radio-row">
<label>
<input type="radio" name="dimmed-mode" value="auto"
<input id="caption-dimmed-auto" type="radio" name="dimmed-mode" value="auto"
checked={settings.dimmedColorMode === 'auto'}
onchange={() => update({ dimmedColorMode: 'auto' })} />
Auto
@@ -108,18 +110,19 @@
<label>
Dim Opacity
<span class="value">{Math.round(settings.dimmedOpacity * 100)}%</span>
<input
type="range" min="10" max="90" step="5"
value={Math.round(settings.dimmedOpacity * 100)}
oninput={(e) => update({ dimmedOpacity: parseInt((e.target as HTMLInputElement).value, 10) / 100 })}
/>
</label>
<input
type="range" min="10" max="90" step="5"
value={Math.round(settings.dimmedOpacity * 100)}
oninput={(e) => update({ dimmedOpacity: parseInt((e.target as HTMLInputElement).value, 10) / 100 })}
/>
</div>
{:else}
<div class="control row">
<label>Dimmed Color</label>
<label for="caption-dimmed-color">Dimmed Color</label>
<div class="row-controls">
<input
id="caption-dimmed-color"
type="color" value={settings.dimmedColor}
oninput={(e) => update({ dimmedColor: (e.target as HTMLInputElement).value })}
/>
@@ -165,12 +168,12 @@
<label>
BG Opacity
<span class="value">{Math.round(settings.backgroundOpacity * 100)}%</span>
<input
type="range" min="0" max="100" step="5"
value={Math.round(settings.backgroundOpacity * 100)}
oninput={(e) => update({ backgroundOpacity: parseInt((e.target as HTMLInputElement).value, 10) / 100 })}
/>
</label>
<input
type="range" min="0" max="100" step="5"
value={Math.round(settings.backgroundOpacity * 100)}
oninput={(e) => update({ backgroundOpacity: parseInt((e.target as HTMLInputElement).value, 10) / 100 })}
/>
</div>
{/if}
@@ -195,21 +198,21 @@
<label>
Shadow Depth
<span class="value">{settings.shadowDepth}px</span>
<input
type="range" min="1" max="5" step="1"
value={settings.shadowDepth}
oninput={(e) => update({ shadowDepth: parseInt((e.target as HTMLInputElement).value, 10) })}
/>
</label>
<input
type="range" min="1" max="5" step="1"
value={settings.shadowDepth}
oninput={(e) => update({ shadowDepth: parseInt((e.target as HTMLInputElement).value, 10) })}
/>
</div>
{/if}
<!-- Position -->
<div class="control">
<label>Position</label>
<label for="caption-pos-bottom">Position</label>
<div class="radio-row">
<label>
<input type="radio" name="caption-position" value="bottom"
<input id="caption-pos-bottom" type="radio" name="caption-position" value="bottom"
checked={settings.position === 'bottom'}
onchange={() => update({ position: 'bottom' })} />
Bottom