Nested tooltips don't function as intended
What package has an issue
@mantine/core
Describe the bug
Nested tooltips seem to inherit each-others properties leading to buggy behaviors or not showing at all.
See the linked demo where we attempt to nest a clickable Tooltip inside of a hoverable Tooltip, and instead neither fires.
What version of @mantine/hooks page do you have in package.json?
5.2.0
If possible, please include a link to a codesandbox with the reproduced problem
https://codesandbox.io/s/optimistic-meadow-95x4i9
Do you know how to fix the issue
No
Are you willing to participate in fixing this issue and create a pull request with the fix
Yes
Possible fix
Unknown. It works with TippyJS, however they manage this.
We had a custom wrapper to also help with this, but that doesn't help in this case either unfortunately:
function mergeRefs(refs) {
return value => {
refs.forEach(ref => {
if (typeof ref === 'function') {
ref(value);
} else if (ref != null) {
ref.current = value;
}
});
};
}
const TooltipWrap = forwardRef(({ label, tooltipOpts = {}, children }, ref) => {
const mergedRefs = mergeRefs([children.ref, ref]);
return label ? (
<Tooltip
{...{
label,
// NOTE: Doesn't work even if we use ...props here
}}
{...tooltipOpts}
>
{React.cloneElement(children, { ref: mergedRefs })}
</Tooltip>
) : (
React.cloneElement(children, { ref: mergedRefs })
);
});
@rtivital could you comment on whether should nested tooltips work or should we back out of transitioning to Mantine's tooltips?
I assume they should work since you removed "review required"?
Yes, I will try to resolve this, not sure if it is possible yet
My example presumed that focus would fire in response to click events, which was mistaken. Here's an updated repro
https://codesandbox.io/s/inspiring-snow-zh1y16?file=/src/App.tsx
Note that the nested tooltips can work if the top level tooltip is a controlled component. I wonder if that might help point to a fix for nested use cases.
As a work around, if you wrap the inner ToolTip in a non fragment component (such as <Box> or <div>) it seems to work:
https://codesandbox.io/s/infallible-nash-edf3f2?file=/src/App.tsx
This makes some sense, as the Tooltip needs an immediate child element that it can reference. One approach would be to automatically wrap the children in a component if an inner Tooltip is detected as the direct child.
@rtivital If this an approach you approve of I could put together a PR.
I don't think an interceding element is a good solution as it can affect styling. It should theoretically be possible with just forwardRef and no extra elements, I think?
Using forwardRef gets a bit tricky as the ToolTip actually needs to be rendered, in this case as an <OptionalPortal>. One could do the equivalent and avoid another element by flattening the nested tooltip(s) and creating all the necessary '<OptionalPortal>`s against the one child component. The last complication is you'd have to also merge the tooltip events in the child component as well. It all seems doable, but perhaps needlessly complicated. I could try implementing it to see if it works.
Question: does the work around get you what you need? I understand there are some concerns with styling, but if you use an inner container without any style (such as <Box>) then the side effects seem manageable.
Never mind my previous comment - there is a simpler solution which involves merging the incoming events (from the parent tooltip) with the current tooltip. I did a quick test and it appears to work. I'll see if I can't put together a PR.
Damn, fixed before I even got to reply! Thanks a ton @nfbuckley!
This issue is closed by #2768.
@nfbuckley @rtivital I figured I could remove our span around our inner tooltips now, but when I did, the inner tooltip now appears in a totally unexpected location (upper-left corner of the screen.) It only occurs when using withinPortal.
I thought maybe because we defined defaultProps for Portal through MantineProvider, but when I remove that - no difference.
So far, I'm not sure how to reproduce this in a sandbox though, I guess it's not particularly easy to instigate. Any ideas?

Edit:
Actually, removing the span seems to break positioning even without withinPortal, albeit very minorly, by 10ish pixels, rather than moving it across the entire screen.
Provide a sandbox that reproduces the issue
@rtivital I've tried to reproduce it and I'll continue to try. I'm asking if you have any ideas what CSS properties or patterns might be relevant to the portaled tooltip losing its positioning?
So far, I'm not sure how to reproduce this in a sandbox though, I guess it's not particularly easy to instigate. Any ideas?
For example, I can get the positioning screwed up using absolute positioning on the child - but this appears to be a separate oddity that doesn't move the tooltip to the zero-point of its portal. I say "separate" because in our actual code nothing is absolute positioned, and the outcome here is a bit different.
I've played with a number of properties but haven't been able to reproduce quite what we're seeing.