diff --git a/packages/material-ui/src/Tooltip/Tooltip.js b/packages/material-ui/src/Tooltip/Tooltip.js index 19d96a2caf20d0..b2c780e0c5fcc4 100644 --- a/packages/material-ui/src/Tooltip/Tooltip.js +++ b/packages/material-ui/src/Tooltip/Tooltip.js @@ -160,11 +160,11 @@ class Tooltip extends React.Component { } } - if (event.type === 'mouseenter') { + if (event.type === 'mouseover') { this.internalState.hover = true; - if (childrenProps.onMouseEnter) { - childrenProps.onMouseEnter(event); + if (childrenProps.onMouseOver) { + childrenProps.onMouseOver(event); } } @@ -190,7 +190,10 @@ class Tooltip extends React.Component { }; handleOpen = event => { - if (!this.isControlled) { + // The mouseover event will trigger for every nested element in the tooltip. + // We can skip rerendering when the tooltip is already open. + // We are using the mouseover event instead of the mouseenter event to fix a hide/show issue. + if (!this.isControlled && !this.state.open) { this.setState({ open: true }); } @@ -317,7 +320,7 @@ class Tooltip extends React.Component { } if (!disableHoverListener) { - childrenProps.onMouseEnter = this.handleEnter; + childrenProps.onMouseOver = this.handleEnter; childrenProps.onMouseLeave = this.handleLeave; } diff --git a/packages/material-ui/src/Tooltip/Tooltip.test.js b/packages/material-ui/src/Tooltip/Tooltip.test.js index 52f53eca684f08..1d04f5257ba8ea 100644 --- a/packages/material-ui/src/Tooltip/Tooltip.test.js +++ b/packages/material-ui/src/Tooltip/Tooltip.test.js @@ -64,7 +64,7 @@ describe('', () => { wrapper.instance().childrenRef = document.createElement('div'); const children = wrapper.childAt(0).childAt(0); assert.strictEqual(wrapper.state().open, false); - children.simulate('mouseEnter', { type: 'mouseenter' }); + children.simulate('mouseOver', { type: 'mouseover' }); assert.strictEqual(wrapper.state().open, true); children.simulate('mouseLeave', { type: 'mouseleave' }); assert.strictEqual(wrapper.state().open, false); @@ -81,7 +81,7 @@ describe('', () => { const children = wrapper.childAt(0).childAt(0); assert.strictEqual(handleRequestOpen.callCount, 0); assert.strictEqual(handleClose.callCount, 0); - children.simulate('mouseEnter', { type: 'mouseenter' }); + children.simulate('mouseOver', { type: 'mouseover' }); assert.strictEqual(handleRequestOpen.callCount, 1); assert.strictEqual(handleClose.callCount, 0); children.simulate('mouseLeave', { type: 'mouseleave' }); @@ -94,7 +94,7 @@ describe('', () => { wrapper.instance().childrenRef = document.createElement('div'); const children = wrapper.childAt(0).childAt(0); assert.strictEqual(wrapper.state().open, false); - children.simulate('mouseEnter', { type: 'mouseenter' }); + children.simulate('mouseOver', { type: 'mouseover' }); children.simulate('focus', { type: 'focus', persist }); clock.tick(0); assert.strictEqual(wrapper.state().open, true); @@ -112,7 +112,6 @@ describe('', () => { children.simulate('touchStart', { type: 'touchstart', persist }); children.simulate('touchEnd', { type: 'touchend', persist }); children.simulate('focus', { type: 'focus', persist }); - children.simulate('mouseover', { type: 'mouseover' }); assert.strictEqual(wrapper.state().open, false); }); @@ -122,7 +121,6 @@ describe('', () => { const children = wrapper.childAt(0).childAt(0); children.simulate('touchStart', { type: 'touchstart', persist }); children.simulate('focus', { type: 'focus', persist }); - children.simulate('mouseover', { type: 'mouseover' }); clock.tick(1e3); assert.strictEqual(wrapper.state().open, true); children.simulate('touchEnd', { type: 'touchend', persist }); @@ -164,26 +162,32 @@ describe('', () => { }); describe('prop: overrides', () => { - ['onTouchStart', 'onTouchEnd', 'onMouseEnter', 'onMouseLeave', 'onFocus', 'onBlur'].forEach( - name => { - it(`should be transparent for the ${name} event`, () => { - const handler = spy(); - const wrapper = shallow( - - - , - ); - wrapper.instance().childrenRef = document.createElement('div'); - const children = wrapper.childAt(0).childAt(0); - const type = name.slice(2).toLowerCase(); - children.simulate(type, { type, persist }); - clock.tick(0); - assert.strictEqual(handler.callCount, 1); - }); - }, - ); + [ + 'onTouchStart', + 'onTouchEnd', + 'onMouseEnter', + 'onMouseOver', + 'onMouseLeave', + 'onFocus', + 'onBlur', + ].forEach(name => { + it(`should be transparent for the ${name} event`, () => { + const handler = spy(); + const wrapper = shallow( + + + , + ); + wrapper.instance().childrenRef = document.createElement('div'); + const children = wrapper.childAt(0).childAt(0); + const type = name.slice(2).toLowerCase(); + children.simulate(type, { type, persist }); + clock.tick(0); + assert.strictEqual(handler.callCount, 1); + }); + }); }); describe('disabled button warning', () => {