From f9651659cfb8650afbf45d988c4806482e24f3e6 Mon Sep 17 00:00:00 2001 From: tourman <8002615@gmail.com> Date: Tue, 28 Nov 2023 15:49:23 +0000 Subject: [PATCH 1/2] fix: typo for mouseEnterTimer (#4442) --- src/addons/Portal/Portal.js | 2 +- test/specs/addons/Portal/Portal-test.js | 33 +++++++++++++++++++++++++ test/utils/wait.js | 3 +++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 test/utils/wait.js diff --git a/src/addons/Portal/Portal.js b/src/addons/Portal/Portal.js index 4f49874189..ef6e61a725 100644 --- a/src/addons/Portal/Portal.js +++ b/src/addons/Portal/Portal.js @@ -215,7 +215,7 @@ function Portal(props) { } const handleTriggerMouseLeave = (e, ...rest) => { - clearTimeout(mouseEnterTimer) + clearTimeout(mouseEnterTimer.current) // Call original event handler _.invoke(trigger, 'props.onMouseLeave', e, ...rest) diff --git a/test/specs/addons/Portal/Portal-test.js b/test/specs/addons/Portal/Portal-test.js index 05cf68a1ae..3cec8a3695 100644 --- a/test/specs/addons/Portal/Portal-test.js +++ b/test/specs/addons/Portal/Portal-test.js @@ -7,6 +7,7 @@ import * as common from 'test/specs/commonTests' import { domEvent, sandbox } from 'test/utils' import Portal from 'src/addons/Portal/Portal' import PortalInner from 'src/addons/Portal/PortalInner' +import wait from 'test/utils/wait' let wrapper @@ -371,6 +372,38 @@ describe('Portal', () => { done() }, 1) }) + + /** + * e--l--d--v + * ^: mouseenter + * ^: BEFORE_DELAY: mouseleave + * ^: expected DELAY + * ^: final validation + */ + it('does not open the portal when leave before delay', async () => { + const DELAY = 20 + const BEFORE_DELAY = 10 + + wrapperMount( + } openOnTriggerMouseEnter mouseEnterDelay={DELAY}> +

+ , + ) + + wrapper.should.not.have.descendants(PortalInner) + wrapper.find('button').simulate('mouseenter') + + await wait(BEFORE_DELAY) + + wrapper.update() + wrapper.should.not.have.descendants(PortalInner) + wrapper.find('button').simulate('mouseleave') + + await wait(DELAY) + + wrapper.update() + wrapper.should.not.have.descendants(PortalInner) + }) }) describe('closeOnTriggerMouseLeave', () => { diff --git a/test/utils/wait.js b/test/utils/wait.js new file mode 100644 index 0000000000..e1f1bb2fff --- /dev/null +++ b/test/utils/wait.js @@ -0,0 +1,3 @@ +export default function wait(timeout) { + return new Promise((resolve) => setTimeout(resolve, timeout)) +} From eb03d995e90827b56bf25bbc8de0ec0e7b660789 Mon Sep 17 00:00:00 2001 From: tourman <8002615@gmail.com> Date: Tue, 28 Nov 2023 21:24:43 +0000 Subject: [PATCH 2/2] fix: typo for mouseLeaveTimer --- src/addons/Portal/Portal.js | 2 +- test/specs/addons/Portal/Portal-test.js | 44 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/addons/Portal/Portal.js b/src/addons/Portal/Portal.js index ef6e61a725..eeac3f9710 100644 --- a/src/addons/Portal/Portal.js +++ b/src/addons/Portal/Portal.js @@ -229,7 +229,7 @@ function Portal(props) { } const handleTriggerMouseEnter = (e, ...rest) => { - clearTimeout(mouseLeaveTimer) + clearTimeout(mouseLeaveTimer.current) // Call original event handler _.invoke(trigger, 'props.onMouseEnter', e, ...rest) diff --git a/test/specs/addons/Portal/Portal-test.js b/test/specs/addons/Portal/Portal-test.js index 3cec8a3695..9d6900b1b2 100644 --- a/test/specs/addons/Portal/Portal-test.js +++ b/test/specs/addons/Portal/Portal-test.js @@ -440,6 +440,50 @@ describe('Portal', () => { done() }, 1) }) + + /** + * e--l--e--d--v + * ^: mouseenter + * ^: mouseleave + * ^: BEFORE_DELAY: reenter + * ^: expected DELAY + * ^: final validation + */ + it('does not close the portal when reenter before delay', async () => { + const DELAY = 20 + const BEFORE_DELAY = 10 + + wrapperMount( + } + openOnTriggerMouseEnter + closeOnTriggerMouseLeave + mouseLeaveDelay={DELAY} + > +

+ , + ) + + wrapper.should.not.have.descendants(PortalInner) + wrapper.find('button').simulate('mouseenter') + + await wait(BEFORE_DELAY) + + wrapper.update() + wrapper.should.have.descendants(PortalInner) + wrapper.find('button').simulate('mouseleave') + + await wait(BEFORE_DELAY) + + wrapper.update() + wrapper.should.have.descendants(PortalInner) + wrapper.find('button').simulate('mouseenter') + + await wait(DELAY) + + wrapper.update() + wrapper.should.have.descendants(PortalInner) + }) }) describe('closeOnPortalMouseLeave', () => {