feat(v2): audio history player is keyboard-inaccessible despite declaring role="slider"

Open
#184 0 comments 0 reactions 0 assignees View on GitHub

@RahulHarihar is already working on this.

Since Sep 23, 2026.

  • #185 by @RahulHarihar — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
25/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Stale
Tech stack
react, typescript

Research direction

Start in desktop/src/components/AudioPlayer.tsx, at the div with role="slider" that handles the waveform seek click, and check the disabled={!peaks} guard on the Play button. Keyboard support needs focus, the arrow/Home/End/Space keys, and aria-valuetext. A linked pull request (#185) is already open, so check it before starting. Done means Tab reaches the seeker after audio loads and the keys seek as the issue lists.

Written by the indexing model from the issue text.

Description

bug
What happened?

The waveform seeker in the audio history player (desktop/src/components/AudioPlayer.tsx) declares role="slider" with the correct ARIA attributes (aria-valuemin, aria-valuemax, aria-valuenow), but the element has no tabIndex and no onKeyDown handler:

<div
  role="slider"
  aria-label="Playback position"
  aria-valuemin={0}
  aria-valuemax={Math.round(duration)}
  aria-valuenow={Math.round(time)}
  onClick={...}
  className="flex h-10 flex-1 items-center gap-[2px]"
>
  • No tabIndex: The seeker is unreachable via Tab navigation.
  • No onKeyDown: Arrow keys, Space, Home, and End do nothing even if the element is focused.
  • No aria-valuetext: Screen readers announce a raw integer (e.g. "32") instead of a human-readable position (e.g. "0:32 of 1:45").
  • The Play/Pause button is correctly reachable by keyboard, so a keyboard-only user can start playback but cannot seek at all.

Expected Behaviour
Per the W3C ARIA slider keyboard contract:

Key Action
← Seek back 5 seconds
→ Seek forward 5 seconds
Home Jump to start
End Jump to end of clip
Space / Enter Toggle play/pause

The seeker should also be reachable via Tab once audio has loaded, and show a focus ring consistent with other interactive elements in the app.

Proposed Solution

  1. Add tabIndex={0} (guarded: only after audio loads, i.e. when peaks is set, matching the existing disabled={!peaks} guard on the Play button).
  2. Add an onKeyDown handler implementing the ARIA slider keyboard pattern above.
  3. Add aria-valuetext to expose "0:32 of 1:45" to screen readers.
  4. Add focus-visible:ring-2 focus-visible:ring-accent/50 for the keyboard focus ring, consistent with the accent colour already used for the filled portion of the waveform.

All changes are confined to AudioPlayer.tsx. No new dependencies. No existing mouse/click behaviour changes.

I would be happy to submit a pull request for this.

Steps to reproduce
1. Open SpeakType and go to the History screen.
2. Select any transcription with recorded audio.
3. Try navigating to the waveform progress slider using the Tab key.
4. Notice that focus skips the waveform entirely, and arrow keys cannot seek playback.

### Which system?

Windows

### System version

Windows 11

### SpeakType version

2.0.0

### Which model were you using?

_No response_

### Anything else?

### Proposed Solution

1. Add `tabIndex={0}` guarded by `peaks` (matching the existing `disabled={!peaks}` guard on the Play button).
2. Add an `onKeyDown` handler implementing the ARIA slider keyboard pattern (`ArrowLeft`/`ArrowRight` ±5s, `Home`/`End`, `Space`/`Enter`).
3. Add `aria-valuetext` to expose `"0:32 of 1:45"` to screen readers via `formatClock`.
4. Add `focus-visible:ring-2 focus-visible:ring-accent/50` for the focus ring.

All changes are confined to [`AudioPlayer.tsx`](file:/speaktype/desktop/src/components/AudioPlayer.tsx). No new dependencies. Existing mouse click seeking is untouched.

I already have this tested and working on submitting it in a PR.
Dominant language
Swift
Stars
540
Forks
74
PR merge metrics
No merged PRs in 30d

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from karansinghgit/speaktype

All issues in karansinghgit/speaktype

Similar issues

More Swift issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.