mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 19:01:39 -04:00
ui: the navbar shows which section you are in (#649)
* ui: the navbar shows which section you are in
Clicking Videos opened the videos page and left the bar looking untouched.
react-router was doing its part the whole time -- the tab carried `active` and
`aria-current="page"` on every one of those pages. Nothing in the stylesheet
drew that class, so all eleven tabs rendered identically and the mark was
visible only to a screen reader.
The current tab now takes a deepened version of the hover wash plus an
underline. The underline is a pseudo-element in `currentColor` rather than a
border, for two reasons: `currentColor` is the foreground the bar already
computed for whichever of the fourteen navbar colors the user picked, so one
rule covers every color in every theme without naming one; and a pseudo-element
adds no height, where a border would jog the whole row as the mark moved
between tabs. The overflow "More" menu and the mobile hamburger mark their
copy of the tab too -- on a phone that menu is where most tabs live.
Calculators and Statistics also lose `end: true`. A tab is meant to stay
current for the pages beneath it, and `end` restricts the match to the exact
path, so either one would have dropped its mark the moment it grew a sub-page.
The other nine links never had it, which is why /videos/1234 already kept
Videos marked.
The test renders the real bar, which needed two pieces of browser jsdom does
not have: fresnel renders no navbar at all unless a breakpoint query matches,
and every width is 0, which convinces the overflow logic that nothing fits and
sweeps all eleven tabs into the closed "More" menu -- where every assertion
about them would have passed vacuously. Both are stubbed, and the styling
itself is asserted against the stylesheet, since jsdom applies none.
* review: the mark follows the tab into the overflow menu
Six review points, no bugs among them. The substantive one: when the window
narrows enough to fold the current tab into "More", the bar went blank again --
the trigger is a plain button, not a NavLink, so nothing was marked until the
user opened the menu to look, which is exactly when they least need telling.
"More" now takes the mark when it holds the current section.
That needs the matching rule outside a NavLink, where the hooks that answer it
cannot be called in a loop, so `isLinkActive` states it once: a link owns the
pages beneath it unless it asks for an exact match. The trigger gets the class
only -- the real NavLink inside the menu already carries `aria-current`, and a
second one on the button that opens the menu announces the same page twice.
The other five, all fair:
* The mobile hamburger and the overflow menu had no test at all, so
`.mantine-Menu-item.active` -- the whole of the mark on a phone -- was
never exercised. Both now are, which meant splitting the viewport and the
bar width out of the fixture so a test can ask for a narrow bar or a phone.
The mobile case also needs the real getBoundingClientRect back: floating-ui
positions the menu's portal and crashes the worker on a stub DOMRect.
* The CSS guard matched the selector as a substring, which still passed with
the rule body emptied or the underline deleted -- and the underline is the
half that survives on a dark bar. It now reads the declarations.
* The table cases used `toContain`, which a regression leaving Home
permanently marked would satisfy on every row. `toEqual([text])`.
* A comment claimed the tab "only matched its own exact path", which is the
root cause the PR description explicitly rules out -- Videos never carried
`end`. Corrected to what those cases actually guard.
* The navbar offers twelve colors, not fourteen. I had carried over
Semantic's palette count, which includes black and white.
Writing the tightened height assertion I reached for `(?!0)`, which calls
0.1875rem zero. It reads the number instead.
This commit is contained in:
parent
499ef435f8
commit
eaa8b83e54
3 changed files with 309 additions and 4 deletions
|
|
@ -67,6 +67,46 @@ html .mantine-Notifications-root[data-position^='top'] {
|
|||
background: rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
/*
|
||||
* The tab for the section the user is in.
|
||||
*
|
||||
* react-router marks it with `active` and `aria-current` on its own, and always did -- the
|
||||
* mark reached the DOM and nothing here drew it, so every tab looked identical and clicking
|
||||
* Videos appeared to leave the bar untouched.
|
||||
*
|
||||
* The underline is a pseudo-element in `currentColor`, not a border: `currentColor` follows
|
||||
* the foreground the bar computed for whatever navbar color the user picked, so this works
|
||||
* on all twelve of them (see `navColorNames`) and in all four themes without naming a color;
|
||||
* and a pseudo-element adds no height, where a border would jog the whole row as the mark
|
||||
* moved between tabs. The darker wash is the hover treatment deepened, so the two read as
|
||||
* the same idea.
|
||||
*/
|
||||
.wrolpi-navbar-link.active {
|
||||
position: relative;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.wrolpi-navbar-link.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
/* rem, not px, so the mark grows with the --ui-scale setting like the text above it. */
|
||||
height: 0.1875rem;
|
||||
background: currentColor;
|
||||
}
|
||||
|
||||
/*
|
||||
* The same tabs inside the overflow "More" menu and the mobile hamburger, which are the
|
||||
* only place most of them appear on a phone. Those render in a portal, outside the bar,
|
||||
* so they take theme tokens rather than the bar's foreground.
|
||||
*/
|
||||
.mantine-Menu-item.active {
|
||||
background: var(--head);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/*
|
||||
* Everything in the bar takes the bar's foreground.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue