Demote the album page version selector to a disclosure #120

Merged
logan merged 1 commits from feat/17-demote-version-selector into main 2026-08-19 05:38:26 +00:00
Collaborator

Closes #17 — the last Phase 1 item before #28, and the one #73 pairs
with #38 as "same page, do it in the same pass".

Commits

commit issue what
905654c feat(explore): demote the album page's version selector to a disclosure #17 the move, the two unguarded blocks that shared its slot, and the line that says which version you chose

What was actually in that slot

The report says one control. Reading it, there were three, and only the
first was guarded by "is there even a choice":

  1. the selector, behind distinctTracklistCount() <= 1;
  2. a Versions / Loading releases… block with no guard, so it took
    the primary position on every album load — beside
    renderTracklist's own "Loading tracks…", which is the same fetch
    reported twice;
  3. a Versions / <error> block, also unguarded, duplicating what
    catalog-scope-notice shows at the top of the page with a retry
    every path that sets errorReleases also sets catalogFailed,
    which is the only route to unavailable.

Plus renderVersionMeta, which explains in prose above the tracklist
that the standard version is picked "by weighing how many physical
releases share it, release status, and release date". That is a
sentence about our clustering heuristic in the most valuable space on
the page.

The shape

"Other versions of this album (N)", below the tracklist, collapsed. A
real <button aria-expanded aria-controls> inside the heading that
names the section, body rendered unconditionally and toggled with
hidden — both config-section's rules, not new ones, and the second
because aria-controls has to name an element that is in the DOM.

Of the three placements the Direction offers: the overflow menu needs a
menu this page does not have, and "near the release metadata" puts the
control in the header while its panel lives elsewhere, which splits
aria-controls from the thing it names.

Why this was a rewrite and not a move

renderTracklist returned nothing on errorReleases and leaned on
the selector's own error block to have said it. A control inside a
collapsed disclosure cannot be a page's error surface. The failure
belongs to the list that is missing because of it, so that is where it
is drawn now — and the duplicate at the top of the page stops being a
duplicate.

What had to survive

  • The ★ and the words "in your library" on the matching entry,
    unchanged, inside the panel.
  • Which version is on screen. The default is what the header
    already describes, so stating it on every album would be this issue's
    own complaint one size smaller. defaultVersionKey is the test: a
    line appears above the tracklist only once someone has chosen
    another, naming it and offering the way back.
  • The panel stays open after a choice. A panel that shuts on use
    cannot be used twice.
  • The <select> also loses an aria-label of "Select release version"
    that outranked its own visible <label>Version</label> — a label not
    in the name.

The "Show the whole album" switch stays where it is: that is #7's
control, it is not a metadata task, and it belongs next to the list it
changes.

Verification actually run

make ui-test          # 883 passed (77 files), up from 871
frontend/node_modules/.bin/tsc --noEmit   # clean
make e2e              # 114 passed, chromium, against a seeded app
make css-check        # 127 files, no broken literals

12 new specs in album-version-demotion.test.ts. The disclosure's name
goes through page.getByRole('button', …) — the browser's own answer —
because a disclosure that cannot be tabbed to is the fault
config-section shipped for every setting in the app, and a shadow
query cannot tell you a control has a name.

And it was looked at, not only asserted. Against make dev-headless SEED=default, driving the real component in the real app
(where the theme actually reaches :root, which the component tier
cannot see): the collapsed page, the open panel, a chosen version
swapping the tracklist from 10 rows to 14, and 390×800 with
document.body.scrollWidth === 390.

Filed on the way

  • #119dev-headless silently talks to whatever already holds
    its port. A yj-dev orphaned by a deleted worktree two days ago made
    make sandbox-seed fail with no such table: libraries against a
    fresh YJ_HOME, which reads exactly like a schema bug and is not.
  • A comment on #66 rather than a new issue, since that Direction
    names the version selector as a likely culprit for the phone-width
    overflow: it is no longer in the header row at all, and the real
    culprit is measured there — the cover art keeps its desktop size, so
    the title renders as G… and "Request this" is clipped, while
    body.scrollWidth stays equal to the viewport. That last part is why
    layout-overflow.spec.ts cannot see it.

