Skip to content

Commit

Permalink
Return outOfBounds synchronously, no useEffect delay
Browse files Browse the repository at this point in the history
  • Loading branch information
acusti committed Nov 18, 2023
1 parent 9f0d8dc commit bb11352
Showing 1 changed file with 37 additions and 46 deletions.
83 changes: 37 additions & 46 deletions packages/use-is-out-of-bounds/src/useIsOutOfBounds.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import useBoundingClientRect from '@acusti/use-bounding-client-rect';
import * as React from 'react';

const { useCallback, useEffect, useRef, useState } = React;
const { useEffect, useRef, useState } = React;

type MaybeHTMLElement = HTMLElement | null;
type OutOfBounds = {
Expand Down Expand Up @@ -79,12 +79,8 @@ const getWillBeOutOfBounds = ({
};

const useIsOutOfBounds = (element: MaybeHTMLElement): OutOfBounds => {
const [outOfBounds, _setOutOfBounds] = useState<OutOfBounds>(INITIAL_OUT_OF_BOUNDS);
const [outOfBounds, setOutOfBounds] = useState<OutOfBounds>(INITIAL_OUT_OF_BOUNDS);
const outOfBoundsRef = useRef<OutOfBounds>(outOfBounds);
const setOutOfBounds = useCallback((nextOutOfBounds: OutOfBounds) => {
_setOutOfBounds(nextOutOfBounds);
outOfBoundsRef.current = nextOutOfBounds;
}, []);
const elementRect = useBoundingClientRect(element);
const offsetParent = getOverflowHiddenParent(element);
const offsetParentRect = useBoundingClientRect(offsetParent);
Expand All @@ -94,16 +90,23 @@ const useIsOutOfBounds = (element: MaybeHTMLElement): OutOfBounds => {
}

useEffect(() => {
if (elementRect.top == null) {
setOutOfBounds(INITIAL_OUT_OF_BOUNDS);
return;
}

if (offsetParentRect.top == null) {
setOutOfBounds(INITIAL_OUT_OF_BOUNDS_HAS_LAYOUT);
return;
}
setOutOfBounds(outOfBoundsRef.current);
}, [
elementRect.bottom,
elementRect.left,
elementRect.right,
elementRect.top,
offsetParentRect.bottom,
offsetParentRect.left,
offsetParentRect.right,
offsetParentRect.top,
]);

if (elementRect.top == null) {
outOfBoundsRef.current = INITIAL_OUT_OF_BOUNDS;
} else if (offsetParentRect.top == null) {
outOfBoundsRef.current = INITIAL_OUT_OF_BOUNDS_HAS_LAYOUT;
} else {
const elementBottom = elementRect.bottom!;
const elementLeft = elementRect.left!;
const elementRight = elementRect.right!;
Expand Down Expand Up @@ -172,41 +175,29 @@ const useIsOutOfBounds = (element: MaybeHTMLElement): OutOfBounds => {
? offsetParentRight - elementLeft
: elementRight - offsetParentLeft;

// Do nothing if none of the outOfBounds values have changed
// Only overwrite outOfBoundsRef if one of the values has changed
if (
previousOutOfBounds.hasLayout &&
bottom === previousOutOfBounds.bottom &&
left === previousOutOfBounds.left &&
maxHeight === previousOutOfBounds.maxHeight &&
maxWidth === previousOutOfBounds.maxWidth &&
right === previousOutOfBounds.right &&
top === previousOutOfBounds.top
!previousOutOfBounds.hasLayout ||
bottom !== previousOutOfBounds.bottom ||
left !== previousOutOfBounds.left ||
maxHeight !== previousOutOfBounds.maxHeight ||
maxWidth !== previousOutOfBounds.maxWidth ||
right !== previousOutOfBounds.right ||
top !== previousOutOfBounds.top
) {
return;
outOfBoundsRef.current = {
bottom,
hasLayout: true,
left,
maxHeight,
maxWidth,
right,
top,
};
}
}

setOutOfBounds({
bottom,
hasLayout: true,
left,
maxHeight,
maxWidth,
right,
top,
});
}, [
elementRect.bottom,
elementRect.left,
elementRect.right,
elementRect.top,
offsetParentRect.bottom,
offsetParentRect.left,
offsetParentRect.right,
offsetParentRect.top,
setOutOfBounds,
]);

return outOfBounds;
return outOfBoundsRef.current;
};

export default useIsOutOfBounds;

0 comments on commit bb11352

Please sign in to comment.