mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 19:01:39 -04:00
Four things, three cosmetic and one a real legibility bug. * Tags were square chips. They now have a pointed left edge and an eyelet, like a tag tied to a garment -- the shape Semantic gave them, and the reason a tag reads as a tag rather than as a small button. The point is a square rotated behind the left edge, sized so its diagonal equals the body height and its two edges meet the body at the corners. Only where something is actually a tag. `Label` carries the count badges in the Tags table too -- file, zim, channel and domain counts -- and a point on a number reads as an arrow, so the shape is behind a `tag` prop and `NameToTagLabel` opts in. * They were smaller than what they replaced: 11.5px text with 3px of padding, against Semantic's 12px and ~7px. Now 12.5px and 5px, which also keeps them a reasonable thing to tap. * Wrapped rows of tags sat on the row above, so they carry a bottom margin, plus a left margin for the point to occupy. * The text colour was unreadable in night and wrong in amber. Tags.js calculates black-or-light against the colour the user chose for each tag, and wrote the answer to `color` inline -- a declaration no stylesheet rule can outrank. Night turns a tag into an outline over a near-black page, so a near-white tag kept the black text calculated for its fill and was left legible only by its border: 1.1:1, measured. Amber replaces every fill with its own bright orange and was painting `#dddddd` on `#ff9500`, about 1.9:1, and a neutral grey in a theme whose whole point is that no other hue reaches the eye. The fix is to stop hard-coding `color` so the theme can decide: the calculated colour goes into `--label-text`, and night and amber override it alongside the fill they already override. There is no second contrast function to write, which is what this looked like it needed -- once a theme has discarded the user's colour there is nothing left to calculate against, and the answer is just the theme's own token. `.wrolpi-label-white` and `-black` moved to the same variable. Setting `color` there outranked the base rule, so amber was painting `--white` on `--text`: light orange on orange. `contrastingColor` was also picking the worse of its two options. It compared a brightness figure against a threshold, and the figure weighted the gamma-encoded bytes without linearising them, so Semantic's blue `#2185d0` got light text at 2.9:1 where dark text gives 5.3:1. Every mid-tone blue, teal and purple a user might pick sat in that band. It now measures the WCAG contrast ratio of both candidates and returns the better one, which needs no threshold at all. Tests ----- `Tags.test.js` is new, and covers the chip nothing covered: every other spec takes `NameToTagLabel` from `tagsContextFixture`, which stubs it as a function returning the name. That is how a tag could be unreadable without a single test noticing. Two of these were verified red against the inline `color`. `cy.contrastRatio()` measures text against the surface *actually* behind it, walking up to the first ancestor that paints something -- a transparent tag has no background of its own, so a naive check reads rgba(0,0,0,0) and concludes anything is legible. Twelve cases, three tag colours across four themes, at WCAG AA. Plus a test asserting the old inline-`color` version still measures below 1.5:1, so the check is provably able to fail. The gallery had label swatches in theme colours and no user-coloured tag, which is why none of this was visible in it. It has eleven now, spanning the range where the black-or-light decision flips. |
||
|---|---|---|
| .. | ||
| admin | ||
| calculators | ||
| collections | ||
| inventory | ||
| ui | ||
| AddToPlaylist.js | ||
| Apps.js | ||
| Archive.js | ||
| ArchivePreview.js | ||
| BulkTagModal.js | ||
| BulkTagModal.test.js | ||
| Calculators.js | ||
| CbzViewer.js | ||
| Channels.cy.js | ||
| Channels.js | ||
| Common.js | ||
| Common.test.js | ||
| DatesSelector.js | ||
| DesktopToggle.test.js | ||
| Docs.js | ||
| DomainEditPage.test.js | ||
| DomainsPage.test.js | ||
| DomainTagging.test.js | ||
| DonatePage.js | ||
| Download.cy.js | ||
| Download.js | ||
| Download.test.js | ||
| ErrorBoundary.js | ||
| FileBrowser.js | ||
| FileBrowser.test.js | ||
| FilePreview.js | ||
| FilePreview.test.js | ||
| Files.js | ||
| Flasher.js | ||
| Flasher.test.js | ||
| Headline.js | ||
| HelpModal.js | ||
| KeyboardShortcutsProvider.js | ||
| Map.js | ||
| MapSearchView.js | ||
| MapViewer.js | ||
| Nav.js | ||
| otp.js | ||
| otp.test.js | ||
| Placeholder.js | ||
| Playlists.js | ||
| Playlists.test.js | ||
| Search.js | ||
| SearchFilterModal.test.js | ||
| Share.js | ||
| ShortcutHint.js | ||
| SortableTable.js | ||
| Tables.js | ||
| TaggedDeleteConfirmModal.js | ||
| TaggedDeleteConfirmModal.test.js | ||
| Theme.tsx | ||
| ThemeProvider.test.js | ||
| ThemeSamplePage.js | ||
| Upload.js | ||
| Vars.js | ||
| VideoPlayer.js | ||
| VideoPlayer.test.js | ||
| Videos.js | ||
| VncToggle.test.js | ||
| Zim.js | ||