Fix tooltips within context menu portals being unreliable (#31129)

* Fix tooltips within context menu portals being unreliable

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update snapshots

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Add test

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski
2025-10-31 09:00:01 +00:00
committed by GitHub
parent bbb16f7ea9
commit c7f07f4c29
4 changed files with 97 additions and 45 deletions

View File

@@ -12,6 +12,7 @@ import React, { type JSX, type CSSProperties, type RefObject, type SyntheticEven
import ReactDOM from "react-dom";
import classNames from "classnames";
import FocusLock from "react-focus-lock";
import { TooltipProvider } from "@vector-im/compound-web";
import { type Writeable } from "../../@types/common";
import UIStore from "../../stores/UIStore";
@@ -425,15 +426,17 @@ export default class ContextMenu extends React.PureComponent<React.PropsWithChil
onContextMenu={this.onContextMenuPreventBubbling}
>
{background}
<div
className={menuClasses}
style={menuStyle}
ref={this.collectContextMenuRect}
role={managed ? "menu" : undefined}
{...divProps}
>
{body}
</div>
<TooltipProvider>
<div
className={menuClasses}
style={menuStyle}
ref={this.collectContextMenuRect}
role={managed ? "menu" : undefined}
{...divProps}
>
{body}
</div>
</TooltipProvider>
</div>
)}
</RovingTabIndexProvider>

View File

@@ -212,38 +212,41 @@ export function ReadReceiptPerson({
onAfterClick,
}: ReadReceiptPersonProps): JSX.Element {
return (
<Tooltip description={roomMember?.rawDisplayName ?? userId} caption={userId} placement="top">
<div>
<MenuItem
className="mx_ReadReceiptGroup_person"
onClick={() => {
dis.dispatch({
action: Action.ViewUser,
// XXX: We should be using a real member object and not assuming what the receiver wants.
// The ViewUser action leads to the RightPanelStore, and RightPanelStoreIPanelState defines the
// member property of IRightPanelCardState as `RoomMember | User`, so were fine for now, but we
// should definitely clean this up later
member: roomMember ?? ({ userId } as User),
push: false,
});
onAfterClick?.();
}}
>
<MemberAvatar
member={roomMember}
fallbackUserId={userId}
size="24px"
aria-hidden="true"
aria-live="off"
resizeMethod="crop"
hideTitle
/>
<div className="mx_ReadReceiptGroup_name">
<p>{roomMember?.name ?? userId}</p>
<p className="mx_ReadReceiptGroup_secondary">{formatDate(new Date(ts), isTwelveHour)}</p>
</div>
</MenuItem>
</div>
<Tooltip
description={roomMember?.rawDisplayName ?? userId}
caption={userId}
placement="top"
isTriggerInteractive={false}
>
<MenuItem
className="mx_ReadReceiptGroup_person"
onClick={() => {
dis.dispatch({
action: Action.ViewUser,
// XXX: We should be using a real member object and not assuming what the receiver wants.
// The ViewUser action leads to the RightPanelStore, and RightPanelStoreIPanelState defines the
// member property of IRightPanelCardState as `RoomMember | User`, so were fine for now, but we
// should definitely clean this up later
member: roomMember ?? ({ userId } as User),
push: false,
});
onAfterClick?.();
}}
>
<MemberAvatar
member={roomMember}
fallbackUserId={userId}
size="24px"
aria-hidden="true"
aria-live="off"
resizeMethod="crop"
hideTitle
/>
<div className="mx_ReadReceiptGroup_name">
<p>{roomMember?.name ?? userId}</p>
<p className="mx_ReadReceiptGroup_secondary">{formatDate(new Date(ts), isTwelveHour)}</p>
</div>
</MenuItem>
</Tooltip>
);
}