Fix account hovercard sometimes not triggering (#39381)
This commit is contained in:
parent
8ba8ce5669
commit
2e3b81cc1e
@ -30,8 +30,8 @@ export const HoverCardController: React.FC = () => {
|
|||||||
const cardRef = useRef<HTMLDivElement | null>(null);
|
const cardRef = useRef<HTMLDivElement | null>(null);
|
||||||
const [setLeaveTimeout, cancelLeaveTimeout] = useTimeout();
|
const [setLeaveTimeout, cancelLeaveTimeout] = useTimeout();
|
||||||
const [setEnterTimeout, cancelEnterTimeout, delayEnterTimeout] = useTimeout();
|
const [setEnterTimeout, cancelEnterTimeout, delayEnterTimeout] = useTimeout();
|
||||||
const [setMoveTimeout, cancelMoveTimeout] = useTimeout();
|
|
||||||
const [setScrollTimeout] = useTimeout();
|
const [setScrollTimeout] = useTimeout();
|
||||||
|
const lastMouseMoveTime = useRef<number>(0);
|
||||||
|
|
||||||
const handleClose = useCallback(() => {
|
const handleClose = useCallback(() => {
|
||||||
cancelEnterTimeout();
|
cancelEnterTimeout();
|
||||||
@ -50,7 +50,6 @@ export const HoverCardController: React.FC = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let isScrolling = false;
|
let isScrolling = false;
|
||||||
let isUsingTouch = false;
|
let isUsingTouch = false;
|
||||||
let isActiveMouseMovement = false;
|
|
||||||
let currentAnchor: HTMLElement | null = null;
|
let currentAnchor: HTMLElement | null = null;
|
||||||
let currentTitle: string | null = null;
|
let currentTitle: string | null = null;
|
||||||
|
|
||||||
@ -84,31 +83,40 @@ export const HoverCardController: React.FC = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bail out if we're scrolling, a touch is active,
|
// This 0ms timeout is needed to push processing of this code
|
||||||
// or if there was no active mouse movement
|
// until after the mousemove event was run, in order to be able
|
||||||
if (isScrolling || !isActiveMouseMovement || isUsingTouch) {
|
// to track the most recent value of lastMouseMoveTime.current
|
||||||
return;
|
setTimeout(() => {
|
||||||
}
|
// Check if mouse moved within the active movement threshold
|
||||||
|
const timeSinceLastMove = Date.now() - lastMouseMoveTime.current;
|
||||||
|
const hasRecentMovement = timeSinceLastMove < activeMovementThreshold;
|
||||||
|
|
||||||
// We've entered an anchor
|
// Bail out if we're scrolling, a touch is active,
|
||||||
if (isHoverCardAnchor(target)) {
|
// or if there was no active mouse movement
|
||||||
cancelLeaveTimeout();
|
if (isScrolling || !hasRecentMovement || isUsingTouch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
currentAnchor?.removeAttribute('aria-describedby');
|
// We've entered an anchor
|
||||||
currentAnchor = target;
|
if (isHoverCardAnchor(target)) {
|
||||||
|
cancelLeaveTimeout();
|
||||||
|
|
||||||
currentTitle = target.getAttribute('title');
|
currentAnchor?.removeAttribute('aria-describedby');
|
||||||
target.removeAttribute('title');
|
currentAnchor = target;
|
||||||
|
|
||||||
setEnterTimeout(() => {
|
currentTitle = target.getAttribute('title');
|
||||||
open(target);
|
target.removeAttribute('title');
|
||||||
}, enterDelay);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We've entered the hover card
|
setEnterTimeout(() => {
|
||||||
if (target === currentAnchor || target === cardRef.current) {
|
open(target);
|
||||||
cancelLeaveTimeout();
|
}, enterDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We've entered the hover card
|
||||||
|
if (target === currentAnchor || target === cardRef.current) {
|
||||||
|
cancelLeaveTimeout();
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseLeave = (e: MouseEvent) => {
|
const handleMouseLeave = (e: MouseEvent) => {
|
||||||
@ -149,18 +157,15 @@ export const HoverCardController: React.FC = () => {
|
|||||||
isUsingTouch = false;
|
isUsingTouch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasMoved = Math.max(e.movementX, e.movementY) > 0;
|
const hasMoved =
|
||||||
|
Math.max(Math.abs(e.movementX), Math.abs(e.movementY)) > 0;
|
||||||
|
|
||||||
if (!hasMoved) {
|
if (!hasMoved) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
delayEnterTimeout(enterDelay);
|
delayEnterTimeout(enterDelay);
|
||||||
|
lastMouseMoveTime.current = Date.now();
|
||||||
cancelMoveTimeout();
|
|
||||||
isActiveMouseMovement = true;
|
|
||||||
setMoveTimeout(() => {
|
|
||||||
isActiveMouseMovement = false;
|
|
||||||
}, activeMovementThreshold);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
document.body.addEventListener('touchstart', handleTouchStart, {
|
document.body.addEventListener('touchstart', handleTouchStart, {
|
||||||
@ -204,8 +209,6 @@ export const HoverCardController: React.FC = () => {
|
|||||||
setOpen,
|
setOpen,
|
||||||
setAccountId,
|
setAccountId,
|
||||||
setAnchor,
|
setAnchor,
|
||||||
setMoveTimeout,
|
|
||||||
cancelMoveTimeout,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user