Row affordances become buttons; drop dead and duplicated rows #253

Closed
opened 2026-08-25 18:04:26 +01:00 by naps62-yolo · 0 comments
Owner

Six fixes to how rows read in the library deck and the search results
(DESIGN.md §9.2, §9.6). They land together because they all edit the row
helpers in web/src/main.ts and the row block in web/src/style.css.

The affordance does not read as a button. .row-add renders add on TMDB
hits, episodes on series rows and open on movie rows as bare accent text.
Give it the .control look — border, radius, the --control-h rail the chips
already sit on. It stays a <span>: the row itself is a <button>, so a
nested button is invalid markup and would steal the row's click. Nothing about
the interaction changes; the whole row is still what is clicked.

add is in the wrong place. tmdbRow (web/src/main.ts:1013-1029) appends
it between the language chip and the rating and trailer chips, so the line reads
en · ADD · 7.7 · trailer. It belongs last, where open and episodes
already are.

A TMDB hit already in the library renders twice — once under "in library",
once under "on tmdb" where it is aria-disabled and does nothing. Drop it from
the TMDB group entirely. The inLibrary set is built from the same response's
library hits, so anything filtered out is guaranteed to be visible in the group
above. Hide the TMDB group and correct its count when filtering empties it. The
inLibrary branch of tmdbRow and its aria-disabled return path become dead
code and go with it.

Series have no poster in list mode. seriesRow (web/src/main.ts:2711)
builds its row by hand and never calls rowPoster, while libraryRow uses
richRow() and does. Series rows in the library list are the only rows in the
app with a hole where the poster goes. Use richRow().

The hero has a border. .movie-hero on both title pages also carries
.module, whose border and inset highlight fight the backdrop that bleeds to
the rail. Drop the border on the hero specifically.

available becomes a green check. The word is the longest chip on a dense
episode list and says the least — a file is either there or it is not. Replace
it with a check glyph tinted --signal-ok, keeping the word in the chip's
aria-label.

This contradicts DESIGN.md §4.2 — "The word stays present in every chip, so
state survives with colour removed" — so amend §4.2 in this issue. The
amendment: a check glyph is a shape, not only a hue, so the greyscale read
survives; the rule stands for chips whose state is a word with no unambiguous
glyph, which is every status chip §4.2 lists. Scope the change to
mediaStateChip, not to the derived-status chips.

Depends on: #252

Six fixes to how rows read in the library deck and the search results (DESIGN.md §9.2, §9.6). They land together because they all edit the row helpers in `web/src/main.ts` and the row block in `web/src/style.css`. **The affordance does not read as a button.** `.row-add` renders `add` on TMDB hits, `episodes` on series rows and `open` on movie rows as bare accent text. Give it the `.control` look — border, radius, the `--control-h` rail the chips already sit on. It stays a `<span>`: the row itself is a `<button>`, so a nested button is invalid markup and would steal the row's click. Nothing about the interaction changes; the whole row is still what is clicked. **`add` is in the wrong place.** `tmdbRow` (`web/src/main.ts:1013-1029`) appends it between the language chip and the rating and trailer chips, so the line reads `en · ADD · 7.7 · trailer`. It belongs last, where `open` and `episodes` already are. **A TMDB hit already in the library renders twice** — once under "in library", once under "on tmdb" where it is `aria-disabled` and does nothing. Drop it from the TMDB group entirely. The `inLibrary` set is built from the same response's library hits, so anything filtered out is guaranteed to be visible in the group above. Hide the TMDB group and correct its count when filtering empties it. The `inLibrary` branch of `tmdbRow` and its `aria-disabled` return path become dead code and go with it. **Series have no poster in list mode.** `seriesRow` (`web/src/main.ts:2711`) builds its row by hand and never calls `rowPoster`, while `libraryRow` uses `richRow()` and does. Series rows in the library list are the only rows in the app with a hole where the poster goes. Use `richRow()`. **The hero has a border.** `.movie-hero` on both title pages also carries `.module`, whose border and inset highlight fight the backdrop that bleeds to the rail. Drop the border on the hero specifically. **`available` becomes a green check.** The word is the longest chip on a dense episode list and says the least — a file is either there or it is not. Replace it with a check glyph tinted `--signal-ok`, keeping the word in the chip's `aria-label`. This contradicts DESIGN.md §4.2 — "The word stays present in every chip, so state survives with colour removed" — so **amend §4.2 in this issue**. The amendment: a check glyph is a shape, not only a hue, so the greyscale read survives; the rule stands for chips whose state is a word with no unambiguous glyph, which is every status chip §4.2 lists. Scope the change to `mediaStateChip`, not to the derived-status chips. Depends on: #252
naps62-yolo added this to the Feedback pass 3 milestone 2026-08-25 18:04:26 +01:00
naps62-yolo added the area/webdifficulty/moderatetype/bug labels 2026-08-25 18:04:26 +01:00
naps62-yolo added a new dependency 2026-08-25 18:04:36 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: yolo/arr#253