feat: open the user card on hover and the user info on click
Merged
GG
18d ago+639+639+012345678901234567890123456789-155-155-012345678901234567890123456789
Proposed changes (including videos or screenshots)
One interaction for every user reference (message author name and avatar, system messages, @mentions): hover opens the user card, click or Enter/Space opens the user info. The card is a pointer-only preview of what the user info shows. Today clicking opens the card, and the card's "See full profile" opens the user info.
UserCardProvider
- Opens on hover after a 500 ms intent delay; leaving the trigger before that cancels it. A click (e.g. call history, contact history) still opens it right away.
- Closes 300 ms after the pointer leaves the card, its trigger, or a menu spawned from the card (the kebab is portaled outside the card, so hover is tracked geometrically instead of with
mouseleave). - Moving straight to another author hands the card off; the card shows a skeleton instead of the previous user's data while the next one loads.
- Non-modal popover: it doesn't aria-hide the page or lock scroll, and never takes focus. Escape is handled at the document level (WCAG 1.4.13) and consumed, so it doesn't also close an underlying contextual bar; while a menu from the card is open, the menu owns Escape.
- An explicit dismissal (Escape, the card's close button, an action) also cancels a pending hover open.
- Where a click still opens the card (call history, contact history), only the trigger that opened it gets
aria-expanded. Message and mention triggers no longer carryaria-haspopup, since activating them opens the user info. UserCardDialogno longer uses react-aria'suseDialog, which focused the card on mount: a card shown on hover would otherwise take focus from what the user is doing (e.g. typing in the composer).- The document listeners are bound through the card's ref callback for as long as the card is mounted (with
Suspenseinside the card container, so the ref attaches before the card's code loads), instead of an effect keyed on the open state.
Triggers
- Message header, room/thread/system message avatars and mentions: hover opens the card, click opens the user info. Avatars are
aria-hiddenpointer shortcuts for the name button next to them, and their native tooltip is gone (the card answers the hover). - While messages are being selected, the author is not a trigger (the row toggles the selection).
- gazzodown gets an
onUserMentionHoverhandler next toonUserMentionClick.
Nothing visual changes in the card or the user info; that's the redesign in #41650. The video call changes that used to be here (creating a DM on demand) stay with the redesign in #41650.
Extracted from #41650 (user information redesign), where @ivans-netto built this behavior. Stacked on #42509; #41650 is stacked on top.
Issue(s)
Steps to test or reproduce
- Hover a message author's name, avatar, or an @mention: the card opens after a short delay and closes when the pointer leaves it.
- Move from one author straight to another: the card switches to the new user.
- Open the kebab in the card and move into the menu: the card stays open.
- Press Escape with the card open over an open contextual bar: only the card closes.
- Click an author or mention: the user info opens directly.
5b. Tab to an author's name or a mention and press Enter/Space: the user info opens, same as a click.
5c. Type in the composer and hover an author: the card opens and the composer keeps focus. - Open a thread: hovering authors in the thread panel opens the card too; clicking opens the user info.
Further comments
UserCardProvider.spec.tsxcovers the hover delay and cancel, Escape consumption, menus owning Escape, explicit dismissal cancelling a pending open, and the stable context value.- e2e updated: hover where a test needs the card, click where it needs the user info; the unused
userCardToolbarpage-object getter is removed.