Skip to content

Commit

Permalink
feat(modal): draggable (#6583)
Browse files Browse the repository at this point in the history
* feat(modal): 弹窗增加拖拽功能

* docs(modal): 增加文档示例

* chore(changelog): 拖拽功能增加 changelog

* chore(modal): getMousePosition 逻辑重构,删除不需要的代码

* chore(modal): 阻止默认行为,防止拖拽文字触发浏览器默认拖拽行为引起的 bug

---------

Co-authored-by: 07akioni <[email protected]>
  • Loading branch information
Zheng-Changfu and 07akioni authored Jan 4, 2025
1 parent d7ca2e4 commit 11ee8fc
Show file tree
Hide file tree
Showing 16 changed files with 465 additions and 158 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

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

### Features

- `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)

### Fixes

- 修复 `n-data-table` 在使用树形数据的时候出现多个展开 icon
Expand Down
1 change: 1 addition & 0 deletions src/_utils/css/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { color2Class } from './color-to-class'
export { formatLength } from './format-length'
export { mergeClass } from './merge-class'
export { rtlInset } from './rtl-inset'
18 changes: 18 additions & 0 deletions src/_utils/css/merge-class.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { isArray, isString } from 'lodash-es'

export function mergeClass(
...args: Array<string | undefined | boolean | (string | undefined)[]>
) {
return args
.reduce<Array<string | undefined>>((p, c) => {
if (isString(c)) {
p.push(c)
}
if (isArray(c)) {
p.push(...c)
}
return p
}, [])
.filter(Boolean)
.join(' ')
}
1 change: 0 additions & 1 deletion src/dialog/src/DialogEnvironment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ export const NDialogEnvironment = defineComponent({
autoFocus={this.autoFocus}
transformOrigin={this.transformOrigin}
internalAppear
internalDialog
>
{{
default: () => (
Expand Down
6 changes: 0 additions & 6 deletions src/dialog/src/DialogProvider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { ExtractPublicPropTypes, Mutable } from '../../_utils'
import { createId } from 'seemly'
import { useClicked, useClickPosition } from 'vooks'
import {
type CSSProperties,
defineComponent,
Expand All @@ -16,7 +15,6 @@ import {
import { omit } from '../../_utils'
import {
dialogApiInjectionKey,
dialogProviderInjectionKey,
dialogReactiveListInjectionKey
} from './context'
import {
Expand Down Expand Up @@ -127,10 +125,6 @@ export const NDialogProvider = defineComponent({
error: typedApi[3]
}
provide(dialogApiInjectionKey, api)
provide(dialogProviderInjectionKey, {
clickedRef: useClicked(64),
clickedPositionRef: useClickPosition()
})
provide(dialogReactiveListInjectionKey, dialogListRef)
return {
...api,
Expand Down
4 changes: 0 additions & 4 deletions src/dialog/src/context.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import type {
DialogApiInjection,
DialogProviderInjection,
DialogReactiveListInjection
} from './DialogProvider'
import { createInjectionKey } from '../../_utils'

export const dialogProviderInjectionKey
= createInjectionKey<DialogProviderInjection>('n-dialog-provider')

export const dialogApiInjectionKey
= createInjectionKey<DialogApiInjection>('n-dialog-api')

Expand Down
137 changes: 137 additions & 0 deletions src/modal/demos/zhCN/draggable.demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<markdown>
# 可拖拽

有人需要,它便有了
</markdown>

<script lang="ts">
import { useModal } from 'naive-ui'
import { defineComponent, ref } from 'vue'
export default defineComponent({
data() {
const modal = useModal()
function showDialogPreset() {
modal.create({
title: 'Dialog 预设拖拽',
draggable: true,
preset: 'dialog',
content: '无意义的内容....'
})
}
function showCardPreset() {
modal.create({
title: 'Card 预设拖拽',
draggable: true,
preset: 'card',
content: '无意义的内容....'
})
}
return {
showModal1: ref(false),
showModal2: ref(false),
showModal3: ref(false),
showModal4: ref(false),
showCardPreset,
showDialogPreset
}
}
})
</script>

<template>
<n-flex>
<n-button @click="showModal1 = !showModal1">
card 预设
</n-button>
<n-button @click="showModal2 = !showModal2">
dialog 预设
</n-button>
<n-button @click="showModal3 = !showModal3">
无预设
</n-button>
<n-button @click="showDialogPreset">
dialog 预设[命令式 Api]
</n-button>
<n-button @click="showCardPreset">
card 预设[命令式 Api]
</n-button>
<n-button @click="showModal4 = !showModal4">
弹窗嵌套
</n-button>
</n-flex>
<n-modal
v-model:show="showModal1"
title="card 预设拖拽"
preset="card"
draggable
:style="{ width: '800px' }"
>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
</n-modal>
<n-modal
v-model:show="showModal2"
title="dialog 预设拖拽"
preset="dialog"
draggable
:style="{ width: '800px' }"
>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
</n-modal>
<n-modal
v-model:show="showModal3"
title="无预设拖拽"
draggable
:style="{ width: '800px' }"
>
<template #default="{ draggableClass }">
<div :style="{ background: '#fff', padding: '20px' }">
<h1 :class="draggableClass" :style="{ margin: 0 }">
自定义标题
</h1>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
<div>无意义的内容...</div>
</div>
</template>
</n-modal>
<n-modal
v-model:show="showModal4"
title="嵌套弹窗拖拽"
preset="card"
:draggable="{ sticky: false }"
:style="{ width: '800px' }"
>
<n-button @click="showDialogPreset">
在开一个弹窗
</n-button>
</n-modal>
</template>
2 changes: 2 additions & 0 deletions src/modal/demos/zhCN/index.demo-entry.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ preset-card.vue
preset-confirm.vue
preset-confirm-slot.vue
transform-origin.vue
draggable.vue
nested-debug.vue
a11y-debug.vue
raw-debug.vue
Expand Down Expand Up @@ -72,6 +73,7 @@ mask-click-debug.vue
| auto-focus | `boolean` | `true` | 是否自动聚焦 Modal 第一个可聚焦的元素 | 2.24.2 |
| block-scroll | `boolean` | `true` | 是否在打开时禁用 body 滚动 | 2.28.3 |
| close-on-esc | `boolean` | `true` | 是否在摁下 Esc 键的时候关闭 Modal | 2.24.2 |
| draggable | `boolean \| {sticky?: boolean}` | `false` | 是否可拖拽,`sticky` 限制拖拽时不可超出视口 | NEXT_VERSION |
| display-directive | `'if' \| 'show'` | `'if'` | 使用何种指令控制模态框主体的条件渲染 | |
| mask-closable | `boolean` | `true` | 点击遮罩时是否发出 `update:show` 事件 | |
| preset | `'dialog' \| 'card'` | `undefined` | 模态框使用何种预设 | |
Expand Down
Loading

0 comments on commit 11ee8fc

Please sign in to comment.