Fix v3 Songs A–Z rail: reliable taps, precise drag, hittable size (#653)

* Fix v3 Songs A–Z rail: reliable taps, precise drag, hittable size

Follow-up to #634. Three rail bugs reported on macOS + Windows (0.3.0,
2026-06-29 — =Scr4tch=, MajorMokoto):

- Taps often did nothing ("clicked O, nothing happened"). pointerdown
  calls setPointerCapture, after which the browser retargets the
  follow-up click to the rail container, so the click handler's
  closest('.v3-azrail-letter') resolved null and a plain tap (no
  pointermove) had no other path. Drive the jump from pointerdown
  itself; reduce the click handler to keyboard activation only
  (e.detail === 0, Enter/Space).

- A drag landed short of the release ("where you release isn't where
  you get sent"). Every letter crossed fired jumpToLetter with
  behavior:'smooth'; stacked smooth-scroll animations over the
  virtualized grid lagged and settled imprecisely. jumpToLetter now
  takes a smooth flag and scrolls instantly ('auto') while scrubbing,
  animating only discrete taps/keyboard jumps, so the grid tracks the
  finger and the release lands on the let-go letter.

- The rail was too small at 1440p and didn't scale. Letters were a
  fixed .62rem glued at right:2px (~13px-tall target). They now scale
  with the viewport (clamp(.72rem, 1.4vh, 1.05rem)), sit off the edge
  with taller/wider equal-width hit targets and a hover/active
  highlight so the scrub target is visible.

Keyboard arrow-nav and present-letter gating are unchanged. Tests:
tests/js/v3_az_rail.test.js gains pointerdown-seek, keyboard-only click
guard, and instant-vs-smooth assertions (809 JS tests; the 13
pre-existing unrelated failures are unchanged).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QbexxfTt8q2tAn436MqGWF

* fix(v3): ignore non-primary buttons on A–Z rail pointerdown (PR #653 review)

Right- or middle-clicking the A–Z rail (or a secondary multi-touch
pointer) no longer triggers a seek; only the primary tap/drag scrubs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: byrongamatos <xasiklas@gmail.com>
This commit is contained in:
ChrisBeWithYou
2026-07-02 13:59:10 +02:00
committed by GitHub
co-authored by Claude Opus 4.8 byrongamatos
parent 0d28886d46
commit 15fabb62aa
4 changed files with 85 additions and 30 deletions
+14 -8
View File
@@ -1205,14 +1205,14 @@ html.fb-immersive #v3-main > .screen.active {
centered. Shown only for the grid view + alphabetical (artist/title) sorts. */
.v3-azrail {
position: fixed;
right: 2px;
right: 4px; /* off the very edge so letters aren't clipped */
top: 50%;
transform: translateY(-50%);
z-index: 25;
display: flex;
flex-direction: column;
align-items: center;
max-height: 84vh;
align-items: stretch; /* equal-width buttons → one wide, even hit column */
max-height: 92vh;
padding: 4px 1px;
user-select: none;
-webkit-user-select: none;
@@ -1224,17 +1224,23 @@ html.fb-immersive #v3-main > .screen.active {
background: none;
border: 0;
color: #94a3b8; /* fb-textDim */
font-size: .62rem;
/* Scale with viewport height so the 27-letter rail grows on tall / hi-res
displays (a fixed size looked tiny at 1440p) while still fitting 27 rows
within max-height on short screens. */
font-size: clamp(.72rem, 1.4vh, 1.05rem);
font-weight: 700;
line-height: 1.05;
padding: 1px 4px;
line-height: 1.04;
/* Vertical padding fattens the tap target (was ~13px tall → easy to miss). */
padding: clamp(2px, .55vh, 6px) 9px;
margin: 0;
cursor: pointer;
border-radius: 4px;
text-align: center;
}
.v3-azrail-letter:hover:not([disabled]),
.v3-azrail-letter.is-active {
color: #0ea5e9; /* fb-primary */
background: rgba(14, 165, 233, .15); /* visible target under the scrub */
}
.v3-azrail-letter:focus-visible {
outline: 2px solid #38bdf8; /* fb-primaryHi */
@@ -1247,7 +1253,7 @@ html.fb-immersive #v3-main > .screen.active {
/* Drag indicator bubble (Android fast-scroll pattern). */
.v3-azbubble {
position: fixed;
right: 2.6rem;
right: 2.9rem; /* clear the (now wider) rail */
top: 50%;
transform: translateY(-50%);
z-index: 26;
@@ -1269,7 +1275,7 @@ html.fb-immersive #v3-main > .screen.active {
/* Coarse-pointer / short viewports: the 27-letter rail can crowd a phone edge.
Tighten it; a collapse-to-anchors pass is a follow-up. */
@media (max-height: 640px) {
.v3-azrail-letter { font-size: .55rem; padding: 0 4px; }
.v3-azrail-letter { font-size: clamp(.5rem, 1.3vh, .62rem); padding: 0 7px; }
}
/* — Practice-aware library home: repertoire meter + "Keep practicing" shelf — */