Skip to content

Commit

Permalink
Fix popover positioning and optimize rendering logic
Browse files Browse the repository at this point in the history
- Eliminate flash of incorrect position on popover open
- Simplify useLayoutEffect hook for more clean and correct positioning calculation
- Adjust event listener management in useEffect to accomplish the same
  • Loading branch information
cozmo committed Oct 5, 2024
1 parent a96b809 commit c7aef7c
Showing 1 changed file with 20 additions and 34 deletions.
54 changes: 20 additions & 34 deletions src/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,42 +94,28 @@ const PopoverInternal = forwardRef(
});

useLayoutEffect(() => {
let shouldUpdate = true;
const updatePopover = () => {
if (isOpen && shouldUpdate) {
const childRect = childRef?.current?.getBoundingClientRect();
const popoverRect = popoverRef?.current?.getBoundingClientRect();
if (
childRect != null &&
popoverRect != null &&
(!rectsAreEqual(childRect, popoverState.childRect) ||
popoverRect.width !== popoverState.popoverRect.width ||
popoverRect.height !== popoverState.popoverRect.height ||
popoverState.padding !== padding ||
popoverState.align !== align ||
positions !== prev.positions ||
reposition !== prev.reposition ||
transformMode !== prev.transformMode ||
transform !== prev.transform ||
boundaryElement !== prev.boundaryElement ||
boundaryInset !== prev.boundaryInset)
) {
positionPopover();
}

if (isOpen) {
const childRect = childRef.current?.getBoundingClientRect();
const popoverRect = popoverRef.current?.getBoundingClientRect();
if (
childRect &&
popoverRect &&
(!rectsAreEqual(childRect, popoverState.childRect) ||
popoverRect.width !== popoverState.popoverRect.width ||
popoverRect.height !== popoverState.popoverRect.height ||
popoverState.padding !== padding ||
popoverState.align !== align ||
positions !== prev.positions ||
reposition !== prev.reposition ||
transformMode !== prev.transformMode ||
transform !== prev.transform ||
boundaryElement !== prev.boundaryElement ||
boundaryInset !== prev.boundaryInset)
) {
positionPopover();
updatePrevValues();

if (shouldUpdate) {
window.requestAnimationFrame(updatePopover);
}
}
};

window.requestAnimationFrame(updatePopover);

return () => {
shouldUpdate = false;
};
}
}, [
align,
boundaryElement,
Expand Down

0 comments on commit c7aef7c

Please sign in to comment.