Files
openclaw/ui
Vyctor H. Brzezowski 38e0ae6ec8 fix(ui): GitHub link hovercard closes before the pointer can reach it (#124274)
* fix(ui): keep the GitHub hovercard open while the pointer reaches it

Hover intent now spans the link and the portaled card: leaving one for the other keeps the card open through a bounded traversal grace, and only leaving both dismisses it. The card also receives pointer events again, so its text can be selected. Escape, click, focus, viewport, and route-removal dismissals are unchanged, and the close timer is cleared on every close and disconnect.

* fix(ui): make the GitHub hovercard title a navigable link

The preview card's title now renders as an <a> reusing the exact
activation href, opening in a new tab like other external Control UI
links (buildExternalLinkRel/EXTERNAL_LINK_TARGET). Because the card is
portaled to document.body outside the provider's delegated focus
listeners, focus landing on the title link needed its own tracking,
mirroring the existing pointerenter/pointerleave pattern; that focus
hold releases once the pointer leaves the card after a pointer-initiated
open, so clicking the title link can never leave a hover-opened card
stuck open with the mouse gone.

* test(ui): prove hovercard pointer traversal and title-link click in real Chromium

Extends the existing github-link-hovercard e2e test with two cases: one
drives real page.mouse.move coordinates from the source link, across the
gap, onto the portaled card, and confirms it stays open and only closes
once the pointer leaves both surfaces; the other clicks the card's title
link and confirms the resulting popup navigates to the item URL.

* fix(ui): make the GitHub hovercard an accessible interactive popover

The card declared role="tooltip" while owning a focusable title link. ARIA
tooltips are descriptive text: their content is flattened and unreachable, so
the link existed for the pointer only. Drop the tooltip contract instead of the
link, and give the card the popover semantics its content already needs.

The card is now a non-modal role="dialog" named by every render state, and the
trigger carries aria-haspopup/aria-expanded/aria-controls in place of the old
aria-describedby juggling. Because the card is portaled to document.body it has
no tab-sequence neighbour, so Tab from the trigger forwards into it, Tab moves
between its links natively, and Tab past either edge or Escape returns focus to
the trigger with the card closed and no reopen.

The card's other references are links too: the repo reference and the title open
the item, the author opens their profile, and a pull request's diff-size chip
deep-links to the files-changed view. The title keeps the card's only underline;
the rest stay quiet until hovered or focused. Pointer behavior is unchanged -
leaving both the link and the card still dismisses it after the traversal grace
period, with no click required.
2026-08-15 21:05:25 -03:00
..