From 3e64509aa6cbe588c2db7455ff8737646623bf0a Mon Sep 17 00:00:00 2001 From: Lo Date: Tue, 15 Oct 2024 10:21:26 +0800 Subject: [PATCH 1/4] feat: mount internal plugins from sortablejs --- docs/.vitepress/sidebar.ts | 8 ++- src/__docs__/multi-drag/demo.vue | 83 ++++++++++++++++++++++++++ src/__docs__/multi-drag/directive.vue | 66 ++++++++++++++++++++ src/__docs__/multi-drag/function.vue | 64 ++++++++++++++++++++ src/__docs__/multi-drag/index.en-US.md | 30 ++++++++++ src/__docs__/multi-drag/index.zh-CN.md | 30 ++++++++++ src/__docs__/swap/demo.vue | 83 ++++++++++++++++++++++++++ src/__docs__/swap/directive.vue | 65 ++++++++++++++++++++ src/__docs__/swap/function.vue | 63 +++++++++++++++++++ src/__docs__/swap/index.en-US.md | 30 ++++++++++ src/__docs__/swap/index.zh-CN.md | 30 ++++++++++ src/useDraggable.ts | 11 +++- 12 files changed, 560 insertions(+), 3 deletions(-) create mode 100644 src/__docs__/multi-drag/demo.vue create mode 100644 src/__docs__/multi-drag/directive.vue create mode 100644 src/__docs__/multi-drag/function.vue create mode 100644 src/__docs__/multi-drag/index.en-US.md create mode 100644 src/__docs__/multi-drag/index.zh-CN.md create mode 100644 src/__docs__/swap/demo.vue create mode 100644 src/__docs__/swap/directive.vue create mode 100644 src/__docs__/swap/function.vue create mode 100644 src/__docs__/swap/index.en-US.md create mode 100644 src/__docs__/swap/index.zh-CN.md diff --git a/docs/.vitepress/sidebar.ts b/docs/.vitepress/sidebar.ts index 89b4d2bb..201995e9 100644 --- a/docs/.vitepress/sidebar.ts +++ b/docs/.vitepress/sidebar.ts @@ -17,7 +17,9 @@ export const sidebar = { { text: 'Mixin Animation', link: '/en/demo/transitions/' }, { text: 'Table Row', link: '/en/demo/table/' }, { text: 'Table Column', link: '/en/demo/table-column/' }, - { text: 'Nesting', link: '/en/demo/nested/' } + { text: 'Nesting', link: '/en/demo/nested/' }, + { text: 'Swap', link: '/en/demo/swap/' }, + { text: 'Multi Drag', link: '/en/demo/multi-drag/' } ] }, { @@ -47,7 +49,9 @@ export const sidebar = { { text: '内置动画合并', link: '/demo/transitions/' }, { text: '表格行拖拽', link: '/demo/table/' }, { text: '表格列拖拽', link: '/demo/table-column/' }, - { text: '嵌套', link: '/demo/nested/' } + { text: '嵌套', link: '/demo/nested/' }, + { text: '交换', link: '/demo/swap/' }, + { text: '多选拖拽', link: '/demo/multi-drag/' } ] }, { diff --git a/src/__docs__/multi-drag/demo.vue b/src/__docs__/multi-drag/demo.vue new file mode 100644 index 00000000..bd9c003a --- /dev/null +++ b/src/__docs__/multi-drag/demo.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/src/__docs__/multi-drag/directive.vue b/src/__docs__/multi-drag/directive.vue new file mode 100644 index 00000000..24c656f9 --- /dev/null +++ b/src/__docs__/multi-drag/directive.vue @@ -0,0 +1,66 @@ + + + + + diff --git a/src/__docs__/multi-drag/function.vue b/src/__docs__/multi-drag/function.vue new file mode 100644 index 00000000..15043e07 --- /dev/null +++ b/src/__docs__/multi-drag/function.vue @@ -0,0 +1,64 @@ + + + + + diff --git a/src/__docs__/multi-drag/index.en-US.md b/src/__docs__/multi-drag/index.en-US.md new file mode 100644 index 00000000..f57b2f79 --- /dev/null +++ b/src/__docs__/multi-drag/index.en-US.md @@ -0,0 +1,30 @@ +--- +map: + path: /demo/multi-drag +--- + +# Basic Usage + +Allow selecting multiple items within a sortable at once, and drag them as one item. Once placed, the items will unfold into their original order, but all beside each other at the new position. + +## Component Usage + + + + + +## Function Usage + + + + +## Directive Usage + + + diff --git a/src/__docs__/multi-drag/index.zh-CN.md b/src/__docs__/multi-drag/index.zh-CN.md new file mode 100644 index 00000000..43073b39 --- /dev/null +++ b/src/__docs__/multi-drag/index.zh-CN.md @@ -0,0 +1,30 @@ +--- +map: + path: /demo/multi-drag +--- + +# 基础使用 + +允许一次选择可排序项中的多个选项,并将它们作为一个选项拖动。一旦放置,这些选项将按原始顺序展开,但在新的位置上会并排放置。 + +## 组件使用 + + + + + +## 函数使用 + + + + +## 指令使用 + + + diff --git a/src/__docs__/swap/demo.vue b/src/__docs__/swap/demo.vue new file mode 100644 index 00000000..4d272a5b --- /dev/null +++ b/src/__docs__/swap/demo.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/src/__docs__/swap/directive.vue b/src/__docs__/swap/directive.vue new file mode 100644 index 00000000..93842a35 --- /dev/null +++ b/src/__docs__/swap/directive.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/src/__docs__/swap/function.vue b/src/__docs__/swap/function.vue new file mode 100644 index 00000000..39f9fbdd --- /dev/null +++ b/src/__docs__/swap/function.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/src/__docs__/swap/index.en-US.md b/src/__docs__/swap/index.en-US.md new file mode 100644 index 00000000..66f25804 --- /dev/null +++ b/src/__docs__/swap/index.en-US.md @@ -0,0 +1,30 @@ +--- +map: + path: /demo/swap +--- + +# Basic Usage + +Change the behaviour of Sortable to allow for items to be swapped with eachother rather than sorted. + +## Component Usage + + + + + +## Function Usage + + + + +## Directive Usage + + + diff --git a/src/__docs__/swap/index.zh-CN.md b/src/__docs__/swap/index.zh-CN.md new file mode 100644 index 00000000..15dbba59 --- /dev/null +++ b/src/__docs__/swap/index.zh-CN.md @@ -0,0 +1,30 @@ +--- +map: + path: /demo/swap +--- + +# 基础使用 + +更改 Sortable 的行为以允许相互交换而不是排序。 + +## 组件使用 + + + + + +## 函数使用 + + + + +## 指令使用 + + + diff --git a/src/useDraggable.ts b/src/useDraggable.ts index 8e12db8b..c0b97fb6 100644 --- a/src/useDraggable.ts +++ b/src/useDraggable.ts @@ -1,4 +1,9 @@ -import Sortable, { type Options, type SortableEvent } from 'sortablejs' +import Sortable, { + type Options, + type SortableEvent, + Swap, + MultiDrag +} from 'sortablejs' import { getCurrentInstance, isRef, @@ -29,6 +34,10 @@ import { removeNode } from './utils' +// mount internal plugins +Sortable.mount(new Swap()) +Sortable.mount(new MultiDrag()) + function defaultClone(element: T): T { if (element === undefined || element === null) return element return JSON.parse(JSON.stringify(element)) From 9b89988df7a860a8695a742f754c4581246c0ccc Mon Sep 17 00:00:00 2001 From: Lo Date: Fri, 18 Oct 2024 17:24:29 +0800 Subject: [PATCH 2/4] feat: resolve data when swap or multiDrag enable --- src/shims.d.ts | 4 ++++ src/useDraggable.ts | 52 +++++++++++++++++++++++++++++++++------------ src/utils/index.ts | 16 ++++++++++++++ 3 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 src/shims.d.ts diff --git a/src/shims.d.ts b/src/shims.d.ts new file mode 100644 index 00000000..ff57a56d --- /dev/null +++ b/src/shims.d.ts @@ -0,0 +1,4 @@ +declare module 'sortablejs/modular/sortable.complete.esm' { + import Sortable from 'sortablejs' + export default Sortable +} diff --git a/src/useDraggable.ts b/src/useDraggable.ts index f16bbd5a..2305f059 100644 --- a/src/useDraggable.ts +++ b/src/useDraggable.ts @@ -1,9 +1,5 @@ -import Sortable, { - type Options, - type SortableEvent, - Swap, - MultiDrag -} from 'sortablejs' +import { type Options, type SortableEvent } from 'sortablejs' +import Sortable from 'sortablejs/modular/sortable.complete.esm' import { getCurrentInstance, isRef, @@ -31,13 +27,10 @@ import { mergeOptionsEvents, moveArrayElement, removeElement, - removeNode + removeNode, + swapArrayElement } from './utils' -// mount internal plugins -Sortable.mount(new Swap()) -Sortable.mount(new MultiDrag()) - function defaultClone(element: T): T { if (element === undefined || element === null) return element return JSON.parse(JSON.stringify(element)) @@ -154,7 +147,9 @@ export function useDraggable(...args: any[]): UseDraggableReturn { const { immediate = true, clone = defaultClone, - customUpdate + customUpdate, + swap, + multiDrag } = unref(options) ?? {} /** @@ -214,7 +209,37 @@ export function useDraggable(...args: any[]): UseDraggableReturn { customUpdate(evt) return } - const { from, item, oldIndex, newIndex } = evt + + const { from, item, oldIndex, newIndex, oldIndicies, newIndicies } = evt + + if (multiDrag) { + const oldIndexList = oldIndicies.map(i => i.index) + const newIndexList = newIndicies.map(i => i.index) + + const newList = [...unref(list)] + + const selectedItems = oldIndexList.map(index => newList[index]) + + oldIndexList + .sort((a, b) => b - a) + .forEach(oIndex => { + newList.splice(oIndex, 1) + }) + + newIndexList.forEach((nIndex, i) => { + newList.splice(nIndex, 0, selectedItems[i]) + }) + + list.value = newList + return + } + + if (swap) { + const newList = [...unref(list)] + list.value = swapArrayElement(newList, oldIndex!, newIndex!) + return + } + removeNode(item) insertNodeAt(from, item, oldIndex!) if (isRef(list)) { @@ -229,6 +254,7 @@ export function useDraggable(...args: any[]): UseDraggableReturn { const { newIndex, oldIndex, from, to } = e let error: Error | null = null const isSameIndex = newIndex === oldIndex && from === to + try { //region #202 if (isSameIndex) { diff --git a/src/utils/index.ts b/src/utils/index.ts index cf9af01a..f999fa91 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -14,6 +14,22 @@ export function moveArrayElement(array: T[], from: number, to: number): T[] { return array } +/** + * Swaps two elements in an array. + * @param {T[]} array + * @param {number} index1 + * @param {number} index2 + * @returns {T[]} + */ +export function swapArrayElement( + array: T[], + index1: number, + index2: number +): T[] { + ;[array[index1], array[index2]] = [array[index2], array[index1]] + return array +} + /** * Convert a hyphen-delimited string to camelCase. * @param {string} str From 9cd50588661f39b23f2b5a996ac7e111891efec4 Mon Sep 17 00:00:00 2001 From: Lo Date: Fri, 18 Oct 2024 17:38:25 +0800 Subject: [PATCH 3/4] chore: remove extra blank --- src/useDraggable.ts | 1 - src/utils/index.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/useDraggable.ts b/src/useDraggable.ts index 2305f059..b52b1dc8 100644 --- a/src/useDraggable.ts +++ b/src/useDraggable.ts @@ -254,7 +254,6 @@ export function useDraggable(...args: any[]): UseDraggableReturn { const { newIndex, oldIndex, from, to } = e let error: Error | null = null const isSameIndex = newIndex === oldIndex && from === to - try { //region #202 if (isSameIndex) { diff --git a/src/utils/index.ts b/src/utils/index.ts index f999fa91..1a560f89 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -15,7 +15,7 @@ export function moveArrayElement(array: T[], from: number, to: number): T[] { } /** - * Swaps two elements in an array. + * Swaps two elements in an array. * @param {T[]} array * @param {number} index1 * @param {number} index2 From 9bd179c7d23778568022e99100ae58e84a6d2fe8 Mon Sep 17 00:00:00 2001 From: Lo Date: Fri, 18 Oct 2024 17:40:34 +0800 Subject: [PATCH 4/4] chore: use cjs sortable --- src/shims.d.ts | 2 +- src/useDraggable.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shims.d.ts b/src/shims.d.ts index ff57a56d..84541def 100644 --- a/src/shims.d.ts +++ b/src/shims.d.ts @@ -1,4 +1,4 @@ -declare module 'sortablejs/modular/sortable.complete.esm' { +declare module 'sortablejs/Sortable' { import Sortable from 'sortablejs' export default Sortable } diff --git a/src/useDraggable.ts b/src/useDraggable.ts index b52b1dc8..dc242662 100644 --- a/src/useDraggable.ts +++ b/src/useDraggable.ts @@ -1,5 +1,5 @@ import { type Options, type SortableEvent } from 'sortablejs' -import Sortable from 'sortablejs/modular/sortable.complete.esm' +import Sortable from 'sortablejs/Sortable' import { getCurrentInstance, isRef,