Skip to content

Commit 11ee8fc

Browse files
feat(modal): draggable (#6583)
* feat(modal): 弹窗增加拖拽功能 * docs(modal): 增加文档示例 * chore(changelog): 拖拽功能增加 changelog * chore(modal): getMousePosition 逻辑重构,删除不需要的代码 * chore(modal): 阻止默认行为,防止拖拽文字触发浏览器默认拖拽行为引起的 bug --------- Co-authored-by: 07akioni <[email protected]>
1 parent d7ca2e4 commit 11ee8fc

16 files changed

+465
-158
lines changed

CHANGELOG.zh-CN.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
- (需要 Vue 3.3+)为所有的组件增加插槽的类型标注
88

9+
### Features
10+
11+
- `n-modal` 新增 `draggable` 属性,关闭 [#6525](https://github.com/tusen-ai/naive-ui/issues/6525)[#5792](https://github.com/tusen-ai/naive-ui/issues/5792)[#5711](https://github.com/tusen-ai/naive-ui/issues/5711)[#5501](https://github.com/tusen-ai/naive-ui/issues/5501)[#2152](https://github.com/tusen-ai/naive-ui/issues/2152)
12+
913
### Fixes
1014

1115
- 修复 `n-data-table` 在使用树形数据的时候出现多个展开 icon

src/_utils/css/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export { color2Class } from './color-to-class'
22
export { formatLength } from './format-length'
3+
export { mergeClass } from './merge-class'
34
export { rtlInset } from './rtl-inset'

src/_utils/css/merge-class.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { isArray, isString } from 'lodash-es'
2+
3+
export function mergeClass(
4+
...args: Array<string | undefined | boolean | (string | undefined)[]>
5+
) {
6+
return args
7+
.reduce<Array<string | undefined>>((p, c) => {
8+
if (isString(c)) {
9+
p.push(c)
10+
}
11+
if (isArray(c)) {
12+
p.push(...c)
13+
}
14+
return p
15+
}, [])
16+
.filter(Boolean)
17+
.join(' ')
18+
}

src/dialog/src/DialogEnvironment.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ export const NDialogEnvironment = defineComponent({
157157
autoFocus={this.autoFocus}
158158
transformOrigin={this.transformOrigin}
159159
internalAppear
160-
internalDialog
161160
>
162161
{{
163162
default: () => (

src/dialog/src/DialogProvider.ts

-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { ExtractPublicPropTypes, Mutable } from '../../_utils'
22
import { createId } from 'seemly'
3-
import { useClicked, useClickPosition } from 'vooks'
43
import {
54
type CSSProperties,
65
defineComponent,
@@ -16,7 +15,6 @@ import {
1615
import { omit } from '../../_utils'
1716
import {
1817
dialogApiInjectionKey,
19-
dialogProviderInjectionKey,
2018
dialogReactiveListInjectionKey
2119
} from './context'
2220
import {
@@ -127,10 +125,6 @@ export const NDialogProvider = defineComponent({
127125
error: typedApi[3]
128126
}
129127
provide(dialogApiInjectionKey, api)
130-
provide(dialogProviderInjectionKey, {
131-
clickedRef: useClicked(64),
132-
clickedPositionRef: useClickPosition()
133-
})
134128
provide(dialogReactiveListInjectionKey, dialogListRef)
135129
return {
136130
...api,

src/dialog/src/context.ts

-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
import type {
22
DialogApiInjection,
3-
DialogProviderInjection,
43
DialogReactiveListInjection
54
} from './DialogProvider'
65
import { createInjectionKey } from '../../_utils'
76

8-
export const dialogProviderInjectionKey
9-
= createInjectionKey<DialogProviderInjection>('n-dialog-provider')
10-
117
export const dialogApiInjectionKey
128
= createInjectionKey<DialogApiInjection>('n-dialog-api')
139

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<markdown>
2+
# 可拖拽
3+
4+
有人需要,它便有了
5+
</markdown>
6+
7+
<script lang="ts">
8+
import { useModal } from 'naive-ui'
9+
import { defineComponent, ref } from 'vue'
10+
11+
export default defineComponent({
12+
data() {
13+
const modal = useModal()
14+
15+
function showDialogPreset() {
16+
modal.create({
17+
title: 'Dialog 预设拖拽',
18+
draggable: true,
19+
preset: 'dialog',
20+
content: '无意义的内容....'
21+
})
22+
}
23+
24+
function showCardPreset() {
25+
modal.create({
26+
title: 'Card 预设拖拽',
27+
draggable: true,
28+
preset: 'card',
29+
content: '无意义的内容....'
30+
})
31+
}
32+
33+
return {
34+
showModal1: ref(false),
35+
showModal2: ref(false),
36+
showModal3: ref(false),
37+
showModal4: ref(false),
38+
showCardPreset,
39+
showDialogPreset
40+
}
41+
}
42+
})
43+
</script>
44+
45+
<template>
46+
<n-flex>
47+
<n-button @click="showModal1 = !showModal1">
48+
card 预设
49+
</n-button>
50+
<n-button @click="showModal2 = !showModal2">
51+
dialog 预设
52+
</n-button>
53+
<n-button @click="showModal3 = !showModal3">
54+
无预设
55+
</n-button>
56+
<n-button @click="showDialogPreset">
57+
dialog 预设[命令式 Api]
58+
</n-button>
59+
<n-button @click="showCardPreset">
60+
card 预设[命令式 Api]
61+
</n-button>
62+
<n-button @click="showModal4 = !showModal4">
63+
弹窗嵌套
64+
</n-button>
65+
</n-flex>
66+
<n-modal
67+
v-model:show="showModal1"
68+
title="card 预设拖拽"
69+
preset="card"
70+
draggable
71+
:style="{ width: '800px' }"
72+
>
73+
<div>无意义的内容...</div>
74+
<div>无意义的内容...</div>
75+
<div>无意义的内容...</div>
76+
<div>无意义的内容...</div>
77+
<div>无意义的内容...</div>
78+
<div>无意义的内容...</div>
79+
<div>无意义的内容...</div>
80+
<div>无意义的内容...</div>
81+
<div>无意义的内容...</div>
82+
<div>无意义的内容...</div>
83+
</n-modal>
84+
<n-modal
85+
v-model:show="showModal2"
86+
title="dialog 预设拖拽"
87+
preset="dialog"
88+
draggable
89+
:style="{ width: '800px' }"
90+
>
91+
<div>无意义的内容...</div>
92+
<div>无意义的内容...</div>
93+
<div>无意义的内容...</div>
94+
<div>无意义的内容...</div>
95+
<div>无意义的内容...</div>
96+
<div>无意义的内容...</div>
97+
<div>无意义的内容...</div>
98+
<div>无意义的内容...</div>
99+
<div>无意义的内容...</div>
100+
<div>无意义的内容...</div>
101+
</n-modal>
102+
<n-modal
103+
v-model:show="showModal3"
104+
title="无预设拖拽"
105+
draggable
106+
:style="{ width: '800px' }"
107+
>
108+
<template #default="{ draggableClass }">
109+
<div :style="{ background: '#fff', padding: '20px' }">
110+
<h1 :class="draggableClass" :style="{ margin: 0 }">
111+
自定义标题
112+
</h1>
113+
<div>无意义的内容...</div>
114+
<div>无意义的内容...</div>
115+
<div>无意义的内容...</div>
116+
<div>无意义的内容...</div>
117+
<div>无意义的内容...</div>
118+
<div>无意义的内容...</div>
119+
<div>无意义的内容...</div>
120+
<div>无意义的内容...</div>
121+
<div>无意义的内容...</div>
122+
<div>无意义的内容...</div>
123+
</div>
124+
</template>
125+
</n-modal>
126+
<n-modal
127+
v-model:show="showModal4"
128+
title="嵌套弹窗拖拽"
129+
preset="card"
130+
:draggable="{ sticky: false }"
131+
:style="{ width: '800px' }"
132+
>
133+
<n-button @click="showDialogPreset">
134+
在开一个弹窗
135+
</n-button>
136+
</n-modal>
137+
</template>

src/modal/demos/zhCN/index.demo-entry.md

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ preset-card.vue
2727
preset-confirm.vue
2828
preset-confirm-slot.vue
2929
transform-origin.vue
30+
draggable.vue
3031
nested-debug.vue
3132
a11y-debug.vue
3233
raw-debug.vue
@@ -72,6 +73,7 @@ mask-click-debug.vue
7273
| auto-focus | `boolean` | `true` | 是否自动聚焦 Modal 第一个可聚焦的元素 | 2.24.2 |
7374
| block-scroll | `boolean` | `true` | 是否在打开时禁用 body 滚动 | 2.28.3 |
7475
| close-on-esc | `boolean` | `true` | 是否在摁下 Esc 键的时候关闭 Modal | 2.24.2 |
76+
| draggable | `boolean \| {sticky?: boolean}` | `false` | 是否可拖拽,`sticky` 限制拖拽时不可超出视口 | NEXT_VERSION |
7577
| display-directive | `'if' \| 'show'` | `'if'` | 使用何种指令控制模态框主体的条件渲染 | |
7678
| mask-closable | `boolean` | `true` | 点击遮罩时是否发出 `update:show` 事件 | |
7779
| preset | `'dialog' \| 'card'` | `undefined` | 模态框使用何种预设 | |

0 commit comments

Comments
 (0)