refactor: give the user card context a stable, stateless contract
Proposed changes (including videos or screenshots)
UserCardContext exposed the overlay state, the triggerRef and react-aria's stateful trigger props. A single UserCardProvider serves every trigger in a room, which had two side effects:
- Re-renders: the context value changed whenever a card opened or closed, so every message header, avatar and mention subscribed to it re-rendered.
- A11y:
aria-expanded/aria-controlswere spread on every trigger, so while any one card was open, all the triggers in the room were announced as expanded.
The contract is now:
type UserCardContextValue = {
openUserCard: (e: UIEvent, username: string) => void;
openUserInfo: (username: string) => void; // new: open the full profile directly
closeUserCard: () => void;
triggerProps: AriaAttributes; // static: { 'aria-haspopup': 'dialog' }
};
All entries are identity-stable, so the value never changes. Nothing outside the provider read state or triggerRef. openUserInfo has no consumer yet; the card behavior change (click on a name opens the full profile) builds on it next.
The card still opens on click, as today.
Extracted from #41650 (user information redesign), where @ivans-netto designed this contract. Stacked on #42507; #41650 is stacked on top.
Issue(s)
Steps to test or reproduce
- Click a user's name in a message: the card opens as before; "See full profile" and the actions work.
- With a screen reader, open a card and move to another message's author: it's no longer announced as expanded.
Further comments
UserCardProvider.spec.tsx checks the context value stays the same object across opening and closing a card (it changed 3 times before) and that triggers carry no aria-expanded.
Summary by CodeRabbit
- Bug Fixes
- Opening or closing a user card no longer triggers re-renders across messages, helping keep room interactions more stable.
- Room announcements of user-card triggers no longer repeat while a card is open.
- The trigger that opens a user card now reports its expanded state to assistive technologies; other triggers remain unexpanded.
- Clicking the text inside a user-card trigger opens the card as expected.