-
Notifications
You must be signed in to change notification settings - Fork 719
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TooltipWithBounds] fix : overflowing its parent on small screens #837
Conversation
Pull Request Test Coverage Report for Build 297437244Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
Hey @LethalPants thanks for the PR! In playing with this locally there are a couple of issues:
|
Okay I'll take a look at it and make the changes. Thanks! |
Hi @LethalPants this looks gangsta, just curious do you think this is also related to #839? |
I don't think this and the overflow issue my commit fixes are related as it is persistent in the current version too, just that the tooltip is in the bottom right not sure if that was planned. Unrelated but the tooltip is under the plot in the published docs. 👀 |
… offset in all quadrants
I've changed the logic so that the position of the tooltip is change when the gap is less than 1% of the width of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LethalPants sorry for the delay, thanks for iterating on this! After playing with this version, I think something like the following might be the ideal fix:
// parentBounds.width = 0 when rendered in a `Portal`
const placeTooltipLeft = parentBounds.width
? left + offsetLeft > parentBounds.width / 2
: left + offsetLeft > window.innerWidth / 2;
const placeTooltipUp = parentBounds.height
? top + offsetTop > parentBounds.height / 2
: top + offsetTop > window.innerHeight / 2;
I think this has two benefits versus the 1% implementation:
- This always puts the tooltip in the quadrant with the most space (even if it's clipped; to avoid this I agree the Tooltip needs to have a dynamic width). With the 1% logic, if the tooltip will overflow on either side, it will still choose the side with less space (which is the bug report)
largest quadrant logic (proposed)
- This logic doesn't depend on
ownBounds.left/right
, which actually is a great performance win. If you check the example code, we often usekey={Math.random()}
for the tooltip to force updateownBounds
, but that re-mounts the component on every mouse move. If we don't needownBounds
, we can remove that and improve perf pretty significantly.
Thanks for the 🐛 report for the z-index issue in the airbnb.io/visx site, I noticed this as well and created an issue #850 |
Sorry, playing with my suggested code more also isn't 100% perfect for the I think this is better, but it isn't as robust to not needing the const placeTooltipLeft = parentBounds.width
? left + offsetLeft > parentBounds.width / 2
: left + offsetLeft + ownBounds.width > window.innerWidth;
const placeTooltipUp = parentBounds.height
? top + offsetTop + ownBounds.height > parentBounds.height
: top + offsetTop + ownBounds.height > window.innerHeight; |
My initial solution used
Can you please elaborate on this, I couldn't recreate the issue you mentioned. I'm not sure whether the tooltip is supposed to stay in the bounds of the plot but that isn't the case in the code snippet you pasted. |
@LethalPants yeah I agree that the shift at the midway point doesn't feel as great UX wise. okay what about this, it doesn't rely on let placeTooltipLeft = false;
if (parentBounds.width) {
const rightPlacementClippedPx = left + offsetLeft + ownBounds.width - parentBounds.width;
const leftPlacementClippedPx = ownBounds.width - left - offsetLeft;
placeTooltipLeft =
rightPlacementClippedPx > 0 && rightPlacementClippedPx > leftPlacementClippedPx;
} else {
placeTooltipLeft = left + offsetLeft + ownBounds.width > window.innerWidth;
}
const placeTooltipUp = parentBounds.height
? top + offsetTop + ownBounds.height > parentBounds.height
: top + offsetTop + ownBounds.height > window.innerHeight;
When
This is confusing, sorry. It only applies to the |
Sorry for the delay.
This seems fine.
I think changing to I've also pushed changes for detecting the edge with the snippet you posted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LethalPants this looks great 👌 going to go ahead and merge, thanks for all the iteration on this!
I think changing to Portal would be a better option, incase the tooltip is wider than parentBounds.width * 0.75 we can switch it to Portal, sounds good?
I think auto-switching is pretty tricky at the moment because rendering in the Portal
currently requires a ResizeObserver
polyfill so it'd be a breaking change. I think in most cases a Portal
is actually more ideal, and useTooltipInPortal
is compatible with TooltipWithBounds
so users can leverage these enhancements.
🐛 Bug Fix