fix(a11y): bump record button to 48x48 and announce Recording stopped to screen readers
Record button bumped from 40x40 to 48x48 (WCAG 2.5.5 AA requires 44x44; 48 chosen as forgivable oversize for the most-touched control). Inner stop-square and record-circle bumped 14x14 to 16x16, Loader2 16 to 18, to keep the visual ratio. Recording-status sr-only live region now announces both transitions: "Recording started" on start and "Recording stopped" on stop, with the stop message clearing after 1200ms so the live region does not hold stale text. Transition tracked via a plain let prevRecording (not $state) since it is bookkeeping and must not retrigger the effect. aria-atomic="true" added so the whole region re-reads on update.
This commit is contained in:
@@ -794,11 +794,27 @@
|
|||||||
);
|
);
|
||||||
|
|
||||||
let transcriptionFailed = $state(false);
|
let transcriptionFailed = $state(false);
|
||||||
|
|
||||||
|
// Screen-reader announcer for recording state transitions.
|
||||||
|
// Announces both start and stop, then clears so the live region does not
|
||||||
|
// hold stale text. prevRecording is a plain let (not $state) because it is
|
||||||
|
// bookkeeping and must not re-trigger the effect.
|
||||||
|
let recordingAnnouncement = $state("");
|
||||||
|
let prevRecording = false;
|
||||||
|
$effect(() => {
|
||||||
|
if (page.recording && !prevRecording) {
|
||||||
|
recordingAnnouncement = "Recording started";
|
||||||
|
} else if (!page.recording && prevRecording) {
|
||||||
|
recordingAnnouncement = "Recording stopped";
|
||||||
|
setTimeout(() => { recordingAnnouncement = ""; }, 1200);
|
||||||
|
}
|
||||||
|
prevRecording = page.recording;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col h-full animate-fade-in">
|
<div class="flex flex-col h-full animate-fade-in">
|
||||||
<div aria-live="assertive" class="sr-only" style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);">
|
<div aria-live="assertive" aria-atomic="true" class="sr-only" style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);">
|
||||||
{#if page.recording}Recording started{/if}
|
{recordingAnnouncement}
|
||||||
</div>
|
</div>
|
||||||
{#if needsDownload}
|
{#if needsDownload}
|
||||||
<ModelDownloader
|
<ModelDownloader
|
||||||
@@ -811,7 +827,7 @@
|
|||||||
<div class="flex items-center gap-3 px-5 h-[56px] border-b border-border-subtle flex-shrink-0">
|
<div class="flex items-center gap-3 px-5 h-[56px] border-b border-border-subtle flex-shrink-0">
|
||||||
<!-- Record button -->
|
<!-- Record button -->
|
||||||
<button
|
<button
|
||||||
class="relative flex items-center justify-center w-[40px] h-[40px] min-w-[40px] flex-shrink-0 rounded-full text-white
|
class="relative flex items-center justify-center w-[48px] h-[48px] min-w-[48px] flex-shrink-0 rounded-full text-white
|
||||||
{page.recording
|
{page.recording
|
||||||
? 'bg-danger animate-pulse-warm'
|
? 'bg-danger animate-pulse-warm'
|
||||||
: modelLoading
|
: modelLoading
|
||||||
@@ -824,11 +840,11 @@
|
|||||||
aria-label={page.recording ? "Stop recording" : "Start recording"}
|
aria-label={page.recording ? "Stop recording" : "Start recording"}
|
||||||
>
|
>
|
||||||
{#if page.recording}
|
{#if page.recording}
|
||||||
<span class="w-[14px] h-[14px] rounded-[3px] bg-white"></span>
|
<span class="w-[16px] h-[16px] rounded-[3px] bg-white"></span>
|
||||||
{:else if modelLoading}
|
{:else if modelLoading}
|
||||||
<Loader2 size={16} class="animate-spin" aria-hidden="true" />
|
<Loader2 size={18} class="animate-spin" aria-hidden="true" />
|
||||||
{:else}
|
{:else}
|
||||||
<span class="w-[14px] h-[14px] rounded-full bg-white/90"></span>
|
<span class="w-[16px] h-[16px] rounded-full bg-white/90"></span>
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
<span class="text-[12px] font-medium flex-shrink-0 {page.recording ? 'text-danger' : 'text-text-secondary'}">
|
<span class="text-[12px] font-medium flex-shrink-0 {page.recording ? 'text-danger' : 'text-text-secondary'}">
|
||||||
|
|||||||
Reference in New Issue
Block a user