@marsio/vue-draggable 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/README.md +143 -3
  2. package/build/cjs/Draggable.js +328 -70
  3. package/build/cjs/DraggableCore.js +884 -74
  4. package/build/cjs/utils/domFns.js +60 -18
  5. package/build/cjs/utils/noop.js +9 -0
  6. package/build/cjs/utils/positionFns.js +78 -40
  7. package/build/cjs/utils/shims.js +2 -2
  8. package/build/web/vue-draggable.min.179e4c366756eb300fbf.hot-update.js +30 -0
  9. package/build/web/vue-draggable.min.19bbf2e057882622f2f8.hot-update.js +30 -0
  10. package/build/web/vue-draggable.min.6cc5294fa16ef72f1dc6.hot-update.js +30 -0
  11. package/build/web/vue-draggable.min.870ce0c3b8d1e5af7abb.hot-update.js +30 -0
  12. package/build/web/vue-draggable.min.8a0eb1cdda0c757918ec.hot-update.js +30 -0
  13. package/build/web/vue-draggable.min.8c4367bbfb0323ed907d.hot-update.js +30 -0
  14. package/build/web/vue-draggable.min.900bc4aa354497b18d12.hot-update.js +30 -0
  15. package/build/web/vue-draggable.min.a529009727f3ce56b642.hot-update.js +30 -0
  16. package/build/web/vue-draggable.min.js +241 -282
  17. package/build/web/vue-draggable_min.179e4c366756eb300fbf.hot-update.json +1 -0
  18. package/build/web/vue-draggable_min.19bbf2e057882622f2f8.hot-update.json +1 -0
  19. package/build/web/vue-draggable_min.6cc5294fa16ef72f1dc6.hot-update.json +1 -0
  20. package/build/web/vue-draggable_min.870ce0c3b8d1e5af7abb.hot-update.json +1 -0
  21. package/build/web/vue-draggable_min.8a0eb1cdda0c757918ec.hot-update.json +1 -0
  22. package/build/web/vue-draggable_min.8c4367bbfb0323ed907d.hot-update.json +1 -0
  23. package/build/web/vue-draggable_min.900bc4aa354497b18d12.hot-update.json +1 -0
  24. package/build/web/vue-draggable_min.a529009727f3ce56b642.hot-update.json +1 -0
  25. package/package.json +4 -3
  26. package/typings/index.d.ts +80 -47
@@ -11,15 +11,14 @@ Object.defineProperty(exports, "DraggableCore", {
11
11
  });
12
12
  exports.draggableProps = exports.default = void 0;
13
13
  var _vue = require("vue");
14
- var _get = _interopRequireDefault(require("lodash/get"));
15
14
  var _clsx = _interopRequireDefault(require("clsx"));
16
15
  var _domFns = require("./utils/domFns");
17
16
  var _positionFns = require("./utils/positionFns");
18
17
  var _shims = require("./utils/shims");
19
18
  var _DraggableCore = _interopRequireWildcard(require("./DraggableCore"));
20
19
  var _log = _interopRequireDefault(require("./utils/log"));
21
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
22
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
20
+ var _noop = _interopRequireDefault(require("./utils/noop"));
21
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
23
22
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
24
23
  /**
25
24
  * Draggable is a Vue component that allows elements to be dragged and dropped.
@@ -56,15 +55,21 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
56
55
  * Note:
57
56
  * This component requires Vue 3 and is designed to work within a Vue 3 application.
58
57
  */
