Skip to content

GridList: keep a row highlighted while a control inside it has a menu… - #40

Merged
microbit-matt-hillsdon merged 1 commit into
mainfrom
gridlist-open-menu-row-highlight
Aug 4, 2026
Merged

GridList: keep a row highlighted while a control inside it has a menu…#40
microbit-matt-hillsdon merged 1 commit into
mainfrom
gridlist-open-menu-row-highlight

Conversation

@microbit-matt-hillsdon

@microbit-matt-hillsdon microbit-matt-hillsdon commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

… open

A Popover renders a position: fixed; inset: 0 underlay whenever it is not isNonModal — the default, and what MenuList uses. The pointer ends up over the underlay rather than the row, so the browser fires pointerleave and the row's hover grey drops the instant the menu opens. Chakra's Menu was a Popper with useOutsideClick and no underlay, so this only appears at an app's kill-switch, with nothing in the diff to explain it (playbook gotcha #43).

data-hovered is no help — the hover condition already covers it and it is downstream of the same pointerleave. The row needs a different question: does it hold an open overlay? A trigger carries aria-expanded from useOverlayTrigger, so :has() answers it on the row with no state plumbing between the list and whatever a call site renders inside it. Repeated inside the selected rule rather than trusting emit order, since :has() takes its argument's specificity and ties with [data-selected].

Found via classroom's class roster, which needs the same rule locally: its flat bg override silences the recipe's backgrounds (gotcha 21), so it cannot inherit this one.

Also in the playbook, from the same investigation:

  • Gotcha 37 gains the other shape of its failure: a component that calls its slot recipe with no arguments at all. GridList, ListBox and Menu all do, so an app preset that adds a variant group to them gets nothing applied. Latent — those three have no variants yet — but they are not extensible today.

  • A decisions-due entry for colorPalette in place of per-component colour tokens, to be settled after the brand ramp review. The gridList item's greys are already gray.50 and gray.100, the two stops a palette swap would use, so the roster is a small first pilot. Includes what the ramp review has to decide first (completeness, not just correctness), and why the button.* tokens stay: the brand idiom is palette-shaped at brand.500/600/700, but black plus blackAlpha.800/700 spans two token groups and no palette produces it.

… open

A Popover renders a `position: fixed; inset: 0` underlay whenever it is not
`isNonModal` — the default, and what MenuList uses. The pointer ends up over
the underlay rather than the row, so the browser fires pointerleave and the
row's hover grey drops the instant the menu opens. Chakra's Menu was a Popper
with useOutsideClick and no underlay, so this only appears at an app's
kill-switch, with nothing in the diff to explain it (playbook gotcha #43).

`data-hovered` is no help — the hover condition already covers it and it is
downstream of the same pointerleave. The row needs a different question: does
it hold an open overlay? A trigger carries `aria-expanded` from
useOverlayTrigger, so `:has()` answers it on the row with no state plumbing
between the list and whatever a call site renders inside it. Repeated inside
the selected rule rather than trusting emit order, since `:has()` takes its
argument's specificity and ties with `[data-selected]`.

Found via classroom's class roster, which needs the same rule locally: its flat
`bg` override silences the recipe's backgrounds (gotcha #21), so it cannot
inherit this one.

Also in the playbook, from the same investigation:

- Gotcha #37 gains the other shape of its failure: a component that calls its
  slot recipe with no arguments at all. GridList, ListBox and Menu all do, so
  an app preset that adds a variant group to them gets nothing applied. Latent
  — those three have no variants yet — but they are not extensible today.

- A decisions-due entry for `colorPalette` in place of per-component colour
  tokens, to be settled after the brand ramp review. The gridList item's greys
  are already gray.50 and gray.100, the two stops a palette swap would use, so
  the roster is a small first pilot. Includes what the ramp review has to decide
  first (completeness, not just correctness), and why the button.* tokens stay:
  the brand idiom is palette-shaped at brand.500/600/700, but black plus
  blackAlpha.800/700 spans two token groups and no palette produces it.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying ui with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6f52460
Status: ✅  Deploy successful!
Preview URL: https://b086e9dc.ui-2wg.pages.dev
Branch Preview URL: https://gridlist-open-menu-row-highl.ui-2wg.pages.dev

View logs

@microbit-matt-hillsdon
microbit-matt-hillsdon merged commit 6f39954 into main Aug 4, 2026
2 checks passed
@microbit-matt-hillsdon
microbit-matt-hillsdon deleted the gridlist-open-menu-row-highlight branch August 4, 2026 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant