export class TooltipInner extends React.Component<Props, State> {
throttledPositionTooltip: (() => void);
- mouseEnterInterval?: number;
- mouseLeaveInterval?: number;
+ mouseEnterTimeout?: number;
+ mouseLeaveTimeout?: number;
tooltipNode?: HTMLElement | null;
mounted = false;
mouseIn = false;
componentWillUnmount() {
this.mounted = false;
this.removeEventListeners();
- this.clearIntervals();
+ this.clearTimeouts();
}
addEventListeners = () => {
window.removeEventListener('scroll', this.throttledPositionTooltip);
};
- clearIntervals = () => {
- window.clearInterval(this.mouseEnterInterval);
- window.clearInterval(this.mouseLeaveInterval);
+ clearTimeouts = () => {
+ window.clearTimeout(this.mouseEnterTimeout);
+ window.clearTimeout(this.mouseLeaveTimeout);
};
isVisible = () => {
};
handleMouseEnter = () => {
- this.mouseEnterInterval = window.setTimeout(() => {
+ this.mouseEnterTimeout = window.setTimeout(() => {
if (this.mounted) {
- if (this.props.visible === undefined) {
+ // for some reason even after the `this.mouseEnterTimeout` is cleared, it still triggers
+ // to workaround this issue, check that its value is not `undefined`
+ // (if it's `undefined`, it means the timer has been reset)
+ if (this.props.visible === undefined && this.mouseEnterTimeout !== undefined) {
this.setState({ visible: true });
}
}
};
handleMouseLeave = () => {
- if (this.mouseEnterInterval !== undefined) {
- window.clearInterval(this.mouseEnterInterval);
- this.mouseEnterInterval = undefined;
+ if (this.mouseEnterTimeout !== undefined) {
+ window.clearTimeout(this.mouseEnterTimeout);
+ this.mouseEnterTimeout = undefined;
}
if (!this.mouseIn) {
- this.mouseLeaveInterval = window.setTimeout(() => {
+ this.mouseLeaveTimeout = window.setTimeout(() => {
if (this.mounted) {
if (this.props.visible === undefined && !this.mouseIn) {
this.setState({ visible: false });
wrapper.find('#tooltip').simulate('mouseenter');
jest.runOnlyPendingTimers();
wrapper.update();
- expect(wrapper).toMatchSnapshot();
+ expect(wrapper.find('TooltipPortal').exists()).toBe(true);
expect(onShow).toBeCalled();
wrapper.find('#tooltip').simulate('mouseleave');
jest.runOnlyPendingTimers();
wrapper.update();
- expect(wrapper).toMatchSnapshot();
+ expect(wrapper.find('TooltipPortal').exists()).toBe(false);
expect(onHide).toBeCalled();
});
+it('should not open when mouse goes away quickly', () => {
+ const onShow = jest.fn();
+ const onHide = jest.fn();
+ const wrapper = shallow(
+ <TooltipInner onHide={onHide} onShow={onShow} overlay={<span id="overlay" />}>
+ <div id="tooltip" />
+ </TooltipInner>
+ );
+
+ wrapper.find('#tooltip').simulate('mouseenter');
+ wrapper.find('#tooltip').simulate('mouseleave');
+ jest.runOnlyPendingTimers();
+ wrapper.update();
+
+ expect(wrapper.find('TooltipPortal').exists()).toBe(false);
+});
+
it('should not render tooltip without overlay', () => {
const wrapper = shallow(
<Tooltip overlay={undefined}>