59
- function _isSlot(s) {
60
- return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !(0, _vue.isVNode)(s);
61
- }
58
+
62
59
  const draggableProps = exports.draggableProps = {
63
60
  ..._DraggableCore.draggableCoreProps,
64
61
  axis: {
65
62
  type: String,
66
63
  default: 'both'
67
64
  },
65
+ directionLock: {
66
+ type: Boolean,
67
+ default: false
68
+ },
69
+ directionLockThreshold: {
70
+ type: Number,
71
+ default: 4
72
+ },
68
73
  bounds: {
69
74
  type: [Object, String, Boolean],
70
75
  default: false
@@ -113,31 +118,89 @@ const Draggable = exports.default = (0, _vue.defineComponent)({
113
118
  let {
114
119
  slots
115
120
  } = _ref;
116
- console.log('props', props);
117
- const rootElement = (0, _vue.ref)(null);
118
- if (props.position && !(props.dragFn || props.stopFn)) {
119
- // eslint-disable-next-line no-console
120
- console.warn('A `position` was applied to this <Draggable>, without drag handlers. This will make this ' + 'component effectively undraggable. Please attach `dragFn` or `stopFn` handlers so you can adjust the ' + '`position` of this element.');
121
- }
121
+ const localNodeRef = (0, _vue.ref)(null);
122
122
  const state = (0, _vue.reactive)({
123
123
  // Whether or not we are currently dragging.
124
124
  dragging: false,
125
125
  // Whether or not we have been dragged before.
126
126
  dragged: false,
127
127
  // Current transform x and y.
128
- x: props.position ? props.position.x : props.defaultPosition.x,
129
- y: props.position ? props.position.y : props.defaultPosition.y,
130
- prevPropsPosition: {
131
- ...props.position
132
- },
128
+ x: props.position?.x ?? props.defaultPosition.x ?? 0,
129
+ y: props.position?.y ?? props.defaultPosition.y ?? 0,
133
130
  // Used for compensating for out-of-bounds drags
134
131
  slackX: 0,
135
132
  slackY: 0,
136
133
  // Can only determine if SVG after mounting
137
134
  isElementSVG: false
138
135
  });
136
+ const internalState = {
137
+ isUnmounted: false
138
+ };
139
+ const isElementNode = v => {
140
+ return !!v && typeof v === 'object' && 'nodeType' in v && v.nodeType === 1;
141
+ };
142
+ const isRefLike = v => {
143
+ return !!v && typeof v === 'object' && 'value' in v;
144
+ };
139
145
  const findDOMNode = () => {
140
- return (0, _get.default)(props, 'nodeRef.value') || rootElement.value;
146
+ const nodeRef = props.nodeRef;
147
+ if (isRefLike(nodeRef)) {
148
+ const v = nodeRef.value;
149
+ if (isElementNode(v)) return v;
150
+ } else if (isElementNode(nodeRef)) {
151
+ return nodeRef;
152
+ }
153
+ return localNodeRef.value;
154
+ };
155
+ const boundsContext = {
156
+ props,
157
+ findDOMNode,
158
+ __boundsCache: {
159
+ key: '',
160
+ node: null,
161
+ boundEl: null,
162
+ boundClientWidth: 0,
163
+ boundClientHeight: 0,
164
+ nodeClientWidth: 0,
165
+ nodeClientHeight: 0,
166
+ bounds: null
167
+ }
168
+ };
169
+ let rafId = null;
170
+ let internalX = state.x;
171
+ let internalY = state.y;
172
+ let internalSlackX = state.slackX;
173
+ let internalSlackY = state.slackY;
174
+ let directionLockAxis = null;
175
+ let directionLockFixedX = NaN;
176
+ let directionLockFixedY = NaN;
177
+ let directionLockTotalX = 0;
178
+ let directionLockTotalY = 0;
179
+ const resetDirectionLock = () => {
180
+ directionLockAxis = null;
181
+ directionLockFixedX = NaN;
182
+ directionLockFixedY = NaN;
183
+ directionLockTotalX = 0;
184
+ directionLockTotalY = 0;
185
+ };
186
+ const getDirectionLockThreshold = () => {
187
+ const threshold = typeof props.directionLockThreshold === 'number' ? props.directionLockThreshold : 0;
188
+ if (threshold <= 0) return 0;
189
+ const scale = typeof props.scale === 'number' ? props.scale : 1;
190
+ if (!scale) return threshold;
191
+ return threshold / scale;
192
+ };
193
+ const flushToReactiveState = () => {
194
+ rafId = null;
195
+ if (internalX === state.x && internalY === state.y && internalSlackX === state.slackX && internalSlackY === state.slackY) return;
196
+ state.x = internalX;
197
+ state.y = internalY;
198
+ state.slackX = internalSlackX;
199
+ state.slackY = internalSlackY;
200
+ };
201
+ const scheduleFlush = () => {
202
+ if (rafId != null) return;
203
+ rafId = window.requestAnimationFrame(flushToReactiveState);
141
204
  };
142
205
  (0, _vue.onMounted)(() => {
143
206
  if (typeof window.SVGElement !== 'undefined' && findDOMNode() instanceof window.SVGElement) {
@@ -146,83 +209,229 @@ const Draggable = exports.default = (0, _vue.defineComponent)({
146
209
  });
147
210
  (0, _vue.onUnmounted)(() => {
148
211
  state.dragging = false;
212
+ internalState.isUnmounted = true;
213
+ if (rafId != null) {
214
+ window.cancelAnimationFrame(rafId);
215
+ rafId = null;
216
+ }
149
217
  });
150
218
  const onDragStart = (e, coreData) => {
151
219
  (0, _log.default)('Draggable: onDragStart: %j', coreData);
152
220
 
153
221
  // Short-circuit if user's callback killed it.
154
- const shouldStart = props.startFn?.(e, (0, _positionFns.createDraggableData)({
155
- props,
156
- state
157
- }, coreData));
158
- // Kills start event on core as well, so move handlers are never bound.
159
- if (shouldStart === false) return false;
222
+ const isControlled = Boolean(props.position);
223
+ if (isControlled) {
224
+ internalX = props.position.x;
225
+ internalY = props.position.y;
226
+ } else {
227
+ internalX = state.x;
228
+ internalY = state.y;
229
+ }
230
+ internalSlackX = state.slackX;
231
+ internalSlackY = state.slackY;
232
+ boundsContext.__boundsCache.key = '';
233
+ boundsContext.__boundsCache.node = null;
234
+ boundsContext.__boundsCache.boundEl = null;
235
+ boundsContext.__boundsCache.boundClientWidth = 0;
236
+ boundsContext.__boundsCache.boundClientHeight = 0;
237
+ boundsContext.__boundsCache.nodeClientWidth = 0;
238
+ boundsContext.__boundsCache.nodeClientHeight = 0;
239
+ boundsContext.__boundsCache.bounds = null;
240
+ resetDirectionLock();
241
+ flushToReactiveState();
242
+ if (props.startFn !== _noop.default) {
243
+ const scale = typeof props.scale === 'number' ? props.scale : 1;
244
+ const uiStart = {
245
+ node: coreData.node,
246
+ x: internalX + coreData.deltaX / scale,
247
+ y: internalY + coreData.deltaY / scale,
248
+ deltaX: coreData.deltaX / scale,
249
+ deltaY: coreData.deltaY / scale,
250
+ lastX: internalX,
251
+ lastY: internalY
252
+ };
253
+ const shouldStart = props.startFn?.(e, uiStart);
254
+ // Kills start event on core as well, so move handlers are never bound.
255
+ if (shouldStart === false) return false;
256
+ }
160
257
  state.dragging = true;
161
258
  state.dragged = true;
162
259
  };
163
260
  const onDrag = (e, coreData) => {
164
261
  if (!state.dragging) return false;
165
262
  (0, _log.default)('Draggable: dragFn: %j', coreData);
166
- const uiData = (0, _positionFns.createDraggableData)({
167
- props,
168
- state
169
- }, coreData);
170
- const newState = {
171
- x: uiData.x,
172
- y: uiData.y,
173
- slackX: 0,
174
- slackY: 0
175
- };
263
+ const scale = typeof props.scale === 'number' ? props.scale : 1;
264
+ const rawDeltaX = coreData.deltaX / scale;
265
+ const rawDeltaY = coreData.deltaY / scale;
266
+ let newX = internalX + rawDeltaX;
267
+ let newY = internalY + rawDeltaY;
268
+ let newSlackX = 0;
269
+ let newSlackY = 0;
270
+ let uiDeltaX = rawDeltaX;
271
+ let uiDeltaY = rawDeltaY;
272
+ const allowAxisX = (0, _positionFns.canDragX)({
273
+ props
274
+ });
275
+ const allowAxisY = (0, _positionFns.canDragY)({
276
+ props
277
+ });
278
+ let effectiveAxisX = allowAxisX;
279
+ let effectiveAxisY = allowAxisY;
280
+ if (props.directionLock && allowAxisX && allowAxisY) {
281
+ if (directionLockAxis == null) {
282
+ directionLockTotalX += rawDeltaX;
283
+ directionLockTotalY += rawDeltaY;
284
+ const threshold = getDirectionLockThreshold();
285
+ if (!threshold || Math.hypot(directionLockTotalX, directionLockTotalY) >= threshold) {
286
+ directionLockAxis = Math.abs(directionLockTotalX) >= Math.abs(directionLockTotalY) ? 'x' : 'y';
287
+ directionLockFixedX = internalX;
288
+ directionLockFixedY = internalY;
289
+ }
290
+ }
291
+ if (directionLockAxis === 'x' && Number.isFinite(directionLockFixedY)) {
292
+ newY = directionLockFixedY;
293
+ uiDeltaY = newY - internalY;
294
+ } else if (directionLockAxis === 'y' && Number.isFinite(directionLockFixedX)) {
295
+ newX = directionLockFixedX;
296
+ uiDeltaX = newX - internalX;
297
+ }
298
+ }
299
+ if (directionLockAxis === 'x') effectiveAxisY = false;
300
+ if (directionLockAxis === 'y') effectiveAxisX = false;
301
+ if (!effectiveAxisX) {
302
+ newX = internalX;
303
+ uiDeltaX = 0;
304
+ }
305
+ if (!effectiveAxisY) {
306
+ newY = internalY;
307
+ uiDeltaY = 0;
308
+ }
176
309
 
177
310
  // Keep within bounds.
178
311
  if (props.bounds) {
179
312
  // Save original x and y.
180
- const {
181
- x,
182
- y
183
- } = newState;
313
+ const x = newX;
314
+ const y = newY;
184
315
 
185
316
  // Add slack to the values used to calculate bound position. This will ensure that if
186
317
  // completely removed.
187
- newState.x += state.slackX;
188
- newState.y += state.slackY;
318
+ const slackX = effectiveAxisX ? internalSlackX : 0;
319
+ const slackY = effectiveAxisY ? internalSlackY : 0;
320
+ newX += slackX;
321
+ newY += slackY;
189
322
 
190
323
  // Get bound position. This will ceil/floor the x and y within the boundaries.
191
- const [newStateX, newStateY] = (0, _positionFns.getBoundPosition)({
192
- props,
193
- findDOMNode
194
- }, newState.x, newState.y);
195
- newState.x = newStateX;
196
- newState.y = newStateY;
324
+ const [boundX, boundY] = (0, _positionFns.getBoundPosition)(boundsContext, newX, newY);
325
+ newX = boundX;
326
+ newY = boundY;
197
327
 
198
328
  // Recalculate slack by noting how much was shaved by the boundPosition handler.
199
- newState.slackX = state.slackX + (x - newState.x);
200
- newState.slackY = state.slackY + (y - newState.y);
329
+ newSlackX = slackX + (x - newX);
330
+ newSlackY = slackY + (y - newY);
201
331
 
202
332
  // Update the event we fire to reflect what really happened after bounds took effect.
203
- uiData.x = newState.x;
204
- uiData.y = newState.y;
205
- uiData.deltaX = newState.x - (state.x ?? 0);
206
- uiData.deltaY = newState.y - (state.y ?? 0);
333
+ uiDeltaX = newX - internalX;
334
+ uiDeltaY = newY - internalY;
207
335
  }
336
+ if (!effectiveAxisX) newSlackX = 0;
337
+ if (!effectiveAxisY) newSlackY = 0;
208
338
 
209
339
  // Short-circuit if user's callback killed it.
210
- const shouldUpdate = props.dragFn?.(e, uiData);
211
- if (shouldUpdate === false) return false;
212
- Object.keys(newState).forEach(key => {
213
- state[key] = newState[key];
214
- });
340
+ if (props.dragFn !== _noop.default) {
341
+ const uiData = {
342
+ node: coreData.node,
343
+ x: newX,
344
+ y: newY,
345
+ deltaX: uiDeltaX,
346
+ deltaY: uiDeltaY,
347
+ lastX: internalX,
348
+ lastY: internalY
349
+ };
350
+ const shouldUpdate = props.dragFn?.(e, uiData);
351
+ if (shouldUpdate === false) return false;
352
+ }
353
+ internalX = newX;
354
+ internalY = newY;
355
+ internalSlackX = newSlackX;
356
+ internalSlackY = newSlackY;
357
+
358
+ // PERF: If we are not controlled, we can just move the element directly.
359
+ // This allows us to run at 60fps without the overhead of Vue's reactivity system.
360
+ if (!props.position) {
361
+ const transformOpts = {
362
+ x: (0, _positionFns.canDragX)({
363
+ props
364
+ }) ? internalX : props.defaultPosition.x,
365
+ y: (0, _positionFns.canDragY)({
366
+ props
367
+ }) ? internalY : props.defaultPosition.y
368
+ };
369
+ const positionOffset = props.positionOffset;
370
+ const unit = 'px';
371
+ const isSVG = state.isElementSVG;
372
+ const translation = (0, _domFns.getTranslation)(transformOpts, positionOffset, unit);
373
+ const domNode = findDOMNode();
374
+ if (domNode) {
375
+ if (isSVG) {
376
+ // SVG logic usually requires attribute setting, but for performance we might try CSS if possible,
377
+ // or just fallback to reactivity.
378
+ // However, the original code used `createSVGTransform` which returns a string for `transform` attribute?
379
+ // Wait, existing code uses `transform` prop on VNode for SVG.
380
+ // Direct DOM manipulation on SVG attributes is also possible.
381
+ // For now, let's keep SVG on the react path or try direct setAttribute if simple.
382
+ // But let's stick to HTMLElement for the 'style' path for now to be safe.
383
+ if (!isSVG) (0, _domFns.setTransform)(domNode, translation);
384
+ } else {
385
+ (0, _domFns.setTransform)(domNode, translation);
386
+ }
387
+ }
388
+ }
389
+
390
+ // If controlled, or if using RafDrag, or if SVG (for safety), we flush.
391
+ // Actually, if controlled, we MUST flush to let parent update.
392
+ // If uncontrolled and HTML, we skip flush until stop!
393
+ if (props.position || props.useRafDrag || state.isElementSVG) {
394
+ if (props.useRafDrag) {
395
+ if (rafId != null) {
396
+ window.cancelAnimationFrame(rafId);
397
+ rafId = null;
398
+ }
399
+ flushToReactiveState();
400
+ } else {
401
+ scheduleFlush();
402
+ }
403
+ }
215
404
  };
216
405
  const onDragStop = (e, coreData) => {
217
406
  if (!state.dragging) return false;
218
407
 
219
408
  // Short-circuit if user's callback killed it.
220
- const shouldContinue = props.stopFn?.(e, (0, _positionFns.createDraggableData)({
221
- props,
222
- state
223
- }, coreData));
224
- if (shouldContinue === false) return false;
409
+ if (props.stopFn !== _noop.default) {
410
+ const scale = typeof props.scale === 'number' ? props.scale : 1;
411
+ const allowAxisX = (0, _positionFns.canDragX)({
412
+ props
413
+ });
414
+ const allowAxisY = (0, _positionFns.canDragY)({
415
+ props
416
+ });
417
+ const effectiveAxisX = allowAxisX && directionLockAxis !== 'y';
418
+ const effectiveAxisY = allowAxisY && directionLockAxis !== 'x';
419
+ const deltaX = effectiveAxisX ? coreData.deltaX / scale : 0;
420
+ const deltaY = effectiveAxisY ? coreData.deltaY / scale : 0;
421
+ const uiStop = {
422
+ node: coreData.node,
423
+ x: internalX + deltaX,
424
+ y: internalY + deltaY,
425
+ deltaX,
426
+ deltaY,
427
+ lastX: internalX,
428
+ lastY: internalY
429
+ };
430
+ const shouldContinue = props.stopFn?.(e, uiStop);
431
+ if (shouldContinue === false) return false;
432
+ }
225
433
  (0, _log.default)('Draggable: onDragStop: %j', coreData);
434
+ resetDirectionLock();
226
435
  const newState = {
227
436
  dragging: false,
228
437
  slackX: 0,
@@ -240,14 +449,57 @@ const Draggable = exports.default = (0, _vue.defineComponent)({
240
449
  newState.x = x;
241
450
  newState.y = y;
242
451
  }
243
- Object.keys(newState).forEach(key => {
244
- state[key] = newState[key];
245
- });
452
+ state.dragging = newState.dragging;
453
+ internalSlackX = newState.slackX;
454
+ internalSlackY = newState.slackY;
455
+ if (typeof newState.x === 'number') internalX = newState.x;
456
+ if (typeof newState.y === 'number') internalY = newState.y;
457
+ if (rafId != null) {
458
+ window.cancelAnimationFrame(rafId);
459
+ rafId = null;
460
+ }
461
+
462
+ // Always flush at the end to ensure state sync
463
+ flushToReactiveState();
464
+ };
465
+ const getFirstUsableChild = () => {
466
+ const raw = slots.default ? slots.default() : [];
467
+ const stack = Array.isArray(raw) ? [...raw] : [raw];
468
+ while (stack.length) {
469
+ const item = stack.shift();
470
+ if (Array.isArray(item)) {
471
+ for (let i = item.length - 1; i >= 0; i -= 1) stack.unshift(item[i]);
472
+ continue;
473
+ }
474
+ if (!(0, _vue.isVNode)(item)) continue;
475
+
476
+ // Skip comment nodes and whitespace-only text nodes.
477
+ if (item.type === _vue.Comment) continue;
478
+ if (item.type === _vue.Text) {
479
+ const txt = typeof item.children === 'string' ? item.children : '';
480
+ if (!txt || !txt.trim()) continue;
481
+ // Draggable requires an element/component vnode, not bare text.
482
+ continue;
483
+ }
484
+
485
+ // Unwrap fragments to find the first real node.
486
+ if (item.type === _vue.Fragment) {
487
+ const fragChildren = item.children;
488
+ if (Array.isArray(fragChildren)) {
489
+ for (let i = fragChildren.length - 1; i >= 0; i -= 1) stack.unshift(fragChildren[i]);
490
+ }
491
+ continue;
492
+ }
493
+ return item;
494
+ }
495
+ return null;
246
496
  };
247
497
  return () => {
248
498
  /* eslint-disable @typescript-eslint/no-unused-vars */
249
499
  const {
250
500
  axis,
501
+ directionLock,
502
+ directionLockThreshold,
251
503
  bounds,
252
504
  defaultPosition,
253
505
  defaultClassName,
@@ -287,12 +539,18 @@ const Draggable = exports.default = (0, _vue.defineComponent)({
287
539
  style = (0, _domFns.createCSSTransform)(transformOpts, positionOffset);
288
540
  }
289
541
 
542
+ // Performance adjustment:
543
+ if (state.dragging && !state.isElementSVG) {
544
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
545
+ style.willChange = 'transform';
546
+ }
547
+
290
548
  // Mark with class while dragging
291
549
  const className = (0, _clsx.default)(defaultClassName, {
292
550
  [defaultClassNameDragging]: state.dragging,
293
551
  [defaultClassNameDragged]: state.dragged
294
552
  });
295
- const child = slots.default ? slots.default()[0] : null;
553
+ const child = getFirstUsableChild();
296
554
  if (!child) return null;
297
555
  const clonedChildren = (0, _vue.cloneVNode)(child, {
298
556
  class: className,
@@ -305,10 +563,10 @@ const Draggable = exports.default = (0, _vue.defineComponent)({
305
563
  dragFn: onDrag,
306
564
  stopFn: onDragStop
307
565
  };
308
- return (0, _vue.createVNode)(_DraggableCore.default, (0, _vue.mergeProps)({
309
- "ref": rootElement
310
- }, coreProps), _isSlot(clonedChildren) ? clonedChildren : {
311
- default: () => [clonedChildren]
566
+ return (0, _vue.createVNode)(_DraggableCore.default, (0, _vue.mergeProps)(coreProps, {
567
+ "nodeRef": props.nodeRef || localNodeRef
568
+ }), {
569
+ default: () => clonedChildren
312
570
  });
313
571
  };
314
572
  }