[P3] Live Dive profile inspector needs a mouse hover; keyboard and touch users have no way to use it #120
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Priority: P3
Type: bug
Source: full codebase review requested 2026-10-31 (independently reproduced against
2cac7cf)Location:
src/App.tsx:2215-2234,src/App.tsx:2309-2314,src/style.css:470-474Problem and evidence
The live "Dive profile" panel draws an
<svg role="img">. Its depth/time inspector (profileHover) is set only inonPointerMoveand cleared inonPointerLeave. Nothing in the panel can take focus, and there is no range input or key handler. The readout says "Hover over the profile to inspect depth and time." The other scrubbable charts all pair the chart with atype="range"input: DiveSummary.tsx:210, DiveImport.tsx:516, DiveReplayComparison.tsx:610 and ProfilePlanner.tsx:277/834. Keyboard and screen-reader users therefore cannot inspect past depth and time on the live chart. On touch, the.profile svgrule does not settouch-action: none(unlike the replay scrubber at style.css:1872). A drag gets taken over by browser scrolling, which cancels the pointer and fires pointerleave. A stationary tap fires pointerdown, pointerup and then pointerleave with no pointermove. In both cases the readout never shows a value, or resets right away.I traced this through the code; I did not run a browser. At src/App.tsx:2215-2234 the svg has only the onPointerMove and onPointerLeave handlers, with no tabIndex, onKeyDown, onPointerDown or pointer capture.
setProfileHoveris called only there (App.tsx:168, 1024). The readout text at App.tsx:2313 refers only to hovering. A grep fortype="range"shows that every other profile chart has a slider and the live Dive profile panel has none. style.css:470-474 sets no touch-action on.profile svg, while style.css:1061 and 1872 settouch-action: noneon other scrubbers. Under standard Pointer Events behaviour, touch has no hover, a tap produces no pointermove, and a scroll gesture produces pointercancel followed by pointerleave. So the readout cannot persist on touch.Suggested correction
Add a "Profile time" range input under the live chart (min 0, max dive.minutes, a small step) that drives
profileHover. Give it aria-valuetext with the formatted time and depth, matching the DiveSummary and planner sliders. AddonPointerDownwithsetPointerCapture, and settouch-action: none(or pan-y) on the svg, so a tap or drag selects a time on touch. Consider not clearing the selection on pointerleave for touch pointers. Reword the readout to something like "Drag on the profile or use the slider to inspect depth and time."Acceptance criteria
With a dive in progress or paused, a keyboard user can Tab to a Profile time slider in the Dive profile panel and change it with the arrow keys. The readout and the dashed marker then update to the chosen time and depth, and the slider announces both through aria-valuetext. On a touch emulation (Playwright hasTouch), tapping the chart leaves the readout showing a time and depth instead of the hover prompt. Regression test: render the live panel, focus the slider, press ArrowRight, and assert the readout text changes from the default prompt to a "m:ss · Depth" string. pnpm verify passes.
Scope: maintenance of the educational simulator. Preserve historical R1 acceptance and operational-validation limits.