fix: keep focus on play button on activation; scope keyboard shortcuts - #10
fix: keep focus on play button on activation; scope keyboard shortcuts#10jeryj wants to merge 1 commit into
Conversation
Activating the play button (Space/Enter/click) no longer moves focus to the player wrapper — the container's click handler only takes focus on non-interactive clicks. The keyboard-shortcut guard now fires when focus is on the play button, the waveform slider, or the container, so Space toggles play from the waveform while other controls (speed button, markers) keep their own keys. The container is no longer promoted into the tab order on click. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Clicking/activating the play button — or any interactive control (slider, link, input) — now keeps focus on that control. The container's click handler only takes focus when the click lands on a non-interactive area, via an `INTERACTIVE_ELEMENTS` closest() guard. The keyboard-shortcut handler is intentionally left untouched: native Space/Enter activation keeps owning the play button, so there's no double-toggle risk. Added a focus-stability regression test. Reported in #10 — took the focus-steal fix directly, left the broader keyboard-shortcut rescoping (unverifiable Space double-fire path). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for this, @jeryj — you flagged a genuine bug: activating the play button (or any interactive control) was stealing keyboard focus onto the wrapping container I've landed that fix directly on I kept it to just the focus-steal guard and left the keyboard-shortcut rescoping out, for two reasons:
Really appreciate the detailed write-up and tests — the focus-stability case mapped straight onto the fix. Closing since the core issue is resolved on |
|
Glad I could help out! Thanks for getting the main bug work merged in so fast. |
|
I tested it out, and there's functionality that got removed. I was intending for Spacebar activation to work to start Playing while focus is on the waveform as well. By removing the Space path work, spacebar does not begin playing the audio while focus is on the waveform. |
…sion 1) The waveform slider swallowed Space (default: return) while the container Space handler only fires when the root is focused — so Space did nothing when the waveform itself had focus. Slider now toggles play on Space. Reported by @jeryj. 2) Media Session metadata was set once at load; iOS ignores metadata set before playback and playbackState was never set — blank lock-screen card. Now re-asserts metadata + sets playbackState + setPositionState on play/pause. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Fixed in |
|
@arraypress Thank you! You're amazing! |
Problem
Activating the play button with Enter (or Space) moved focus to the player's wrapping
<div>instead of leaving it on the button. This is an unexpected focus stealing event which seems unnecessary if we allow the shortcuts to work while the button is focused.Changes
focus()when the click lands on a non-interactive area (button, a[href], input, [role="slider"]→INTERACTIVE_ELEMENTS). Clicking/activating the play button or slider leaves focus on that control.shortcutEnabledElements), instead of only when the bare container is focused. So Space toggles play from the waveform, while other controls (speed button, markers) keep their own keys — no Space-hijacking.tabindex="0"promotion (it staystabindex="-1"— focusable by script/click, never tabbable) since the keyboard shortcuts work while the play button and waveform are focused.Behavior
preventDefaultavoids a double-fire)Tests
test/player.test.js— added focus/shortcut coverage (focus stays on the play button on activation; Space starts/pauses with the play button focused; Space toggles from the slider; click-to-focus the container; mute viam). Full suite: 79 passing.Follow-up (not in this PR)
The playback-speed control (
showPlaybackSpeed) is a button that spawns a menu of buttons; it should become a proper dropdown.🤖 Generated with Claude Code