Releases are manual (#115), so merging cuts no version.

Closes #17

Closes #17 — the last Phase 1 item before #28, and the one #73 pairs with #38 as "same page, do it in the same pass". ## Commits | commit | issue | what | | --- | --- | --- | | `905654c` feat(explore): demote the album page's version selector to a disclosure | #17 | the move, the two unguarded blocks that shared its slot, and the line that says which version you chose | ## What was actually in that slot The report says one control. Reading it, there were three, and only the first was guarded by "is there even a choice": 1. the selector, behind `distinctTracklistCount() <= 1`; 2. a `Versions / Loading releases…` block with **no** guard, so it took the primary position on every album load — beside `renderTracklist`'s own "Loading tracks…", which is the same fetch reported twice; 3. a `Versions / <error>` block, also unguarded, duplicating what `catalog-scope-notice` shows at the top of the page *with a retry* — every path that sets `errorReleases` also sets `catalogFailed`, which is the only route to `unavailable`. Plus `renderVersionMeta`, which explains in prose above the tracklist that the standard version is picked "by weighing how many physical releases share it, release status, and release date". That is a sentence about our clustering heuristic in the most valuable space on the page. ## The shape "Other versions of this album (N)", below the tracklist, collapsed. A real `<button aria-expanded aria-controls>` inside the heading that names the section, body rendered unconditionally and toggled with `hidden` — both `config-section`'s rules, not new ones, and the second because `aria-controls` has to name an element that is in the DOM. Of the three placements the Direction offers: the overflow menu needs a menu this page does not have, and "near the release metadata" puts the control in the header while its panel lives elsewhere, which splits `aria-controls` from the thing it names. ## Why this was a rewrite and not a move `renderTracklist` returned `nothing` on `errorReleases` and leaned on the selector's own error block to have said it. A control inside a collapsed disclosure cannot be a page's error surface. The failure belongs to the list that is missing because of it, so that is where it is drawn now — and the duplicate at the top of the page stops being a duplicate. ## What had to survive - **The ★ and the words "in your library"** on the matching entry, unchanged, inside the panel. - **Which version is on screen.** The default is what the header already describes, so stating it on every album would be this issue's own complaint one size smaller. `defaultVersionKey` is the test: a line appears above the tracklist *only* once someone has chosen another, naming it and offering the way back. - **The panel stays open after a choice.** A panel that shuts on use cannot be used twice. - The `<select>` also loses an `aria-label` of "Select release version" that outranked its own visible `<label>Version</label>` — a label not in the name. The "Show the whole album" switch stays where it is: that is #7's control, it is not a metadata task, and it belongs next to the list it changes. ## Verification actually run ``` make ui-test # 883 passed (77 files), up from 871 frontend/node_modules/.bin/tsc --noEmit # clean make e2e # 114 passed, chromium, against a seeded app make css-check # 127 files, no broken literals ``` 12 new specs in `album-version-demotion.test.ts`. The disclosure's name goes through `page.getByRole('button', …)` — the browser's own answer — because a disclosure that cannot be tabbed to is the fault `config-section` shipped for every setting in the app, and a shadow query cannot tell you a control has a name. **And it was looked at, not only asserted.** Against `make dev-headless SEED=default`, driving the real component in the real app (where the theme actually reaches `:root`, which the component tier cannot see): the collapsed page, the open panel, a chosen version swapping the tracklist from 10 rows to 14, and 390×800 with `document.body.scrollWidth === 390`. ## Filed on the way - **#119** — `dev-headless` silently talks to whatever already holds its port. A `yj-dev` orphaned by a deleted worktree two days ago made `make sandbox-seed` fail with `no such table: libraries` against a fresh `YJ_HOME`, which reads exactly like a schema bug and is not. - **A comment on #66** rather than a new issue, since that Direction names the version selector as a likely culprit for the phone-width overflow: it is no longer in the header row at all, and the real culprit is measured there — the cover art keeps its desktop size, so the title renders as `G…` and "Request this" is clipped, while `body.scrollWidth` stays equal to the viewport. That last part is why `layout-overflow.spec.ts` cannot see it. Releases are manual (#115), so merging cuts no version. Closes #17
logan added 1 commit 2026-08-19 05:26:22 +00:00
feat(explore): demote the album page's version selector to a disclosure
CI / check (push) Skipped
CI / e2e (push) Skipped
CI / check (pull_request) Successful in 2m26s
CI / e2e (pull_request) Successful in 5m59s
905654cc84
Choosing which pressing you are looking at is an advanced,
metadata-repair task, and it sat directly above the tracklist with a
heading, a `<select>` and a paragraph explaining how our clustering
picks a "standard version" by weighing release count, status and date.
That is a sentence about our own heuristic in the most valuable space
on the page.

It is now "Other versions of this album (N)" below the tracklist: a
real `<button aria-expanded aria-controls>` inside the heading that
names the section, with the body rendered unconditionally and toggled
with `hidden`, because `aria-controls` has to name an element that is
in the DOM. Both rules are `config-section`'s rather than new ones.
It is demoted, not removed — matching the wrong release is a real
problem and this is how it gets fixed.

**Two more blocks shared that slot and neither was guarded.** The
selector at least had `distinctTracklistCount() <= 1`; the
`Versions / Loading releases…` spinner and the `Versions / <error>`
block did not, so both took the primary position on every album
regardless of whether there was ever going to be a choice. The spinner
said what `renderTracklist` was already saying about the same fetch, so
it is gone. The error was the one `catalog-scope-notice` shows at the
top of the page with a retry — every path that sets `errorReleases`
also sets `catalogFailed`, the only route to `unavailable`.

That error is what made this a rewrite rather than a move.
`renderTracklist` returned `nothing` on `errorReleases` and leaned on
the selector's own block to have said it, and a control inside a
collapsed disclosure cannot be a page's error surface. The failure
belongs to the list that is missing because of it, so that is where it
is drawn.

**What must not be lost is which version is on screen.** The default is
what the header already describes, so saying it on every album would be
this issue's own complaint one size smaller. `defaultVersionKey` is the
test: a line appears above the tracklist only once someone has chosen
another, naming it and offering the way back. The ★ and the words "in
your library" survive unchanged inside the panel, and the panel does
not close when the selection changes — a panel that shuts on use cannot
be used twice.

The `<select>` also loses an `aria-label` of "Select release version"
that outranked its own visible `<label>Version</label>`, which is a
label not in the name.

Verified against the running app as well as the suite: the collapsed
page, the open panel, a chosen version and 390px width all read
correctly, and the shell still measures 390 in a 390 viewport.

Closes #17
logan merged commit 9375f25629 into main 2026-08-19 05:38:26 +00:00
Sign in to join this conversation.