[BUG] Tooltips are not closing when the hovering is too fast.
SalahAdDin opened this issue · comments
José Luis commented
Describe the bug
We are using a tooltip on a table tool to show the user the dimensions of the table it is supposed to build; as the tool is a grid composed of many div
s, the hovering is too fast and it seems the hook is unable to calculate the tooltip to close.
To Reproduce
Steps to reproduce the behavior:
- Create a grid of
div
s. - Add a tooltip to every
div
. - Go to the tool.
- Hover over the grid.
- Close the grid.
- Check the tooltips are still visible.
Expected behavior
It either:
- should close the tooltip as soon as the element is not hovered anymore (the best).
- should remove all the tooltips when the grid is not visible anymore.
Browser / OS (please complete the following information):
- OS: Manjaro Linux x86_64
- Browser: Firefox Browser
- Version: 119
Additional context
The tooltip component is the following:
const isReactText = (children) =>
["string", "number"].includes(typeof children);
const Tooltip = ({
text,
component: Component,
children,
placement,
className,
}) => {
const [isOver, hoverProps, close] = useHover({
hideOnScroll: true,
});
const { arrowProps, triggerProps, layerProps, renderLayer } = useLayer({
isOpen: isOver,
placement,
triggerOffset: 4,
auto: true,
onDisappear: () => close(),
});
let trigger;
if (isReactText(children)) {
trigger = (
<Component {...triggerProps} {...hoverProps}>
{children}
</Component>
);
} else {
// In case of an react-element, we need to clone it in order to attach our own props
trigger = React.cloneElement(children, {
...triggerProps,
...hoverProps,
});
}
return (
<>
{trigger}
{renderLayer(
<AnimatePresence>
{isOver && (
<motion.span
className={clsx("tooltip", className)}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ ease: [0.4, 0, 0.2, 1] }}
{...layerProps}
>
{text}
<Arrow {...arrowProps} size={8} roundness={0} />
</motion.span>
)}
</AnimatePresence>
)}
</>
);
};
Tooltip.defaultProps = {
component: "div",
};
export default Tooltip;
And we are using it on the grid:
{Array.from(Array(state.rows)).map((row, rowIdx) =>
Array.from(Array(state.cols)).map((col, colIdx) => (
<Tooltip text={`${colIdx + 1}x${rowIdx + 1}`} placement="top">
<div
className={clsx("tableBox__wrapper__items__item", {
"--selected":
rowIdx <= state.activeRow && colIdx <= state.activeCol,
})}
key={`col_${colIdx}_row_${rowIdx}`}
data-col={colIdx}
data-row={rowIdx}
onClick={addTable}
/>
</Tooltip>
))
)}