Skip to content

Commit b4dc00b

Browse files
committed
Prevent close if user mouseDown trigger on the dialog
fix ant-design/ant-design#15891
1 parent a701a7c commit b4dc00b

File tree

4 files changed

+34
-4
lines changed

4 files changed

+34
-4
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rc-dialog",
3-
"version": "7.3.0",
3+
"version": "7.3.1",
44
"description": "dialog ui component for react",
55
"keywords": [
66
"react",

src/Dialog.tsx

+20-2
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ export default class Dialog extends React.Component<IDialogPropTypes, any> {
6868
private sentinelEnd: HTMLElement;
6969
private bodyIsOverflowing: boolean;
7070
private scrollbarWidth: number;
71+
private dialogMouseDown: boolean;
72+
private timeoutId: number;
7173

7274
componentWillMount() {
7375
this.inTransition = false;
@@ -114,6 +116,7 @@ export default class Dialog extends React.Component<IDialogPropTypes, any> {
114116
if (this.props.visible || this.inTransition) {
115117
this.removeScrollingEffect();
116118
}
119+
clearTimeout(this.timeoutId);
117120
}
118121

119122
tryFocus() {
@@ -136,12 +139,25 @@ export default class Dialog extends React.Component<IDialogPropTypes, any> {
136139
afterClose();
137140
}
138141
}
142+
143+
onDialogMouseDown = () => {
144+
this.dialogMouseDown = true;
145+
}
146+
147+
onMaskMouseUp: React.MouseEventHandler<HTMLDivElement> = () => {
148+
if (this.dialogMouseDown) {
149+
this.timeoutId = setTimeout(() => {
150+
this.dialogMouseDown = false;
151+
}, 0);
152+
}
153+
}
154+
139155
onMaskClick = (e: React.MouseEvent<HTMLDivElement>) => {
140156
// android trigger click on open (fastclick??)
141157
if (Date.now() - this.openTime < 300) {
142158
return;
143159
}
144-
if (e.target === e.currentTarget) {
160+
if (e.target === e.currentTarget && !this.dialogMouseDown) {
145161
this.close(e);
146162
}
147163
}
@@ -222,6 +238,7 @@ export default class Dialog extends React.Component<IDialogPropTypes, any> {
222238
style={style}
223239
className={`${prefixCls} ${props.className || ''}`}
224240
visible={props.visible}
241+
onMouseDown={this.onDialogMouseDown}
225242
>
226243
<div tabIndex={0} ref={this.saveRef('sentinelStart')} style={sentinelStyle}>
227244
sentinelStart
@@ -402,7 +419,8 @@ export default class Dialog extends React.Component<IDialogPropTypes, any> {
402419
onKeyDown={this.onKeyDown}
403420
className={`${prefixCls}-wrap ${props.wrapClassName || ''}`}
404421
ref={this.saveRef('wrap')}
405-
onClick={maskClosable ? this.onMaskClick : undefined}
422+
onClick={maskClosable ? this.onMaskClick : null}
423+
onMouseUp={maskClosable ? this.onMaskMouseUp : null}
406424
role="dialog"
407425
aria-labelledby={props.title ? this.titleId : null}
408426
style={style}

src/LazyRenderBox.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export interface ILazyRenderBoxPropTypes {
66
hiddenClassName?: string;
77
role?: string;
88
style?: {};
9+
onMouseDown?: React.MouseEventHandler<HTMLDivElement>;
910
}
1011

1112
export default class LazyRenderBox extends React.Component<ILazyRenderBoxPropTypes, any> {

tests/index.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -277,5 +277,16 @@ describe('dialog', () => {
277277
</Dialog>
278278
),container)
279279
expect($('.rc-dialog-body > div').text()).to.be('forceRender element')
280-
})
280+
});
281+
282+
it('should not close if mouse down in dialog', () => {
283+
dialog.setState({
284+
visible: true,
285+
});
286+
const dialogBody = $('.rc-dialog-body')[0];
287+
Simulate.mouseDown(dialogBody);
288+
const wrapper = $('.rc-dialog-wrap')[0];
289+
Simulate.mouseUp(wrapper);
290+
expect(dialog.state.visible).to.be(true);
291+
});
281292
});

0 commit comments

Comments
 (0)