Skip to content

Commit 2fb5e2f

Browse files
extended SortableJS events with data attribute
1 parent 76c0610 commit 2fb5e2f

File tree

2 files changed

+64
-9
lines changed

2 files changed

+64
-9
lines changed

src/types/index.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
import type { Ref } from 'vue'
2-
export { type Options, type SortableEvent } from 'sortablejs'
2+
import type { SortableEvent, MoveEvent } from 'sortablejs'
3+
export { type Options, type SortableEvent, type MoveEvent } from 'sortablejs'
4+
5+
export interface SortableDataEvent extends SortableEvent {
6+
itemData?: any
7+
}
8+
9+
export interface MoveDataEvent extends MoveEvent {
10+
draggedData?: any
11+
}
312

413
export type RefOrValue<T> = T | Ref<T>
514
export type RefOrElement<T = HTMLElement> =

src/useDraggable.ts

+54-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@ import {
99
watch,
1010
type Ref
1111
} from 'vue-demi'
12-
import type { Fn, RefOrElement, RefOrValue } from './types'
12+
import {
13+
Fn,
14+
MoveDataEvent,
15+
RefOrElement,
16+
RefOrValue,
17+
SortableDataEvent
18+
} from './types'
1319

1420
import { error } from './utils/log'
1521

@@ -51,10 +57,24 @@ function tryOnMounted(fn: Fn) {
5157
else nextTick(fn)
5258
}
5359

54-
const CLONE_ELEMENT_KEY = Symbol('cloneElement')
60+
const DATA_ELEMENT_KEY = Symbol('dataElement')
61+
62+
const sortableEventKeys = [
63+
"onStart",
64+
"onEnd",
65+
"onAdd",
66+
"onClone",
67+
"onChoose",
68+
"onUnchoose",
69+
"onUpdate",
70+
"onSort",
71+
"onRemove",
72+
"onFilter",
73+
"onChange"
74+
] as const;
5575

5676
interface DraggableEvent extends SortableEvent {
57-
item: HTMLElement & { [CLONE_ELEMENT_KEY]: any }
77+
item: HTMLElement & { [DATA_ELEMENT_KEY]: any }
5878
}
5979
type SortableMethod = 'closest' | 'save' | 'toArray' | 'destroy' | 'option'
6080

@@ -69,7 +89,15 @@ export interface UseDraggableReturn extends Pick<Sortable, SortableMethod> {
6989
resume: () => void
7090
}
7191

72-
export interface UseDraggableOptions<T> extends Options {
92+
type MoveDataFunction = (evt: MoveDataEvent, originalEvent: Event) => boolean | -1 | 1 | void
93+
94+
type ExtendedOptions = Options & {
95+
[key in typeof sortableEventKeys[number]]?: (evt: SortableDataEvent) => void
96+
} & {
97+
onMove?: MoveDataFunction;
98+
}
99+
100+
export interface UseDraggableOptions<T> extends ExtendedOptions {
73101
clone?: (element: T) => T
74102
immediate?: boolean
75103
customUpdate?: (event: SortableEvent) => void
@@ -130,16 +158,16 @@ export function useDraggable<T>(...args: any[]): UseDraggableReturn {
130158
* Element dragging started
131159
* @param {DraggableEvent} evt - DraggableEvent
132160
*/
133-
function onStart(evt: DraggableEvent) {
134-
evt.item[CLONE_ELEMENT_KEY] = clone(unref(unref(list)?.[evt.oldIndex!]))
161+
function onChoose(evt: DraggableEvent) {
162+
evt.item[DATA_ELEMENT_KEY] = clone(unref(unref(list)?.[evt.oldIndex!]))
135163
}
136164

137165
/**
138166
* Element is dropped into the list from another list
139167
* @param {DraggableEvent} evt
140168
*/
141169
function onAdd(evt: DraggableEvent) {
142-
const element = evt.item[CLONE_ELEMENT_KEY]
170+
const element = evt.item[DATA_ELEMENT_KEY]
143171
if (isUndefined(element)) return
144172
removeNode(evt.item)
145173
if (isRef<any[]>(list)) {
@@ -193,8 +221,8 @@ export function useDraggable<T>(...args: any[]): UseDraggableReturn {
193221
* preset options
194222
*/
195223
const presetOptions: UseDraggableOptions<T> = {
224+
onChoose,
196225
onUpdate,
197-
onStart,
198226
onAdd,
199227
onRemove
200228
}
@@ -216,12 +244,30 @@ export function useDraggable<T>(...args: any[]): UseDraggableReturn {
216244
function mergeOptions() {
217245
// eslint-disable-next-line
218246
const { immediate, clone, ...restOptions } = unref(options) ?? {}
247+
sortableEventKeys.forEach(key => {
248+
if (restOptions[key]) {
249+
restOptions[key] = extendSortableEvent(restOptions[key])
250+
}
251+
})
252+
if (restOptions.onMove) {
253+
restOptions.onMove = extendMoveEvent(restOptions.onMove)
254+
}
219255
return mergeOptionsEvents(
220256
list === null ? {} : presetOptions,
221257
restOptions
222258
) as Options
223259
}
224260

261+
function extendSortableEvent(fn: (evt: SortableDataEvent) => void) {
262+
return (evt: DraggableEvent) =>
263+
fn({ ...evt, itemData: evt.item[DATA_ELEMENT_KEY] })
264+
}
265+
266+
function extendMoveEvent(fn: MoveDataFunction) {
267+
return (moveEvent: any, originalEvent: Event) =>
268+
fn({ ...moveEvent, draggedData: moveEvent.dragged[DATA_ELEMENT_KEY] }, originalEvent)
269+
}
270+
225271
const start = (target?: HTMLElement) => {
226272
target = getTarget(target)
227273
if (instance) methods.destroy()

0 commit comments

Comments
 (0)