Skip to content

Commit

Permalink
Merge pull request #18782 from cubuspl42/bounds-observer-4
Browse files Browse the repository at this point in the history
Use BoundsObserver to keep tooltip over the wrapper
  • Loading branch information
flodnv committed May 19, 2023
2 parents 9e43cb7 + cd2520f commit 2182d0c
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 160 deletions.
113 changes: 100 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"@react-navigation/drawer": "github:Expensify/react-navigation#react-navigation-drawer-v6.5.0-alpha1-gitpkg",
"@react-navigation/native": "6.0.13",
"@react-navigation/stack": "6.3.1",
"@react-ng/bounds-observer": "^0.2.1",
"@ua/react-native-airship": "^15.2.3",
"awesome-phonenumber": "^5.4.0",
"babel-plugin-transform-remove-console": "^6.9.4",
Expand Down
55 changes: 28 additions & 27 deletions src/components/Tooltip/TooltipRenderedOnPageBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ const propTypes = {
/** The distance between the top of the wrapper view and the top of the window */
yOffset: PropTypes.number.isRequired,

/** The width of the tooltip wrapper */
wrapperWidth: PropTypes.number.isRequired,
/** The width of the tooltip's target */
targetWidth: PropTypes.number.isRequired,

/** The Height of the tooltip wrapper */
wrapperHeight: PropTypes.number.isRequired,
/** The height of the tooltip's target */
targetHeight: PropTypes.number.isRequired,

/** Any additional amount to manually adjust the horizontal position of the tooltip.
A positive value shifts the tooltip to the right, and a negative value shifts it to the left. */
Expand Down Expand Up @@ -63,11 +63,11 @@ const TooltipRenderedOnPageBody = (props) => {
// The width of tooltip's inner content. Has to be undefined in the beginning
// as a width of 0 will cause the content to be rendered of a width of 0,
// which prevents us from measuring it correctly.
const [tooltipContentWidth, setTooltipContentWidth] = useState(undefined);
const [tooltipWidth, setTooltipWidth] = useState(0);
const [tooltipHeight, setTooltipHeight] = useState(0);
const [contentMeasuredWidth, setContentMeasuredWidth] = useState(undefined);
const [wrapperMeasuredWidth, setWrapperMeasuredWidth] = useState(0);
const [wrapperMeasuredHeight, setWrapperMeasuredHeight] = useState(0);
const contentRef = useRef();
const wrapper = useRef();
const rootWrapper = useRef();

useEffect(() => {
if (!props.renderTooltipContent || !props.text) {
Expand All @@ -79,40 +79,41 @@ const TooltipRenderedOnPageBody = (props) => {
useLayoutEffect(() => {
// Calculate the tooltip width and height before the browser repaints the screen to prevent flicker
// because of the late update of the width and the height from onLayout.
const rect = wrapper.current.getBoundingClientRect();
const rect = rootWrapper.current.getBoundingClientRect();

setTooltipWidth(rect.width);
setTooltipHeight(rect.height);
setTooltipContentWidth(contentRef.current.offsetWidth);
setWrapperMeasuredWidth(rect.width);
setWrapperMeasuredHeight(rect.height);
setContentMeasuredWidth(contentRef.current.offsetWidth);
}, []);

const {animationStyle, tooltipWrapperStyle, tooltipTextStyle, pointerWrapperStyle, pointerStyle} = useMemo(
const {animationStyle, rootWrapperStyle, textStyle, pointerWrapperStyle, pointerStyle} = useMemo(
() =>
getTooltipStyles(
props.animation,
props.windowWidth,
props.xOffset,
props.yOffset,
props.wrapperWidth,
props.wrapperHeight,
props.targetWidth,
props.targetHeight,
props.maxWidth,
tooltipWidth,
tooltipHeight,
tooltipContentWidth,
wrapperMeasuredWidth,
wrapperMeasuredHeight,
contentMeasuredWidth,
props.shiftHorizontal,
props.shiftVertical,
rootWrapper.current,
),
[
props.animation,
props.windowWidth,
props.xOffset,
props.yOffset,
props.wrapperWidth,
props.wrapperHeight,
props.targetWidth,
props.targetHeight,
props.maxWidth,
tooltipWidth,
tooltipHeight,
tooltipContentWidth,
wrapperMeasuredWidth,
wrapperMeasuredHeight,
contentMeasuredWidth,
props.shiftHorizontal,
props.shiftVertical,
],
Expand All @@ -125,10 +126,10 @@ const TooltipRenderedOnPageBody = (props) => {
content = (
<Text
numberOfLines={props.numberOfLines}
style={tooltipTextStyle}
style={textStyle}
>
<Text
style={tooltipTextStyle}
style={textStyle}
ref={contentRef}
>
{props.text}
Expand All @@ -139,8 +140,8 @@ const TooltipRenderedOnPageBody = (props) => {

return ReactDOM.createPortal(
<Animated.View
ref={wrapper}
style={[tooltipWrapperStyle, animationStyle]}
ref={rootWrapper}
style={[rootWrapperStyle, animationStyle]}
>
{content}
<View style={pointerWrapperStyle}>
Expand Down
Loading

0 comments on commit 2182d0c

Please sign in to comment.