Skip to content

Commit 518dfa2

Browse files
committed
feat(modal): modal support draggable
1 parent 640d554 commit 518dfa2

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

src/modal/demos/draggable.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React, { useState } from 'react';
2+
import { Button, Space, Tooltip } from 'antd';
3+
import { Modal, TinyTag } from 'dt-react-component';
4+
5+
export default function Basic() {
6+
const [visible, setVisible] = useState(false);
7+
8+
return (
9+
<>
10+
<Modal
11+
title={
12+
<Space>
13+
Draggable Modal
14+
<Tooltip title="通过阻止 mousedown 事件冒泡,可以让 title 中的元素不触发拖拽">
15+
<TinyTag
16+
onMouseDown={(e) => e.stopPropagation()}
17+
value="Cancel"
18+
style={{ color: '#1D78FF' }}
19+
/>
20+
</Tooltip>
21+
</Space>
22+
}
23+
draggable={{
24+
bounds: 'body',
25+
}}
26+
visible={visible}
27+
onCancel={() => setVisible(false)}
28+
onOk={() => setVisible(false)}
29+
>
30+
<ul>
31+
{Array.from({ length: 300 }).map((_, i) => (
32+
<li key={i} style={{ height: 30 }}>
33+
{i}
34+
</li>
35+
))}
36+
</ul>
37+
</Modal>
38+
<Button type="primary" onClick={() => setVisible(true)}>
39+
Draggable Modal
40+
</Button>
41+
</>
42+
);
43+
}

src/modal/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ toc: content
1818
<code src="./demos/size.tsx" title="尺寸"></code>
1919
<code src="./demos/banner.tsx" title="支持 banner"></code>
2020
<code src="./demos/bannerProps.tsx" title="支持传 banner 的 Props 属性"></code>
21+
<code src="./demos/draggable.tsx" title="draggable"></code>
2122

2223
## API
2324

src/modal/index.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
$modal-max-height: 80vh;
22

33
.dtc-modal {
4+
&__draggable {
5+
top: 0;
6+
left: 0;
7+
margin: 0;
8+
}
49
.ant-modal-content {
510
max-height: $modal-max-height;
611
display: flex;

src/modal/modal.tsx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,17 @@ import { Alert, type AlertProps, Modal as AntdModal, type ModalProps } from 'ant
33
import classNames from 'classnames';
44
import { omit } from 'lodash-es';
55

6+
import type { IFloatProps } from '../float';
7+
import Float from '../float';
8+
import useMergeOption from '../float/useMergeOption';
69
import './index.scss';
710

811
export interface IModalProps extends ModalProps {
912
size?: 'small' | 'default' | 'middle' | 'large';
1013
banner?: AlertProps['message'] | Omit<AlertProps, 'banner'>;
14+
draggable?: IFloatProps['draggable'];
15+
position?: IFloatProps['position'];
16+
onPositionChange?: IFloatProps['onChange'];
1117
}
1218

1319
const getWidthFromSize = (size: IModalProps['size']) => {
@@ -29,15 +35,41 @@ export default function Modal({
2935
children,
3036
width,
3137
className,
38+
draggable = false,
39+
position,
40+
onPositionChange,
41+
modalRender,
3242
...rest
3343
}: IModalProps) {
3444
const finalWidth = width ?? getWidthFromSize(size);
3545

46+
const mergedDraggable = useMergeOption(
47+
typeof draggable === 'boolean' ? draggable : { handle: '.ant-modal-header', ...draggable }
48+
);
49+
3650
return (
3751
<AntdModal
38-
className={classNames('dtc-modal', className)}
52+
className={classNames(
53+
'dtc-modal',
54+
!mergedDraggable.disabled && 'dtc-modal__draggable',
55+
className
56+
)}
3957
bodyStyle={{ padding: 0, ...bodyStyle }}
4058
width={finalWidth}
59+
modalRender={(modal) =>
60+
mergedDraggable.disabled ? (
61+
modalRender?.(modal) || modal
62+
) : (
63+
<Float
64+
draggable={mergedDraggable.options}
65+
position={position}
66+
style={{ width: finalWidth }}
67+
onChange={onPositionChange}
68+
>
69+
{modalRender?.(modal) || modal}
70+
</Float>
71+
)
72+
}
4173
{...rest}
4274
>
4375
{banner && (

0 commit comments

Comments
 (0)