react-tooltip
react-tooltip copied to clipboard
Multiple tooltip in same page open all at the same time
I usually have multiple react-tooltip for each place I want to show a tooltip.
Problem, after clicking the second tooltip, the first tooltip does not close. Therefore, user is seeing both tooltip opening at the same time.
My assumption is that data-for
and id
is there to avoid this from happening
<a data-event="click" data-for="first-click" data-tip="firstClick">
first tooltip
</a>
<ReactTooltip globalEventOff="click" id="first-click" />
<a data-event="click" data-for="second-click" data-tip="second-click">
second tooltip
</a>
<ReactTooltip globalEventOff="click" id="second-click" />
I understand that a better way is to put only one reacttooltip for the whole app. But, is there any way to make multiple reacttooltip to work?
Thank you for the working sample code and example code.
This is obviously only a problem when using the data-event="click"
activation - so one work-around is to use a hovering tool-tip.
data-id
is primarily used to connect a specific tooltip with a target, but I can see how it could help in this case. Do you think you might be able to look for a solution and submit a pull request?
A potential work-around is to add an afterShow event handler and hide the other tooltips manually.
@aronhelser Working on a major release now, will come back and raise a PR. Thanks for the solution
@aronhelser can you explain more about this work-around ? how can you hide other tooltips after the show of some tooltip ?
@joedevgee something new about this PR ?
Not sure if that will fulfill your requirements, but if you reach this issue there is a chance that below workaround may come in handy:
const TooltipDemo = (props) => {
const [isTooltipOpen, setTooltipOpen] = React.useState(false)
const tooltipWrapperRef = React.useRef(null)
const hideTooltipHandler = React.useCallback(() => {
const tooltipWrapperEl = tooltipWrapperRef.current
if (tooltipWrapperEl) {
ReactTooltip.hide(tooltipWrapperEl)
setTooltipOpen(false)
document.removeEventListener("click", hideTooltipHandler)
}
}, [])
const onTooltipTriggerClick = React.useCallback(() => {
const tooltipWrapperEl = tooltipWrapperRef.current
if (tooltipWrapperEl) {
if (isTooltipOpen) {
ReactTooltip.hide(tooltipWrapperEl)
setTooltipOpen(false)
} else {
ReactTooltip.show(tooltipWrapperEl)
setTooltipOpen(true)
document.addEventListener("click", hideTooltipHandler)
}
}
}, [isTooltipOpen])
React.useEffect(() => {
return () => {
document.removeEventListener("click", hideTooltipHandler)
}
}, [])
return (
<section>
<div
data-tip
data-for={props.id}
ref={tooltipWrapperRef}
data-event="click"
data-event-off=""
onClick={onTooltipTriggerClick}
>
/* your tooltip trigger here */
</div>
<ReactTooltip
id={props.id}
place="bottom"
type="light"
border
isCapture
effect="solid"
>
/* your tooltip content here */
</ReactTooltip>
</section>
)
}
With multiple TooltipDemo
components on one page the problem described by @joedevgee no longer occurs.
@kkowalczuk do you mind doing your workaround using render props? I don't understand hooks that much yet
you need to set data-event-off property
data-event-off="mouseleave"
or you can combine with click if you need to work it on hover and click together
data-event-off="mouseleave click"
My workaround was to hide all tooltip with a onMouseEnter
<div
data-tip
data-for={props.id}
onMouseEnter={()=>ReactTooltip.hide()}
>
/* your tooltip trigger here */
</div>
<ReactTooltip
id={id}
place="top"
event="click"
globalEventOff="click"
>
/* your tooltip content here */
</ReactTooltip>
i use onMouseDown to hide all tooltip
try it here : https://codesandbox.io/s/staging-feather-3q69z?file=/src/App.js
import "./styles.css";
import ReactTooltip from "react-tooltip";
const data = [
{
id: "1",
label: "Image 1",
link:
"https://images.pexels.com/photos/10344201/pexels-photo-10344201.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"
},
{
id: "2",
label: "Image 2",
link:
"https://images.pexels.com/photos/10400270/pexels-photo-10400270.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"
},
{
id: "3",
label: "Image 3",
link:
"https://images.pexels.com/photos/2567854/pexels-photo-2567854.png?auto=compress&cs=tinysrgb&dpr=1&w=500"
}
];
const wrapperStyle = {
width: "200px",
height: "200px",
background: "#0971F1",
marginTop: "100px"
};
const imageStyle = {
width: "100%"
};
const TooltipDemo = (props) => {
const stopDefault = (e) => {
e.stopPropagation();
};
const hide = (e) => {
ReactTooltip.hide();
};
return (
<section>
<a
style={{
cursor: "pointer"
}}
data-tip
data-for={props.id}
data-event="click"
onMouseDown={hide}
>
{props.label}
</a>
<ReactTooltip
id={props.id}
place="right"
effect="solid"
clickable
globalEventOff="click"
>
<div
role="tab"
onClick={stopDefault}
onSelect={stopDefault}
style={{
width: "120px"
}}
>
<img style={imageStyle} src={props.link} alt="" />
</div>
</ReactTooltip>
</section>
);
};
export default function App() {
return (
<div style={wrapperStyle}>
{data.map((i) => {
return (
<TooltipDemo
key={`tooltop${i.id}`}
id={i.id}
label={i.label}
link={i.link}
/>
);
})}
</div>
);
}