From f997f730e1607ff6dd49dc00c59fe7b6ff5a2f6f Mon Sep 17 00:00:00 2001 From: Roland Date: Sun, 2 Aug 2026 17:57:27 -0600 Subject: [PATCH] review: name the icon-only controls, and make two guards mean what they say Acting on the review of #626. No bugs; one suggestion and three nits. The map's icon-only controls had no accessible name. IconButton requires a label by construction and AddToPlaylistButton supplies one, but the plain Button and APIButton used for edit, delete and the catalog preview reached assistive tech as unnamed buttons -- and my own Cypress fixtures carefully passed `aria-label` on the same pattern while production did not, which is its own kind of tell. All four are named now, and named with the row's subject rather than the verb alone: "Delete Water tank", not "Delete", because a table of pins otherwise offers a screen reader a column of identical buttons. A source guard holds that: it scans for controls that carry an icon and no label text, and reports any without an `aria-label`. Paired with a premise that it found some, since a scanner matching nothing reads exactly like a clean file. The Group guard asserted only that ``, so controls after the closing tag still counted as inside, and the empty-Group plant stayed green. Slicing between the tags makes it fail. Coverage the review asked for: the Semantic size names the call sites actually use (`small`, `big`, `huge`) rather than only the Mantine ones, since the translation step was untested on the exact spellings that were broken; icon-only buttons stay square while loading, when the glyph is replaced by a spinner sized from the button's height; and `iconAfter`-only squares as well as `icon`-only. On the size passthrough, which was flagged as the highest-risk change outside the map: the buttons that grow are Settings' Shutdown and Reboot (`huge`, to 60px), Settings' Upgrade and Save and Channels' Save (`big`, to 50px), and VideoPlayer's Refresh (`large`, to 50px). All six read as deliberate emphasis -- the two biggest are the two destructive ones -- so they are left honoured rather than re-broken at the call site. `size='small'` resolves to `sm`, which is what the accidental default already was, so the detail pages do not move. 1134 jest / 64 suites, 246 in ui-layout.cy.js, clean npm run build. --- app/src/components/Map.js | 6 +- app/src/components/Map.test.js | 84 ++++++++++++++++++++++++++- app/src/components/ui/ui-layout.cy.js | 59 +++++++++++++++++++ 3 files changed, 146 insertions(+), 3 deletions(-) diff --git a/app/src/components/Map.js b/app/src/components/Map.js index 46b832f3..815a2077 100644 --- a/app/src/components/Map.js +++ b/app/src/components/Map.js @@ -235,6 +235,7 @@ function MapCatalogRow({item, subscribedRegions, fetchData}) { {bbox &&