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', () => {