funda-ui 4.7.711 → 4.7.730
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.
- package/DragDropList/index.d.ts +1 -0
- package/DragDropList/index.js +143 -52
- package/DynamicFields/index.d.ts +1 -0
- package/DynamicFields/index.js +108 -8
- package/EventCalendarTimeline/index.css +12 -1
- package/EventCalendarTimeline/index.d.ts +1 -0
- package/EventCalendarTimeline/index.js +99 -6
- package/MultipleSelect/index.js +162 -71
- package/Table/index.css +5 -1
- package/Table/index.js +410 -90
- package/Utils/useBoundedDrag.d.ts +1 -0
- package/Utils/useBoundedDrag.js +124 -39
- package/lib/cjs/DragDropList/index.d.ts +1 -0
- package/lib/cjs/DragDropList/index.js +143 -52
- package/lib/cjs/DynamicFields/index.d.ts +1 -0
- package/lib/cjs/DynamicFields/index.js +108 -8
- package/lib/cjs/EventCalendarTimeline/index.d.ts +1 -0
- package/lib/cjs/EventCalendarTimeline/index.js +99 -6
- package/lib/cjs/MultipleSelect/index.js +162 -71
- package/lib/cjs/Table/index.js +410 -90
- package/lib/cjs/Utils/useBoundedDrag.d.ts +1 -0
- package/lib/cjs/Utils/useBoundedDrag.js +124 -39
- package/lib/css/EventCalendarTimeline/index.css +12 -1
- package/lib/css/Table/index.css +5 -1
- package/lib/esm/DragDropList/index.tsx +23 -16
- package/lib/esm/DynamicFields/index.tsx +107 -8
- package/lib/esm/EventCalendarTimeline/index.scss +15 -1
- package/lib/esm/EventCalendarTimeline/index.tsx +130 -11
- package/lib/esm/ModalDialog/index.tsx +0 -1
- package/lib/esm/Table/Table.tsx +9 -7
- package/lib/esm/Table/TableRow.tsx +9 -3
- package/lib/esm/Table/index.scss +8 -2
- package/lib/esm/Table/utils/DragHandleSprite.tsx +6 -2
- package/lib/esm/Table/utils/func.ts +12 -1
- package/lib/esm/Table/utils/hooks/useTableDraggable.tsx +401 -93
- package/lib/esm/Utils/hooks/useBoundedDrag.tsx +142 -39
- package/package.json +1 -1
|
@@ -112,6 +112,7 @@ export interface BoundedDragOptions {
|
|
|
112
112
|
dragHandleSelector?: string;
|
|
113
113
|
onDragStart?: (index: number) => void;
|
|
114
114
|
onDragOver?: (dragIndex: number | null, dropIndex: number | null) => void;
|
|
115
|
+
onDragUpdate?: (dragIndex: number | null, dropIndex: number | null) => void;
|
|
115
116
|
onDragEnd?: (dragIndex: number | null, dropIndex: number | null) => void;
|
|
116
117
|
}
|
|
117
118
|
export declare const useBoundedDrag: (options?: BoundedDragOptions) => {
|
package/Utils/useBoundedDrag.js
CHANGED
|
@@ -220,6 +220,7 @@ var useBoundedDrag = function useBoundedDrag() {
|
|
|
220
220
|
dragHandleSelector = _options$dragHandleSe === void 0 ? '.custom-draggable-list__handle' : _options$dragHandleSe,
|
|
221
221
|
onDragStart = options.onDragStart,
|
|
222
222
|
onDragOver = options.onDragOver,
|
|
223
|
+
onDragUpdate = options.onDragUpdate,
|
|
223
224
|
onDragEnd = options.onDragEnd;
|
|
224
225
|
var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false),
|
|
225
226
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -228,11 +229,35 @@ var useBoundedDrag = function useBoundedDrag() {
|
|
|
228
229
|
var dragItem = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
229
230
|
var dragOverItem = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
230
231
|
var dragNode = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
232
|
+
var draggedElement = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
233
|
+
var boundaryElement = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
231
234
|
var touchOffset = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)({
|
|
232
235
|
x: 0,
|
|
233
236
|
y: 0
|
|
234
237
|
});
|
|
235
238
|
var currentHoverItem = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
239
|
+
var rafId = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
240
|
+
var lastUpdateDragIndex = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
241
|
+
var lastUpdateDropIndex = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Performance Note:
|
|
245
|
+
*
|
|
246
|
+
* Drag-over events can fire at a very high frequency, especially on touch devices
|
|
247
|
+
* or when dragging quickly. Directly performing DOM read/write operations in the
|
|
248
|
+
* event handler (e.g. `getBoundingClientRect`, `classList` changes, style updates)
|
|
249
|
+
* can easily cause layout thrashing and frame drops when there are many items.
|
|
250
|
+
*
|
|
251
|
+
* To mitigate this, we:
|
|
252
|
+
* - Collect the pointer coordinates synchronously in the event handler.
|
|
253
|
+
* - Schedule all DOM-intensive work inside `requestAnimationFrame`, so the browser
|
|
254
|
+
* batches these operations before the next paint.
|
|
255
|
+
* - Cancel any pending frame (`cancelAnimationFrame`) before scheduling a new one,
|
|
256
|
+
* ensuring there is at most one pending DOM update per frame.
|
|
257
|
+
*
|
|
258
|
+
* This keeps drag interactions smooth even with large lists.
|
|
259
|
+
*/
|
|
260
|
+
|
|
236
261
|
var handleDragStart = function handleDragStart(e, position) {
|
|
237
262
|
var isTouch = ('touches' in e);
|
|
238
263
|
var target = e.target;
|
|
@@ -285,69 +310,127 @@ var useBoundedDrag = function useBoundedDrag() {
|
|
|
285
310
|
opacity: '0.9'
|
|
286
311
|
});
|
|
287
312
|
document.body.appendChild(dragNode.current);
|
|
313
|
+
|
|
314
|
+
// Keep track of the original element (acts as a placeholder inside the list)
|
|
315
|
+
draggedElement.current = listItem;
|
|
316
|
+
boundaryElement.current = boundary;
|
|
288
317
|
setIsDragging(true);
|
|
289
318
|
listItem.classList.add('dragging-placeholder');
|
|
290
319
|
} else {
|
|
291
|
-
//
|
|
320
|
+
// Desktop: use native drag image, but still record dragged element / boundary
|
|
321
|
+
draggedElement.current = listItem;
|
|
322
|
+
boundaryElement.current = boundary;
|
|
323
|
+
setIsDragging(true);
|
|
324
|
+
var dragEvent = e;
|
|
325
|
+
if (dragEvent.dataTransfer) {
|
|
326
|
+
dragEvent.dataTransfer.effectAllowed = 'move';
|
|
327
|
+
// Optional: customize drag preview if needed
|
|
328
|
+
dragEvent.dataTransfer.setData('text/plain', '');
|
|
329
|
+
}
|
|
330
|
+
listItem.classList.add('dragging-placeholder');
|
|
292
331
|
}
|
|
293
332
|
};
|
|
294
333
|
var handleDragOver = function handleDragOver(e) {
|
|
334
|
+
// Always prevent default synchronously
|
|
295
335
|
e.preventDefault();
|
|
296
336
|
var isTouch = ('touches' in e);
|
|
297
337
|
if (!isTouch) {
|
|
298
338
|
e.dataTransfer.dropEffect = 'move';
|
|
299
339
|
}
|
|
300
340
|
|
|
301
|
-
//
|
|
302
|
-
var
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
341
|
+
// Extract primitive coordinates synchronously to avoid using pooled events in async callbacks
|
|
342
|
+
var clientX;
|
|
343
|
+
var clientY;
|
|
344
|
+
if (isTouch) {
|
|
345
|
+
var touch = e.touches[0];
|
|
346
|
+
clientX = touch.clientX;
|
|
347
|
+
clientY = touch.clientY;
|
|
348
|
+
} else {
|
|
349
|
+
clientX = e.clientX;
|
|
350
|
+
clientY = e.clientY;
|
|
351
|
+
}
|
|
306
352
|
|
|
307
|
-
//
|
|
308
|
-
if (
|
|
309
|
-
|
|
310
|
-
dragNode.current.style.top = "".concat(point.clientY - touchOffset.current.y, "px");
|
|
353
|
+
// Cancel any pending frame to avoid stacking DOM operations
|
|
354
|
+
if (rafId.current !== null) {
|
|
355
|
+
cancelAnimationFrame(rafId.current);
|
|
311
356
|
}
|
|
357
|
+
rafId.current = requestAnimationFrame(function () {
|
|
358
|
+
// Update dragged element position for touch events
|
|
359
|
+
if (isTouch && isDragging && dragNode.current) {
|
|
360
|
+
dragNode.current.style.left = "".concat(clientX - touchOffset.current.x, "px");
|
|
361
|
+
dragNode.current.style.top = "".concat(clientY - touchOffset.current.y, "px");
|
|
362
|
+
}
|
|
312
363
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
364
|
+
// Find the element below the pointer/touch
|
|
365
|
+
var elemBelow = document.elementFromPoint(clientX, clientY);
|
|
366
|
+
if (!elemBelow) return;
|
|
316
367
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
368
|
+
// Find the closest list item
|
|
369
|
+
var listItem = elemBelow.closest(itemSelector);
|
|
370
|
+
if (!listItem) return;
|
|
320
371
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
372
|
+
// Check boundary
|
|
373
|
+
var boundary = boundaryElement.current || listItem.closest(boundarySelector);
|
|
374
|
+
if (!boundary) return;
|
|
324
375
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
listItem.
|
|
343
|
-
|
|
344
|
-
|
|
376
|
+
// Update hover states
|
|
377
|
+
if (currentHoverItem.current && currentHoverItem.current !== listItem) {
|
|
378
|
+
currentHoverItem.current.classList.remove('drag-over', 'drag-over-top', 'drag-over-bottom');
|
|
379
|
+
}
|
|
380
|
+
currentHoverItem.current = listItem;
|
|
381
|
+
listItem.classList.add('drag-over');
|
|
382
|
+
var dragEl = draggedElement.current;
|
|
383
|
+
if (!dragEl || !dragEl.parentNode) return;
|
|
384
|
+
var container = boundary;
|
|
385
|
+
|
|
386
|
+
// Collect current ordered items in the container
|
|
387
|
+
var children = Array.from(container.querySelectorAll(itemSelector));
|
|
388
|
+
var currentIndex = children.indexOf(dragEl);
|
|
389
|
+
var targetIndex = children.indexOf(listItem);
|
|
390
|
+
if (currentIndex === -1 || targetIndex === -1) return;
|
|
391
|
+
|
|
392
|
+
// Determine drop position (top/bottom)
|
|
393
|
+
var rect = listItem.getBoundingClientRect();
|
|
394
|
+
var middleY = rect.top + rect.height / 2;
|
|
395
|
+
listItem.classList.remove('drag-over-top', 'drag-over-bottom');
|
|
396
|
+
var insertBefore = clientY < middleY ? listItem : listItem.nextElementSibling;
|
|
397
|
+
if (clientY < middleY) {
|
|
398
|
+
listItem.classList.add('drag-over-top');
|
|
399
|
+
} else {
|
|
400
|
+
listItem.classList.add('drag-over-bottom');
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Only move in DOM when the effective position changes
|
|
404
|
+
if (insertBefore !== dragEl && container.contains(dragEl)) {
|
|
405
|
+
container.insertBefore(dragEl, insertBefore);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Recompute index after DOM move
|
|
409
|
+
var reorderedChildren = Array.from(container.querySelectorAll(itemSelector));
|
|
410
|
+
var newIndex = reorderedChildren.indexOf(dragEl);
|
|
411
|
+
dragOverItem.current = newIndex;
|
|
412
|
+
onDragOver === null || onDragOver === void 0 ? void 0 : onDragOver(dragItem.current, dragOverItem.current);
|
|
413
|
+
|
|
414
|
+
// Only fire onDragUpdate when the (dragIndex, dropIndex) pair actually changes.
|
|
415
|
+
if (onDragUpdate && (dragItem.current !== lastUpdateDragIndex.current || dragOverItem.current !== lastUpdateDropIndex.current)) {
|
|
416
|
+
lastUpdateDragIndex.current = dragItem.current;
|
|
417
|
+
lastUpdateDropIndex.current = dragOverItem.current;
|
|
418
|
+
onDragUpdate(dragItem.current, dragOverItem.current);
|
|
419
|
+
}
|
|
420
|
+
rafId.current = null;
|
|
421
|
+
});
|
|
345
422
|
};
|
|
346
423
|
var handleDragEnd = function handleDragEnd(e) {
|
|
347
424
|
var isTouch = ('touches' in e);
|
|
348
425
|
if (isTouch && !isDragging) return;
|
|
349
426
|
onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd(dragItem.current, dragOverItem.current);
|
|
350
427
|
|
|
428
|
+
// Cancel any pending animation frame
|
|
429
|
+
if (rafId.current !== null) {
|
|
430
|
+
cancelAnimationFrame(rafId.current);
|
|
431
|
+
rafId.current = null;
|
|
432
|
+
}
|
|
433
|
+
|
|
351
434
|
// Cleanup
|
|
352
435
|
if (dragNode.current) {
|
|
353
436
|
dragNode.current.remove();
|
|
@@ -361,6 +444,8 @@ var useBoundedDrag = function useBoundedDrag() {
|
|
|
361
444
|
currentHoverItem.current = null;
|
|
362
445
|
dragItem.current = null;
|
|
363
446
|
dragOverItem.current = null;
|
|
447
|
+
draggedElement.current = null;
|
|
448
|
+
boundaryElement.current = null;
|
|
364
449
|
};
|
|
365
450
|
return {
|
|
366
451
|
isDragging: isDragging,
|
|
@@ -895,6 +895,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|
|
895
895
|
dragHandleSelector = _options$dragHandleSe === void 0 ? '.custom-draggable-list__handle' : _options$dragHandleSe,
|
|
896
896
|
onDragStart = options.onDragStart,
|
|
897
897
|
onDragOver = options.onDragOver,
|
|
898
|
+
onDragUpdate = options.onDragUpdate,
|
|
898
899
|
onDragEnd = options.onDragEnd;
|
|
899
900
|
var _useState = (0, react__WEBPACK_IMPORTED_MODULE_0__.useState)(false),
|
|
900
901
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -903,11 +904,35 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|
|
903
904
|
var dragItem = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
904
905
|
var dragOverItem = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
905
906
|
var dragNode = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
907
|
+
var draggedElement = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
908
|
+
var boundaryElement = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
906
909
|
var touchOffset = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)({
|
|
907
910
|
x: 0,
|
|
908
911
|
y: 0
|
|
909
912
|
});
|
|
910
913
|
var currentHoverItem = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
914
|
+
var rafId = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
915
|
+
var lastUpdateDragIndex = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
916
|
+
var lastUpdateDropIndex = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
917
|
+
|
|
918
|
+
/**
|
|
919
|
+
* Performance Note:
|
|
920
|
+
*
|
|
921
|
+
* Drag-over events can fire at a very high frequency, especially on touch devices
|
|
922
|
+
* or when dragging quickly. Directly performing DOM read/write operations in the
|
|
923
|
+
* event handler (e.g. `getBoundingClientRect`, `classList` changes, style updates)
|
|
924
|
+
* can easily cause layout thrashing and frame drops when there are many items.
|
|
925
|
+
*
|
|
926
|
+
* To mitigate this, we:
|
|
927
|
+
* - Collect the pointer coordinates synchronously in the event handler.
|
|
928
|
+
* - Schedule all DOM-intensive work inside `requestAnimationFrame`, so the browser
|
|
929
|
+
* batches these operations before the next paint.
|
|
930
|
+
* - Cancel any pending frame (`cancelAnimationFrame`) before scheduling a new one,
|
|
931
|
+
* ensuring there is at most one pending DOM update per frame.
|
|
932
|
+
*
|
|
933
|
+
* This keeps drag interactions smooth even with large lists.
|
|
934
|
+
*/
|
|
935
|
+
|
|
911
936
|
var handleDragStart = function handleDragStart(e, position) {
|
|
912
937
|
var isTouch = ('touches' in e);
|
|
913
938
|
var target = e.target;
|
|
@@ -960,69 +985,127 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|
|
960
985
|
opacity: '0.9'
|
|
961
986
|
});
|
|
962
987
|
document.body.appendChild(dragNode.current);
|
|
988
|
+
|
|
989
|
+
// Keep track of the original element (acts as a placeholder inside the list)
|
|
990
|
+
draggedElement.current = listItem;
|
|
991
|
+
boundaryElement.current = boundary;
|
|
963
992
|
setIsDragging(true);
|
|
964
993
|
listItem.classList.add('dragging-placeholder');
|
|
965
994
|
} else {
|
|
966
|
-
//
|
|
995
|
+
// Desktop: use native drag image, but still record dragged element / boundary
|
|
996
|
+
draggedElement.current = listItem;
|
|
997
|
+
boundaryElement.current = boundary;
|
|
998
|
+
setIsDragging(true);
|
|
999
|
+
var dragEvent = e;
|
|
1000
|
+
if (dragEvent.dataTransfer) {
|
|
1001
|
+
dragEvent.dataTransfer.effectAllowed = 'move';
|
|
1002
|
+
// Optional: customize drag preview if needed
|
|
1003
|
+
dragEvent.dataTransfer.setData('text/plain', '');
|
|
1004
|
+
}
|
|
1005
|
+
listItem.classList.add('dragging-placeholder');
|
|
967
1006
|
}
|
|
968
1007
|
};
|
|
969
1008
|
var handleDragOver = function handleDragOver(e) {
|
|
1009
|
+
// Always prevent default synchronously
|
|
970
1010
|
e.preventDefault();
|
|
971
1011
|
var isTouch = ('touches' in e);
|
|
972
1012
|
if (!isTouch) {
|
|
973
1013
|
e.dataTransfer.dropEffect = 'move';
|
|
974
1014
|
}
|
|
975
1015
|
|
|
976
|
-
//
|
|
977
|
-
var
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1016
|
+
// Extract primitive coordinates synchronously to avoid using pooled events in async callbacks
|
|
1017
|
+
var clientX;
|
|
1018
|
+
var clientY;
|
|
1019
|
+
if (isTouch) {
|
|
1020
|
+
var touch = e.touches[0];
|
|
1021
|
+
clientX = touch.clientX;
|
|
1022
|
+
clientY = touch.clientY;
|
|
1023
|
+
} else {
|
|
1024
|
+
clientX = e.clientX;
|
|
1025
|
+
clientY = e.clientY;
|
|
1026
|
+
}
|
|
981
1027
|
|
|
982
|
-
//
|
|
983
|
-
if (
|
|
984
|
-
|
|
985
|
-
dragNode.current.style.top = "".concat(point.clientY - touchOffset.current.y, "px");
|
|
1028
|
+
// Cancel any pending frame to avoid stacking DOM operations
|
|
1029
|
+
if (rafId.current !== null) {
|
|
1030
|
+
cancelAnimationFrame(rafId.current);
|
|
986
1031
|
}
|
|
1032
|
+
rafId.current = requestAnimationFrame(function () {
|
|
1033
|
+
// Update dragged element position for touch events
|
|
1034
|
+
if (isTouch && isDragging && dragNode.current) {
|
|
1035
|
+
dragNode.current.style.left = "".concat(clientX - touchOffset.current.x, "px");
|
|
1036
|
+
dragNode.current.style.top = "".concat(clientY - touchOffset.current.y, "px");
|
|
1037
|
+
}
|
|
987
1038
|
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1039
|
+
// Find the element below the pointer/touch
|
|
1040
|
+
var elemBelow = document.elementFromPoint(clientX, clientY);
|
|
1041
|
+
if (!elemBelow) return;
|
|
991
1042
|
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1043
|
+
// Find the closest list item
|
|
1044
|
+
var listItem = elemBelow.closest(itemSelector);
|
|
1045
|
+
if (!listItem) return;
|
|
995
1046
|
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1047
|
+
// Check boundary
|
|
1048
|
+
var boundary = boundaryElement.current || listItem.closest(boundarySelector);
|
|
1049
|
+
if (!boundary) return;
|
|
999
1050
|
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
listItem.
|
|
1018
|
-
|
|
1019
|
-
|
|
1051
|
+
// Update hover states
|
|
1052
|
+
if (currentHoverItem.current && currentHoverItem.current !== listItem) {
|
|
1053
|
+
currentHoverItem.current.classList.remove('drag-over', 'drag-over-top', 'drag-over-bottom');
|
|
1054
|
+
}
|
|
1055
|
+
currentHoverItem.current = listItem;
|
|
1056
|
+
listItem.classList.add('drag-over');
|
|
1057
|
+
var dragEl = draggedElement.current;
|
|
1058
|
+
if (!dragEl || !dragEl.parentNode) return;
|
|
1059
|
+
var container = boundary;
|
|
1060
|
+
|
|
1061
|
+
// Collect current ordered items in the container
|
|
1062
|
+
var children = Array.from(container.querySelectorAll(itemSelector));
|
|
1063
|
+
var currentIndex = children.indexOf(dragEl);
|
|
1064
|
+
var targetIndex = children.indexOf(listItem);
|
|
1065
|
+
if (currentIndex === -1 || targetIndex === -1) return;
|
|
1066
|
+
|
|
1067
|
+
// Determine drop position (top/bottom)
|
|
1068
|
+
var rect = listItem.getBoundingClientRect();
|
|
1069
|
+
var middleY = rect.top + rect.height / 2;
|
|
1070
|
+
listItem.classList.remove('drag-over-top', 'drag-over-bottom');
|
|
1071
|
+
var insertBefore = clientY < middleY ? listItem : listItem.nextElementSibling;
|
|
1072
|
+
if (clientY < middleY) {
|
|
1073
|
+
listItem.classList.add('drag-over-top');
|
|
1074
|
+
} else {
|
|
1075
|
+
listItem.classList.add('drag-over-bottom');
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
// Only move in DOM when the effective position changes
|
|
1079
|
+
if (insertBefore !== dragEl && container.contains(dragEl)) {
|
|
1080
|
+
container.insertBefore(dragEl, insertBefore);
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
// Recompute index after DOM move
|
|
1084
|
+
var reorderedChildren = Array.from(container.querySelectorAll(itemSelector));
|
|
1085
|
+
var newIndex = reorderedChildren.indexOf(dragEl);
|
|
1086
|
+
dragOverItem.current = newIndex;
|
|
1087
|
+
onDragOver === null || onDragOver === void 0 ? void 0 : onDragOver(dragItem.current, dragOverItem.current);
|
|
1088
|
+
|
|
1089
|
+
// Only fire onDragUpdate when the (dragIndex, dropIndex) pair actually changes.
|
|
1090
|
+
if (onDragUpdate && (dragItem.current !== lastUpdateDragIndex.current || dragOverItem.current !== lastUpdateDropIndex.current)) {
|
|
1091
|
+
lastUpdateDragIndex.current = dragItem.current;
|
|
1092
|
+
lastUpdateDropIndex.current = dragOverItem.current;
|
|
1093
|
+
onDragUpdate(dragItem.current, dragOverItem.current);
|
|
1094
|
+
}
|
|
1095
|
+
rafId.current = null;
|
|
1096
|
+
});
|
|
1020
1097
|
};
|
|
1021
1098
|
var handleDragEnd = function handleDragEnd(e) {
|
|
1022
1099
|
var isTouch = ('touches' in e);
|
|
1023
1100
|
if (isTouch && !isDragging) return;
|
|
1024
1101
|
onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd(dragItem.current, dragOverItem.current);
|
|
1025
1102
|
|
|
1103
|
+
// Cancel any pending animation frame
|
|
1104
|
+
if (rafId.current !== null) {
|
|
1105
|
+
cancelAnimationFrame(rafId.current);
|
|
1106
|
+
rafId.current = null;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1026
1109
|
// Cleanup
|
|
1027
1110
|
if (dragNode.current) {
|
|
1028
1111
|
dragNode.current.remove();
|
|
@@ -1036,6 +1119,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|
|
1036
1119
|
currentHoverItem.current = null;
|
|
1037
1120
|
dragItem.current = null;
|
|
1038
1121
|
dragOverItem.current = null;
|
|
1122
|
+
draggedElement.current = null;
|
|
1123
|
+
boundaryElement.current = null;
|
|
1039
1124
|
};
|
|
1040
1125
|
return {
|
|
1041
1126
|
isDragging: isDragging,
|
|
@@ -1366,6 +1451,9 @@ var DragDropList = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef
|
|
|
1366
1451
|
onDragOver: function onDragOver(dragIndex, dropIndex) {
|
|
1367
1452
|
// Additional drag over logic if needed
|
|
1368
1453
|
},
|
|
1454
|
+
onDragUpdate: function onDragUpdate(dragIndex, dropIndex) {
|
|
1455
|
+
// console.log(dragIndex, dropIndex);
|
|
1456
|
+
},
|
|
1369
1457
|
onDragEnd: function onDragEnd(dragIndex, dropIndex) {
|
|
1370
1458
|
if (dragIndex !== null && dropIndex !== null && dragIndex !== dropIndex) {
|
|
1371
1459
|
var _newItems$dragIndex, _newItems$dragIndex2, _newItems$dropIndex;
|
|
@@ -1398,12 +1486,12 @@ var DragDropList = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef
|
|
|
1398
1486
|
});
|
|
1399
1487
|
|
|
1400
1488
|
// Calculate new insert position
|
|
1489
|
+
// Directly use dropIndex as the insertion position to avoid items snapping back
|
|
1490
|
+
// when dragging an item from above to directly below its neighbor.
|
|
1401
1491
|
var insertIndex = dropIndex;
|
|
1402
|
-
if (dropIndex > dragIndex) {
|
|
1403
|
-
insertIndex -= itemsToMove.length;
|
|
1404
|
-
}
|
|
1405
1492
|
|
|
1406
|
-
// Insert all items
|
|
1493
|
+
// Insert all items (remove first, then insert at the target index;
|
|
1494
|
+
// JavaScript's splice will handle index shifting automatically).
|
|
1407
1495
|
newItems.splice.apply(newItems, [insertIndex, 0].concat(_toConsumableArray(itemsBeingMoved)));
|
|
1408
1496
|
|
|
1409
1497
|
// Rebuild tree structure
|
|
@@ -1516,6 +1604,9 @@ var DragDropList = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef
|
|
|
1516
1604
|
// If the item should be hidden, the rendering is skipped
|
|
1517
1605
|
if (!shouldShowItem(item)) return null;
|
|
1518
1606
|
|
|
1607
|
+
// Item level draggable control, default true when not specified
|
|
1608
|
+
var isItemDraggable = draggable && item.itemDraggable !== false;
|
|
1609
|
+
|
|
1519
1610
|
// collapse
|
|
1520
1611
|
var hasChildItems = hasChildren(item.id);
|
|
1521
1612
|
var isCollapsed = collapsedItems.has(item.id);
|
|
@@ -1529,30 +1620,30 @@ var DragDropList = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef
|
|
|
1529
1620
|
"data-listitemlabel": item.listItemLabel,
|
|
1530
1621
|
className: (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_2__.combinedCls)("".concat(prefix, "-draggable-list__item"), (0,funda_utils_dist_cjs_cls__WEBPACK_IMPORTED_MODULE_2__.clsWrite)(dragMode, 'handle'), {
|
|
1531
1622
|
'disabled': item.disabled,
|
|
1532
|
-
'draggable':
|
|
1623
|
+
'draggable': isItemDraggable,
|
|
1533
1624
|
'editing': editingItem === item.id,
|
|
1534
1625
|
// collapse
|
|
1535
1626
|
'has-children': hasChildItems,
|
|
1536
1627
|
'collapsed': isCollapsed
|
|
1537
1628
|
}),
|
|
1538
|
-
draggable: !
|
|
1539
|
-
onDragStart: !
|
|
1629
|
+
draggable: !isItemDraggable ? undefined : editingItem !== item.id && "true",
|
|
1630
|
+
onDragStart: !isItemDraggable ? undefined : function (e) {
|
|
1540
1631
|
return dragHandlers.handleDragStart(e, index);
|
|
1541
1632
|
},
|
|
1542
|
-
onDragOver: !
|
|
1543
|
-
onDragEnd: !
|
|
1544
|
-
onTouchStart: !
|
|
1633
|
+
onDragOver: !isItemDraggable ? undefined : dragHandlers.handleDragOver,
|
|
1634
|
+
onDragEnd: !isItemDraggable ? undefined : dragHandlers.handleDragEnd,
|
|
1635
|
+
onTouchStart: !isItemDraggable ? undefined : function (e) {
|
|
1545
1636
|
return dragHandlers.handleDragStart(e, index);
|
|
1546
1637
|
},
|
|
1547
|
-
onTouchMove: !
|
|
1548
|
-
onTouchEnd: !
|
|
1638
|
+
onTouchMove: !isItemDraggable ? undefined : dragHandlers.handleDragOver,
|
|
1639
|
+
onTouchEnd: !isItemDraggable ? undefined : dragHandlers.handleDragEnd,
|
|
1549
1640
|
style: itemStyle,
|
|
1550
1641
|
onDoubleClick: function onDoubleClick() {
|
|
1551
1642
|
return handleDoubleClick(item);
|
|
1552
1643
|
}
|
|
1553
1644
|
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
|
1554
1645
|
className: "".concat(prefix, "-draggable-list__itemcontent")
|
|
1555
|
-
}, renderOption ? renderOption(item, "".concat(prefix, "-draggable-list__handle"), index) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null,
|
|
1646
|
+
}, renderOption ? renderOption(item, isItemDraggable ? "".concat(prefix, "-draggable-list__handle") : '', index) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, isItemDraggable && !handleHide ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", {
|
|
1556
1647
|
className: "".concat(prefix, "-draggable-list__handle ").concat(handlePos !== null && handlePos !== void 0 ? handlePos : 'left'),
|
|
1557
1648
|
draggable: dragMode === 'handle',
|
|
1558
1649
|
dangerouslySetInnerHTML: {
|
|
@@ -12,6 +12,7 @@ export declare type DynamicFieldsProps = {
|
|
|
12
12
|
label?: React.ReactNode | string;
|
|
13
13
|
data: DynamicFieldsValueProps | null;
|
|
14
14
|
maxFields?: any;
|
|
15
|
+
defaultRows?: number;
|
|
15
16
|
confirmText?: string;
|
|
16
17
|
doNotRemoveDom?: boolean;
|
|
17
18
|
iconAddBefore?: React.ReactNode | string;
|