react-tooltip
react-tooltip copied to clipboard
hide tootip when click a button in ReactTooltip
` <Icon name="email" data-tip data-for="GIN" data-event="click focus" />
<ReactTooltip id="GIN" aria-haspopup="true" place="top" globalEventOff="click">
<div>
Resend confirmation email?
<div className={styles.toolTipButton}>
<Button type="primary" onClick={() => { ReactTooltip.hide(); }}>Yes</Button>
<Button>No</Button>
</div>
</div>
</ReactTooltip>`
when I click the yes button the tooltip doesn't hide immediately. It just hide after i move the away from the button. it seems the ReactTooltop.hide() function doesn't work.How can i hide the tooltip immediately when i click the yes button
@windinging When you call hideTooltip, This function will check if the mouse is on the tooltip on this line https://github.com/wwayne/react-tooltip/blob/master/src/index.js#L443. If the mouse is on tooltip, it will wait for the mouse to exit the tooltip to close the tooltip.
There is no explicit prop to set to avoid this check and close the tooltip even if the mouse is over the tooltip.
This is super hacky but if you look at https://github.com/wwayne/react-tooltip/blob/master/src/index.js#L164 of the mouseOnTooltip function, the code will check if the tooltipRef is set on the ReactTooltip instance. If it isn't, it will return false. You can set that to null before calling hideTooltip which will allow you to close the tooltip.
@stearagon
how can i set mouseOnTooltip to null
@windinging You can set a ref on tooltip <Tooltip ref={el => this.tooltip = el} />
then have your close function include this.tooltip.tooltipRef = null before you call ReactTooltip.hide
@windinging Can you share your code with this solution?
Hello!
I dont know if you still ned it but I got it working this way.

I hope it works for you! :D
I had to do something similar and it's a bit hacky, but it works with Typescript and React Hooks for the useRef:

put the ref on the ReactTooltip:

and this function for the close button inside the tooltip:

It would be nice to disable the mouseover check in this lib so we don't have to force this null, I will look into doing a PR if there's any other demands for it
@JesusJavierMoreno You are life saver man! Thank you! :)
@josh-stevens I tried your solution. It works fine for first click. When i click again next time, even without clicking close icon or clicking outside, just on entering and coming out of tooltip closes the tooltip. It happens alternate.
Add someone already optional onClose handler :)
@josh-stevens ...Thank you for your solution
A tooltip added a class of show when it gets appeared, you can get rid of that show class to hide the tooltip manually.
<button className="close-tooltip" onClick={(event) => event.target.parentNode.classList.remove('show')>X</button>
I'm not sure how clean this is, but I wasn't able to get the other solutions to work, but something like this worked great using functional components and typescript:
export const Example = () => {
const [showDiscoveryTag, setShowDiscoveryTag] = useState<boolean>(true)
const tooltipId = "discoveryTag"
const tooltipRef = useRef<HtmlDivElement>(null)
useEffect(() => {
const element = (tooltipRef?.current as unknown) as Element;
if (showDiscoveryTag) {
ReactTooltip.show(element)
} else {
ReactTooltip.hide(element)
}
}, [tooltipRef.current, showDiscoveryTag]);
return (
<>
<div data-event={"no-event"} data-event-off={"no-event"} ref={tooltipRef} data-tip data-for={tooltipId}>
div to show tooltip on
</div>
{showDiscoveryTag && <ReactTooltip
clickable
backgroundColor={"#6423EA"}
id={tooltipId}
place="right"
effect="solid"
>
Tooltip for the register button.
<button onClick={()=>{
setShowDiscoveryTag(false);
}
}>X</button>
</ReactTooltip>}
</>
)}
);
};
Basically just removing the component when the state changes, which overrides that weird 'wait until we're not hovering over it any more' thing.
To add on @stearagon response, to solve this in Typescript I did the following:
const ConnectionUrlHelpTooltip = () => {
const tooltipEl = useRef<ReactTooltip & { tooltipRef: Ref<HTMLElement> }>(
null!
);
return (
<ReactTooltip
id="connectionURL_help_tooltip"
ref={tooltipEl}
place="right"
effect="solid"
eventOff="click"
delayHide={0}
clickable
>
<div className="flex flex-col gap-y-4 max-w-xs p-10">
<h2 className="font-extrabold">.....</h2>
<p>
......
</p>
<button
type="button"
onClick={() => {
if ("tooltipRef" in tooltipEl.current) {
tooltipEl.current.tooltipRef = null;
}
ReactTooltip.hide();
}}
>
Got it
</button>
</div>
</ReactTooltip>
);
};
Clarifying the solution here a little for current hooks users based on some confusion I had: There are two parts required to make this work.
- Setting the
tooltipRefof theReactTooltipcomponent as null. Initially, I thought this meant setting the ref itself as null. But I see now that it's just the property on the class. That is the difference betweentooltip.current = nullandtooltip.current.tooltipRef = null. - You have to use the global
ReactTooltip.hide()option instead of passing in the target (ReactTooltip.hide(tooltip.current)). That means that this solution would not work if you have other tooltips that need to stay visible.
I also had to have two refs, one on the element it is referencing (in our case, the children passed in) and one on the ReactTooltip itself. Lastly, it will not work with any delayHide value.
Here's how it looked for us:
export const Tooltip = ({
show,
children,
data
}) => {
let { text, tooltipDirection, step, total } = data;
let child = useRef<any>(null)
let tooltip = useRef<ReactTooltip>(null)
const hideTooltip = () => {
tooltip.current.tooltipRef = null;
ReactTooltip.hide(tooltip.current);
}
const handleSkip = useCallback(
() => {
hideTooltip();
onSkip();
},
[onSkip],
)
const handleAdvance = useCallback(
() => {
hideTooltip();
onAdvance();
},
[onAdvance],
)
useEffect(() => {
if (show && child.current) ReactTooltip.show(child.current);
}, [show])
return (
<>
<div ref={child} data-tip data-for={`tip_${step}`}>
{children && children}
</div>
<div
ref={tooltip}
place={tooltipDirection ? tooltipDirection : 'top'}
event="no-event"
eventOff="no-event"
id={`tip_${step}`}
type='light'
effect='solid'
clickable
>
<div>
{text}
</div>
</div>
</>
);
};