@almadar/ui 4.50.14 → 4.50.16
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/dist/avl/index.cjs +152 -79
- package/dist/avl/index.js +153 -80
- package/dist/components/index.cjs +152 -79
- package/dist/components/index.js +153 -80
- package/dist/providers/index.cjs +152 -79
- package/dist/providers/index.js +153 -80
- package/dist/runtime/index.cjs +152 -79
- package/dist/runtime/index.js +153 -80
- package/package.json +1 -1
|
@@ -20090,11 +20090,32 @@ function useDataDnd(args) {
|
|
|
20090
20090
|
const eventBus = useEventBus();
|
|
20091
20091
|
const parentRoot = React75__namespace.default.useContext(RootCtx);
|
|
20092
20092
|
const isRoot = enabled && parentRoot === null;
|
|
20093
|
-
const
|
|
20094
|
-
const
|
|
20095
|
-
React75__namespace.default.
|
|
20096
|
-
|
|
20097
|
-
|
|
20093
|
+
const zoneId = React75__namespace.default.useId();
|
|
20094
|
+
const ownGroup = dragGroup ?? accepts ?? zoneId;
|
|
20095
|
+
const [optimisticOrders, setOptimisticOrders] = React75__namespace.default.useState(() => /* @__PURE__ */ new Map());
|
|
20096
|
+
const optimisticOrdersRef = React75__namespace.default.useRef(optimisticOrders);
|
|
20097
|
+
optimisticOrdersRef.current = optimisticOrders;
|
|
20098
|
+
const clearOptimisticOrder = React75__namespace.default.useCallback((group) => {
|
|
20099
|
+
setOptimisticOrders((prev) => {
|
|
20100
|
+
if (!prev.has(group)) return prev;
|
|
20101
|
+
const next = new Map(prev);
|
|
20102
|
+
next.delete(group);
|
|
20103
|
+
return next;
|
|
20104
|
+
});
|
|
20105
|
+
}, []);
|
|
20106
|
+
const sharedOptimistic = isRoot ? optimisticOrders : parentRoot?.optimisticOrders ?? /* @__PURE__ */ new Map();
|
|
20107
|
+
const optimisticEntry = sharedOptimistic.get(ownGroup);
|
|
20108
|
+
const orderedItems = optimisticEntry ?? items;
|
|
20109
|
+
if (isZone && enabled) {
|
|
20110
|
+
dndLog.debug("hook:render", {
|
|
20111
|
+
group: ownGroup,
|
|
20112
|
+
isRoot,
|
|
20113
|
+
itemsLen: items.length,
|
|
20114
|
+
optimisticEntryLen: optimisticEntry ? optimisticEntry.length : null,
|
|
20115
|
+
orderedLen: orderedItems.length,
|
|
20116
|
+
sharedKeys: Array.from(sharedOptimistic.keys())
|
|
20117
|
+
});
|
|
20118
|
+
}
|
|
20098
20119
|
const itemIdsSignature = orderedItems.map((it, idx) => {
|
|
20099
20120
|
const raw = it[dndItemIdField];
|
|
20100
20121
|
return String(raw ?? `__idx_${idx}`);
|
|
@@ -20107,6 +20128,15 @@ function useDataDnd(args) {
|
|
|
20107
20128
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
20108
20129
|
[itemIdsSignature]
|
|
20109
20130
|
);
|
|
20131
|
+
const itemsContentSig = items.map((it, idx) => String(it[dndItemIdField] ?? `__${idx}`)).join("|");
|
|
20132
|
+
React75__namespace.default.useEffect(() => {
|
|
20133
|
+
const root = isRoot ? null : parentRoot;
|
|
20134
|
+
if (root) {
|
|
20135
|
+
root.clearOptimisticOrder(ownGroup);
|
|
20136
|
+
} else {
|
|
20137
|
+
clearOptimisticOrder(ownGroup);
|
|
20138
|
+
}
|
|
20139
|
+
}, [itemsContentSig, ownGroup]);
|
|
20110
20140
|
const zonesRef = React75__namespace.default.useRef(/* @__PURE__ */ new Map());
|
|
20111
20141
|
const registerZone = React75__namespace.default.useCallback((zoneId2, meta2) => {
|
|
20112
20142
|
zonesRef.current.set(zoneId2, meta2);
|
|
@@ -20116,11 +20146,9 @@ function useDataDnd(args) {
|
|
|
20116
20146
|
}, []);
|
|
20117
20147
|
const [activeDrag, setActiveDrag] = React75__namespace.default.useState(null);
|
|
20118
20148
|
const [overZoneGroup, setOverZoneGroup] = React75__namespace.default.useState(null);
|
|
20119
|
-
const zoneId = React75__namespace.default.useId();
|
|
20120
|
-
const ownGroup = dragGroup ?? accepts ?? zoneId;
|
|
20121
20149
|
const meta = React75__namespace.default.useMemo(
|
|
20122
|
-
() => ({ group: ownGroup, dropEvent, reorderEvent, itemIds }),
|
|
20123
|
-
[ownGroup, dropEvent, reorderEvent, itemIds]
|
|
20150
|
+
() => ({ group: ownGroup, dropEvent, reorderEvent, itemIds, rawItems: items, idField: dndItemIdField }),
|
|
20151
|
+
[ownGroup, dropEvent, reorderEvent, itemIds, items, dndItemIdField]
|
|
20124
20152
|
);
|
|
20125
20153
|
React75__namespace.default.useEffect(() => {
|
|
20126
20154
|
const target = isRoot ? null : parentRoot;
|
|
@@ -20167,7 +20195,7 @@ function useDataDnd(args) {
|
|
|
20167
20195
|
},
|
|
20168
20196
|
[]
|
|
20169
20197
|
);
|
|
20170
|
-
|
|
20198
|
+
React75__namespace.default.useCallback(
|
|
20171
20199
|
(group) => {
|
|
20172
20200
|
for (const z of zonesRef.current.values()) {
|
|
20173
20201
|
if (z.group === group) return z;
|
|
@@ -20179,81 +20207,76 @@ function useDataDnd(args) {
|
|
|
20179
20207
|
const handleDragEnd = React75__namespace.default.useCallback(
|
|
20180
20208
|
(event) => {
|
|
20181
20209
|
const { active, over } = event;
|
|
20182
|
-
const
|
|
20210
|
+
const activeIdStr = String(active.id);
|
|
20183
20211
|
dndLog.debug("dragEnd:received", {
|
|
20184
20212
|
activeId: active.id,
|
|
20185
20213
|
overId: over?.id,
|
|
20186
|
-
overData: over?.data?.current
|
|
20187
|
-
zones: allZones
|
|
20214
|
+
overData: over?.data?.current
|
|
20188
20215
|
});
|
|
20189
|
-
|
|
20190
|
-
|
|
20191
|
-
|
|
20192
|
-
|
|
20193
|
-
const
|
|
20194
|
-
|
|
20195
|
-
|
|
20196
|
-
|
|
20197
|
-
|
|
20198
|
-
|
|
20199
|
-
|
|
20200
|
-
|
|
20201
|
-
|
|
20202
|
-
|
|
20203
|
-
|
|
20204
|
-
|
|
20205
|
-
|
|
20206
|
-
if (!
|
|
20207
|
-
dndLog.warn("dragEnd:abort:
|
|
20216
|
+
let sourceMeta;
|
|
20217
|
+
let oldIndex = -1;
|
|
20218
|
+
let targetMeta;
|
|
20219
|
+
let newIndex = -1;
|
|
20220
|
+
for (const m of zonesRef.current.values()) {
|
|
20221
|
+
const rawIdx = m.rawItems.findIndex((it) => String(it[m.idField]) === activeIdStr);
|
|
20222
|
+
if (rawIdx >= 0) {
|
|
20223
|
+
sourceMeta = m;
|
|
20224
|
+
oldIndex = rawIdx;
|
|
20225
|
+
}
|
|
20226
|
+
const currentItems = optimisticOrdersRef.current.get(m.group) ?? m.rawItems;
|
|
20227
|
+
const curIdx = currentItems.findIndex((it) => String(it[m.idField]) === activeIdStr);
|
|
20228
|
+
if (curIdx >= 0) {
|
|
20229
|
+
targetMeta = m;
|
|
20230
|
+
newIndex = curIdx;
|
|
20231
|
+
}
|
|
20232
|
+
}
|
|
20233
|
+
if (!sourceMeta || !targetMeta) {
|
|
20234
|
+
dndLog.warn("dragEnd:abort:no-zone-resolved", { activeId: active.id, hasSource: !!sourceMeta, hasTarget: !!targetMeta });
|
|
20208
20235
|
return;
|
|
20209
20236
|
}
|
|
20210
|
-
if (
|
|
20211
|
-
if (
|
|
20212
|
-
const
|
|
20213
|
-
const evt = `UI:${targetZone.dropEvent}`;
|
|
20237
|
+
if (sourceMeta.group !== targetMeta.group) {
|
|
20238
|
+
if (targetMeta.dropEvent) {
|
|
20239
|
+
const evt = `UI:${targetMeta.dropEvent}`;
|
|
20214
20240
|
dndLog.info("dragEnd:cross-container:emit", {
|
|
20215
20241
|
event: evt,
|
|
20216
|
-
id:
|
|
20217
|
-
sourceGroup:
|
|
20218
|
-
targetGroup:
|
|
20219
|
-
newIndex
|
|
20242
|
+
id: activeIdStr,
|
|
20243
|
+
sourceGroup: sourceMeta.group,
|
|
20244
|
+
targetGroup: targetMeta.group,
|
|
20245
|
+
newIndex
|
|
20220
20246
|
});
|
|
20221
20247
|
eventBus.emit(evt, {
|
|
20222
|
-
id:
|
|
20223
|
-
sourceGroup:
|
|
20224
|
-
targetGroup:
|
|
20225
|
-
newIndex
|
|
20248
|
+
id: activeIdStr,
|
|
20249
|
+
sourceGroup: sourceMeta.group,
|
|
20250
|
+
targetGroup: targetMeta.group,
|
|
20251
|
+
newIndex
|
|
20226
20252
|
});
|
|
20227
20253
|
} else {
|
|
20228
|
-
dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup:
|
|
20254
|
+
dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup: targetMeta.group });
|
|
20229
20255
|
}
|
|
20230
20256
|
return;
|
|
20231
20257
|
}
|
|
20232
|
-
|
|
20233
|
-
|
|
20234
|
-
|
|
20235
|
-
if (sourceZone.group === ownGroup) {
|
|
20236
|
-
const reordered = sortable.arrayMove(orderedItems, oldIndex, newIndex);
|
|
20237
|
-
setLocalOrder(reordered);
|
|
20258
|
+
if (oldIndex === newIndex) {
|
|
20259
|
+
dndLog.debug("dragEnd:reorder:no-op", { sourceGroup: sourceMeta.group, oldIndex });
|
|
20260
|
+
return;
|
|
20238
20261
|
}
|
|
20239
|
-
if (
|
|
20240
|
-
const evt = `UI:${
|
|
20262
|
+
if (sourceMeta.reorderEvent) {
|
|
20263
|
+
const evt = `UI:${sourceMeta.reorderEvent}`;
|
|
20241
20264
|
dndLog.info("dragEnd:reorder:emit", {
|
|
20242
20265
|
event: evt,
|
|
20243
|
-
id:
|
|
20266
|
+
id: activeIdStr,
|
|
20244
20267
|
oldIndex,
|
|
20245
20268
|
newIndex
|
|
20246
20269
|
});
|
|
20247
20270
|
eventBus.emit(evt, {
|
|
20248
|
-
id:
|
|
20271
|
+
id: activeIdStr,
|
|
20249
20272
|
oldIndex,
|
|
20250
20273
|
newIndex
|
|
20251
20274
|
});
|
|
20252
20275
|
} else {
|
|
20253
|
-
dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup:
|
|
20276
|
+
dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup: sourceMeta.group });
|
|
20254
20277
|
}
|
|
20255
20278
|
},
|
|
20256
|
-
[
|
|
20279
|
+
[eventBus]
|
|
20257
20280
|
);
|
|
20258
20281
|
const sortableData = React75__namespace.default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
|
|
20259
20282
|
const SortableItem = React75__namespace.default.useCallback(
|
|
@@ -20314,30 +20337,20 @@ function useDataDnd(args) {
|
|
|
20314
20337
|
React75__namespace.default.useEffect(() => {
|
|
20315
20338
|
dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
|
|
20316
20339
|
}, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
|
|
20317
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
20340
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
20318
20341
|
exports.Box,
|
|
20319
20342
|
{
|
|
20320
20343
|
ref: setNodeRef,
|
|
20321
20344
|
"data-dnd-zone": ownGroup,
|
|
20322
20345
|
"data-dnd-is-over": isThisZoneOver ? "true" : "false",
|
|
20323
|
-
className: isThisZoneOver ? "ring-2 ring-primary ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
|
|
20324
|
-
children
|
|
20325
|
-
children,
|
|
20326
|
-
showForeignPlaceholder ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
20327
|
-
exports.Box,
|
|
20328
|
-
{
|
|
20329
|
-
"data-dnd-placeholder": true,
|
|
20330
|
-
style: { height: activeDrag2.height },
|
|
20331
|
-
className: "border-2 border-dashed border-primary/60 bg-primary/5 rounded-md my-1 transition-all"
|
|
20332
|
-
}
|
|
20333
|
-
) : null
|
|
20334
|
-
]
|
|
20346
|
+
className: isThisZoneOver ? "ring-2 ring-primary/40 ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
|
|
20347
|
+
children
|
|
20335
20348
|
}
|
|
20336
20349
|
);
|
|
20337
20350
|
};
|
|
20338
20351
|
const rootContextValue = React75__namespace.default.useMemo(
|
|
20339
|
-
() => ({ registerZone, unregisterZone, activeDrag, overZoneGroup }),
|
|
20340
|
-
[registerZone, unregisterZone, activeDrag, overZoneGroup]
|
|
20352
|
+
() => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
|
|
20353
|
+
[registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
|
|
20341
20354
|
);
|
|
20342
20355
|
const handleDragStart = React75__namespace.default.useCallback((event) => {
|
|
20343
20356
|
const sourceZone = findZoneByItem(event.active.id);
|
|
@@ -20359,13 +20372,73 @@ function useDataDnd(args) {
|
|
|
20359
20372
|
});
|
|
20360
20373
|
}, [findZoneByItem, isRoot, zoneId]);
|
|
20361
20374
|
const handleDragOver = React75__namespace.default.useCallback((event) => {
|
|
20362
|
-
const
|
|
20363
|
-
const
|
|
20364
|
-
|
|
20365
|
-
|
|
20366
|
-
|
|
20367
|
-
|
|
20368
|
-
|
|
20375
|
+
const { active, over } = event;
|
|
20376
|
+
const overData = over?.data?.current;
|
|
20377
|
+
const overGroup = overData?.dndGroup ?? null;
|
|
20378
|
+
setOverZoneGroup(overGroup);
|
|
20379
|
+
if (!over || !overGroup) return;
|
|
20380
|
+
const activeIdStr = String(active.id);
|
|
20381
|
+
let sourceMeta;
|
|
20382
|
+
let sourceGroup;
|
|
20383
|
+
for (const m of zonesRef.current.values()) {
|
|
20384
|
+
const currentItems = optimisticOrdersRef.current.get(m.group) ?? m.rawItems;
|
|
20385
|
+
const found = currentItems.find((it) => String(it[m.idField]) === activeIdStr);
|
|
20386
|
+
if (found) {
|
|
20387
|
+
sourceMeta = m;
|
|
20388
|
+
sourceGroup = m.group;
|
|
20389
|
+
break;
|
|
20390
|
+
}
|
|
20391
|
+
}
|
|
20392
|
+
if (!sourceMeta || !sourceGroup) {
|
|
20393
|
+
dndLog.debug("dragOver:no-source-zone", { activeId: active.id });
|
|
20394
|
+
return;
|
|
20395
|
+
}
|
|
20396
|
+
let targetMeta;
|
|
20397
|
+
for (const m of zonesRef.current.values()) {
|
|
20398
|
+
if (m.group === overGroup) {
|
|
20399
|
+
targetMeta = m;
|
|
20400
|
+
break;
|
|
20401
|
+
}
|
|
20402
|
+
}
|
|
20403
|
+
if (!targetMeta) {
|
|
20404
|
+
dndLog.debug("dragOver:no-target-zone", { overGroup });
|
|
20405
|
+
return;
|
|
20406
|
+
}
|
|
20407
|
+
if (sourceGroup === overGroup) {
|
|
20408
|
+
setOptimisticOrders((prev) => {
|
|
20409
|
+
const currentItems = prev.get(sourceGroup) ?? sourceMeta.rawItems;
|
|
20410
|
+
const oldIndex = currentItems.findIndex((it) => String(it[sourceMeta.idField]) === activeIdStr);
|
|
20411
|
+
const newIndex = currentItems.findIndex((it) => String(it[sourceMeta.idField]) === String(over.id));
|
|
20412
|
+
if (oldIndex === -1 || newIndex === -1 || oldIndex === newIndex) return prev;
|
|
20413
|
+
const reordered = sortable.arrayMove([...currentItems], oldIndex, newIndex);
|
|
20414
|
+
const next = new Map(prev);
|
|
20415
|
+
next.set(sourceGroup, reordered);
|
|
20416
|
+
return next;
|
|
20417
|
+
});
|
|
20418
|
+
return;
|
|
20419
|
+
}
|
|
20420
|
+
setOptimisticOrders((prev) => {
|
|
20421
|
+
const currentSource = prev.get(sourceGroup) ?? sourceMeta.rawItems;
|
|
20422
|
+
const currentTarget = prev.get(overGroup) ?? targetMeta.rawItems;
|
|
20423
|
+
const activeItem = currentSource.find((it) => String(it[sourceMeta.idField]) === activeIdStr);
|
|
20424
|
+
if (!activeItem) return prev;
|
|
20425
|
+
if (currentTarget.some((it) => String(it[targetMeta.idField]) === activeIdStr)) {
|
|
20426
|
+
return prev;
|
|
20427
|
+
}
|
|
20428
|
+
const newSource = currentSource.filter((it) => String(it[sourceMeta.idField]) !== activeIdStr);
|
|
20429
|
+
const overIdStr = String(over.id);
|
|
20430
|
+
const overIndex = currentTarget.findIndex((it) => String(it[targetMeta.idField]) === overIdStr);
|
|
20431
|
+
const insertAt = overIndex >= 0 ? overIndex : currentTarget.length;
|
|
20432
|
+
const newTarget = [
|
|
20433
|
+
...currentTarget.slice(0, insertAt),
|
|
20434
|
+
activeItem,
|
|
20435
|
+
...currentTarget.slice(insertAt)
|
|
20436
|
+
];
|
|
20437
|
+
const next = new Map(prev);
|
|
20438
|
+
next.set(sourceGroup, newSource);
|
|
20439
|
+
next.set(overGroup, newTarget);
|
|
20440
|
+
dndLog.debug("dragOver:cross-zone:splice", { sourceGroup, overGroup, sourceLen: newSource.length, targetLen: newTarget.length, insertAt });
|
|
20441
|
+
return next;
|
|
20369
20442
|
});
|
|
20370
20443
|
}, []);
|
|
20371
20444
|
const handleDragCancel = React75__namespace.default.useCallback((event) => {
|
package/dist/components/index.js
CHANGED
|
@@ -36,7 +36,7 @@ import langGo from 'react-syntax-highlighter/dist/esm/languages/prism/go.js';
|
|
|
36
36
|
import langGraphql from 'react-syntax-highlighter/dist/esm/languages/prism/graphql.js';
|
|
37
37
|
import { isInlineTrait } from '@almadar/core';
|
|
38
38
|
import { useSensors, useSensor, PointerSensor, KeyboardSensor, pointerWithin, rectIntersection, closestCorners, DndContext, useDroppable } from '@dnd-kit/core';
|
|
39
|
-
import { sortableKeyboardCoordinates,
|
|
39
|
+
import { sortableKeyboardCoordinates, useSortable, arrayMove, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
|
40
40
|
import { CSS } from '@dnd-kit/utilities';
|
|
41
41
|
import { Handle, Position } from '@xyflow/react';
|
|
42
42
|
import { useUISlots } from '@almadar/ui/context';
|
|
@@ -20044,11 +20044,32 @@ function useDataDnd(args) {
|
|
|
20044
20044
|
const eventBus = useEventBus();
|
|
20045
20045
|
const parentRoot = React75__default.useContext(RootCtx);
|
|
20046
20046
|
const isRoot = enabled && parentRoot === null;
|
|
20047
|
-
const
|
|
20048
|
-
const
|
|
20049
|
-
React75__default.
|
|
20050
|
-
|
|
20051
|
-
|
|
20047
|
+
const zoneId = React75__default.useId();
|
|
20048
|
+
const ownGroup = dragGroup ?? accepts ?? zoneId;
|
|
20049
|
+
const [optimisticOrders, setOptimisticOrders] = React75__default.useState(() => /* @__PURE__ */ new Map());
|
|
20050
|
+
const optimisticOrdersRef = React75__default.useRef(optimisticOrders);
|
|
20051
|
+
optimisticOrdersRef.current = optimisticOrders;
|
|
20052
|
+
const clearOptimisticOrder = React75__default.useCallback((group) => {
|
|
20053
|
+
setOptimisticOrders((prev) => {
|
|
20054
|
+
if (!prev.has(group)) return prev;
|
|
20055
|
+
const next = new Map(prev);
|
|
20056
|
+
next.delete(group);
|
|
20057
|
+
return next;
|
|
20058
|
+
});
|
|
20059
|
+
}, []);
|
|
20060
|
+
const sharedOptimistic = isRoot ? optimisticOrders : parentRoot?.optimisticOrders ?? /* @__PURE__ */ new Map();
|
|
20061
|
+
const optimisticEntry = sharedOptimistic.get(ownGroup);
|
|
20062
|
+
const orderedItems = optimisticEntry ?? items;
|
|
20063
|
+
if (isZone && enabled) {
|
|
20064
|
+
dndLog.debug("hook:render", {
|
|
20065
|
+
group: ownGroup,
|
|
20066
|
+
isRoot,
|
|
20067
|
+
itemsLen: items.length,
|
|
20068
|
+
optimisticEntryLen: optimisticEntry ? optimisticEntry.length : null,
|
|
20069
|
+
orderedLen: orderedItems.length,
|
|
20070
|
+
sharedKeys: Array.from(sharedOptimistic.keys())
|
|
20071
|
+
});
|
|
20072
|
+
}
|
|
20052
20073
|
const itemIdsSignature = orderedItems.map((it, idx) => {
|
|
20053
20074
|
const raw = it[dndItemIdField];
|
|
20054
20075
|
return String(raw ?? `__idx_${idx}`);
|
|
@@ -20061,6 +20082,15 @@ function useDataDnd(args) {
|
|
|
20061
20082
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
20062
20083
|
[itemIdsSignature]
|
|
20063
20084
|
);
|
|
20085
|
+
const itemsContentSig = items.map((it, idx) => String(it[dndItemIdField] ?? `__${idx}`)).join("|");
|
|
20086
|
+
React75__default.useEffect(() => {
|
|
20087
|
+
const root = isRoot ? null : parentRoot;
|
|
20088
|
+
if (root) {
|
|
20089
|
+
root.clearOptimisticOrder(ownGroup);
|
|
20090
|
+
} else {
|
|
20091
|
+
clearOptimisticOrder(ownGroup);
|
|
20092
|
+
}
|
|
20093
|
+
}, [itemsContentSig, ownGroup]);
|
|
20064
20094
|
const zonesRef = React75__default.useRef(/* @__PURE__ */ new Map());
|
|
20065
20095
|
const registerZone = React75__default.useCallback((zoneId2, meta2) => {
|
|
20066
20096
|
zonesRef.current.set(zoneId2, meta2);
|
|
@@ -20070,11 +20100,9 @@ function useDataDnd(args) {
|
|
|
20070
20100
|
}, []);
|
|
20071
20101
|
const [activeDrag, setActiveDrag] = React75__default.useState(null);
|
|
20072
20102
|
const [overZoneGroup, setOverZoneGroup] = React75__default.useState(null);
|
|
20073
|
-
const zoneId = React75__default.useId();
|
|
20074
|
-
const ownGroup = dragGroup ?? accepts ?? zoneId;
|
|
20075
20103
|
const meta = React75__default.useMemo(
|
|
20076
|
-
() => ({ group: ownGroup, dropEvent, reorderEvent, itemIds }),
|
|
20077
|
-
[ownGroup, dropEvent, reorderEvent, itemIds]
|
|
20104
|
+
() => ({ group: ownGroup, dropEvent, reorderEvent, itemIds, rawItems: items, idField: dndItemIdField }),
|
|
20105
|
+
[ownGroup, dropEvent, reorderEvent, itemIds, items, dndItemIdField]
|
|
20078
20106
|
);
|
|
20079
20107
|
React75__default.useEffect(() => {
|
|
20080
20108
|
const target = isRoot ? null : parentRoot;
|
|
@@ -20121,7 +20149,7 @@ function useDataDnd(args) {
|
|
|
20121
20149
|
},
|
|
20122
20150
|
[]
|
|
20123
20151
|
);
|
|
20124
|
-
|
|
20152
|
+
React75__default.useCallback(
|
|
20125
20153
|
(group) => {
|
|
20126
20154
|
for (const z of zonesRef.current.values()) {
|
|
20127
20155
|
if (z.group === group) return z;
|
|
@@ -20133,81 +20161,76 @@ function useDataDnd(args) {
|
|
|
20133
20161
|
const handleDragEnd = React75__default.useCallback(
|
|
20134
20162
|
(event) => {
|
|
20135
20163
|
const { active, over } = event;
|
|
20136
|
-
const
|
|
20164
|
+
const activeIdStr = String(active.id);
|
|
20137
20165
|
dndLog.debug("dragEnd:received", {
|
|
20138
20166
|
activeId: active.id,
|
|
20139
20167
|
overId: over?.id,
|
|
20140
|
-
overData: over?.data?.current
|
|
20141
|
-
zones: allZones
|
|
20168
|
+
overData: over?.data?.current
|
|
20142
20169
|
});
|
|
20143
|
-
|
|
20144
|
-
|
|
20145
|
-
|
|
20146
|
-
|
|
20147
|
-
const
|
|
20148
|
-
|
|
20149
|
-
|
|
20150
|
-
|
|
20151
|
-
|
|
20152
|
-
|
|
20153
|
-
|
|
20154
|
-
|
|
20155
|
-
|
|
20156
|
-
|
|
20157
|
-
|
|
20158
|
-
|
|
20159
|
-
|
|
20160
|
-
if (!
|
|
20161
|
-
dndLog.warn("dragEnd:abort:
|
|
20170
|
+
let sourceMeta;
|
|
20171
|
+
let oldIndex = -1;
|
|
20172
|
+
let targetMeta;
|
|
20173
|
+
let newIndex = -1;
|
|
20174
|
+
for (const m of zonesRef.current.values()) {
|
|
20175
|
+
const rawIdx = m.rawItems.findIndex((it) => String(it[m.idField]) === activeIdStr);
|
|
20176
|
+
if (rawIdx >= 0) {
|
|
20177
|
+
sourceMeta = m;
|
|
20178
|
+
oldIndex = rawIdx;
|
|
20179
|
+
}
|
|
20180
|
+
const currentItems = optimisticOrdersRef.current.get(m.group) ?? m.rawItems;
|
|
20181
|
+
const curIdx = currentItems.findIndex((it) => String(it[m.idField]) === activeIdStr);
|
|
20182
|
+
if (curIdx >= 0) {
|
|
20183
|
+
targetMeta = m;
|
|
20184
|
+
newIndex = curIdx;
|
|
20185
|
+
}
|
|
20186
|
+
}
|
|
20187
|
+
if (!sourceMeta || !targetMeta) {
|
|
20188
|
+
dndLog.warn("dragEnd:abort:no-zone-resolved", { activeId: active.id, hasSource: !!sourceMeta, hasTarget: !!targetMeta });
|
|
20162
20189
|
return;
|
|
20163
20190
|
}
|
|
20164
|
-
if (
|
|
20165
|
-
if (
|
|
20166
|
-
const
|
|
20167
|
-
const evt = `UI:${targetZone.dropEvent}`;
|
|
20191
|
+
if (sourceMeta.group !== targetMeta.group) {
|
|
20192
|
+
if (targetMeta.dropEvent) {
|
|
20193
|
+
const evt = `UI:${targetMeta.dropEvent}`;
|
|
20168
20194
|
dndLog.info("dragEnd:cross-container:emit", {
|
|
20169
20195
|
event: evt,
|
|
20170
|
-
id:
|
|
20171
|
-
sourceGroup:
|
|
20172
|
-
targetGroup:
|
|
20173
|
-
newIndex
|
|
20196
|
+
id: activeIdStr,
|
|
20197
|
+
sourceGroup: sourceMeta.group,
|
|
20198
|
+
targetGroup: targetMeta.group,
|
|
20199
|
+
newIndex
|
|
20174
20200
|
});
|
|
20175
20201
|
eventBus.emit(evt, {
|
|
20176
|
-
id:
|
|
20177
|
-
sourceGroup:
|
|
20178
|
-
targetGroup:
|
|
20179
|
-
newIndex
|
|
20202
|
+
id: activeIdStr,
|
|
20203
|
+
sourceGroup: sourceMeta.group,
|
|
20204
|
+
targetGroup: targetMeta.group,
|
|
20205
|
+
newIndex
|
|
20180
20206
|
});
|
|
20181
20207
|
} else {
|
|
20182
|
-
dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup:
|
|
20208
|
+
dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup: targetMeta.group });
|
|
20183
20209
|
}
|
|
20184
20210
|
return;
|
|
20185
20211
|
}
|
|
20186
|
-
|
|
20187
|
-
|
|
20188
|
-
|
|
20189
|
-
if (sourceZone.group === ownGroup) {
|
|
20190
|
-
const reordered = arrayMove(orderedItems, oldIndex, newIndex);
|
|
20191
|
-
setLocalOrder(reordered);
|
|
20212
|
+
if (oldIndex === newIndex) {
|
|
20213
|
+
dndLog.debug("dragEnd:reorder:no-op", { sourceGroup: sourceMeta.group, oldIndex });
|
|
20214
|
+
return;
|
|
20192
20215
|
}
|
|
20193
|
-
if (
|
|
20194
|
-
const evt = `UI:${
|
|
20216
|
+
if (sourceMeta.reorderEvent) {
|
|
20217
|
+
const evt = `UI:${sourceMeta.reorderEvent}`;
|
|
20195
20218
|
dndLog.info("dragEnd:reorder:emit", {
|
|
20196
20219
|
event: evt,
|
|
20197
|
-
id:
|
|
20220
|
+
id: activeIdStr,
|
|
20198
20221
|
oldIndex,
|
|
20199
20222
|
newIndex
|
|
20200
20223
|
});
|
|
20201
20224
|
eventBus.emit(evt, {
|
|
20202
|
-
id:
|
|
20225
|
+
id: activeIdStr,
|
|
20203
20226
|
oldIndex,
|
|
20204
20227
|
newIndex
|
|
20205
20228
|
});
|
|
20206
20229
|
} else {
|
|
20207
|
-
dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup:
|
|
20230
|
+
dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup: sourceMeta.group });
|
|
20208
20231
|
}
|
|
20209
20232
|
},
|
|
20210
|
-
[
|
|
20233
|
+
[eventBus]
|
|
20211
20234
|
);
|
|
20212
20235
|
const sortableData = React75__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
|
|
20213
20236
|
const SortableItem = React75__default.useCallback(
|
|
@@ -20268,30 +20291,20 @@ function useDataDnd(args) {
|
|
|
20268
20291
|
React75__default.useEffect(() => {
|
|
20269
20292
|
dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
|
|
20270
20293
|
}, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
|
|
20271
|
-
return /* @__PURE__ */
|
|
20294
|
+
return /* @__PURE__ */ jsx(
|
|
20272
20295
|
Box,
|
|
20273
20296
|
{
|
|
20274
20297
|
ref: setNodeRef,
|
|
20275
20298
|
"data-dnd-zone": ownGroup,
|
|
20276
20299
|
"data-dnd-is-over": isThisZoneOver ? "true" : "false",
|
|
20277
|
-
className: isThisZoneOver ? "ring-2 ring-primary ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
|
|
20278
|
-
children
|
|
20279
|
-
children,
|
|
20280
|
-
showForeignPlaceholder ? /* @__PURE__ */ jsx(
|
|
20281
|
-
Box,
|
|
20282
|
-
{
|
|
20283
|
-
"data-dnd-placeholder": true,
|
|
20284
|
-
style: { height: activeDrag2.height },
|
|
20285
|
-
className: "border-2 border-dashed border-primary/60 bg-primary/5 rounded-md my-1 transition-all"
|
|
20286
|
-
}
|
|
20287
|
-
) : null
|
|
20288
|
-
]
|
|
20300
|
+
className: isThisZoneOver ? "ring-2 ring-primary/40 ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
|
|
20301
|
+
children
|
|
20289
20302
|
}
|
|
20290
20303
|
);
|
|
20291
20304
|
};
|
|
20292
20305
|
const rootContextValue = React75__default.useMemo(
|
|
20293
|
-
() => ({ registerZone, unregisterZone, activeDrag, overZoneGroup }),
|
|
20294
|
-
[registerZone, unregisterZone, activeDrag, overZoneGroup]
|
|
20306
|
+
() => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
|
|
20307
|
+
[registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
|
|
20295
20308
|
);
|
|
20296
20309
|
const handleDragStart = React75__default.useCallback((event) => {
|
|
20297
20310
|
const sourceZone = findZoneByItem(event.active.id);
|
|
@@ -20313,13 +20326,73 @@ function useDataDnd(args) {
|
|
|
20313
20326
|
});
|
|
20314
20327
|
}, [findZoneByItem, isRoot, zoneId]);
|
|
20315
20328
|
const handleDragOver = React75__default.useCallback((event) => {
|
|
20316
|
-
const
|
|
20317
|
-
const
|
|
20318
|
-
|
|
20319
|
-
|
|
20320
|
-
|
|
20321
|
-
|
|
20322
|
-
|
|
20329
|
+
const { active, over } = event;
|
|
20330
|
+
const overData = over?.data?.current;
|
|
20331
|
+
const overGroup = overData?.dndGroup ?? null;
|
|
20332
|
+
setOverZoneGroup(overGroup);
|
|
20333
|
+
if (!over || !overGroup) return;
|
|
20334
|
+
const activeIdStr = String(active.id);
|
|
20335
|
+
let sourceMeta;
|
|
20336
|
+
let sourceGroup;
|
|
20337
|
+
for (const m of zonesRef.current.values()) {
|
|
20338
|
+
const currentItems = optimisticOrdersRef.current.get(m.group) ?? m.rawItems;
|
|
20339
|
+
const found = currentItems.find((it) => String(it[m.idField]) === activeIdStr);
|
|
20340
|
+
if (found) {
|
|
20341
|
+
sourceMeta = m;
|
|
20342
|
+
sourceGroup = m.group;
|
|
20343
|
+
break;
|
|
20344
|
+
}
|
|
20345
|
+
}
|
|
20346
|
+
if (!sourceMeta || !sourceGroup) {
|
|
20347
|
+
dndLog.debug("dragOver:no-source-zone", { activeId: active.id });
|
|
20348
|
+
return;
|
|
20349
|
+
}
|
|
20350
|
+
let targetMeta;
|
|
20351
|
+
for (const m of zonesRef.current.values()) {
|
|
20352
|
+
if (m.group === overGroup) {
|
|
20353
|
+
targetMeta = m;
|
|
20354
|
+
break;
|
|
20355
|
+
}
|
|
20356
|
+
}
|
|
20357
|
+
if (!targetMeta) {
|
|
20358
|
+
dndLog.debug("dragOver:no-target-zone", { overGroup });
|
|
20359
|
+
return;
|
|
20360
|
+
}
|
|
20361
|
+
if (sourceGroup === overGroup) {
|
|
20362
|
+
setOptimisticOrders((prev) => {
|
|
20363
|
+
const currentItems = prev.get(sourceGroup) ?? sourceMeta.rawItems;
|
|
20364
|
+
const oldIndex = currentItems.findIndex((it) => String(it[sourceMeta.idField]) === activeIdStr);
|
|
20365
|
+
const newIndex = currentItems.findIndex((it) => String(it[sourceMeta.idField]) === String(over.id));
|
|
20366
|
+
if (oldIndex === -1 || newIndex === -1 || oldIndex === newIndex) return prev;
|
|
20367
|
+
const reordered = arrayMove([...currentItems], oldIndex, newIndex);
|
|
20368
|
+
const next = new Map(prev);
|
|
20369
|
+
next.set(sourceGroup, reordered);
|
|
20370
|
+
return next;
|
|
20371
|
+
});
|
|
20372
|
+
return;
|
|
20373
|
+
}
|
|
20374
|
+
setOptimisticOrders((prev) => {
|
|
20375
|
+
const currentSource = prev.get(sourceGroup) ?? sourceMeta.rawItems;
|
|
20376
|
+
const currentTarget = prev.get(overGroup) ?? targetMeta.rawItems;
|
|
20377
|
+
const activeItem = currentSource.find((it) => String(it[sourceMeta.idField]) === activeIdStr);
|
|
20378
|
+
if (!activeItem) return prev;
|
|
20379
|
+
if (currentTarget.some((it) => String(it[targetMeta.idField]) === activeIdStr)) {
|
|
20380
|
+
return prev;
|
|
20381
|
+
}
|
|
20382
|
+
const newSource = currentSource.filter((it) => String(it[sourceMeta.idField]) !== activeIdStr);
|
|
20383
|
+
const overIdStr = String(over.id);
|
|
20384
|
+
const overIndex = currentTarget.findIndex((it) => String(it[targetMeta.idField]) === overIdStr);
|
|
20385
|
+
const insertAt = overIndex >= 0 ? overIndex : currentTarget.length;
|
|
20386
|
+
const newTarget = [
|
|
20387
|
+
...currentTarget.slice(0, insertAt),
|
|
20388
|
+
activeItem,
|
|
20389
|
+
...currentTarget.slice(insertAt)
|
|
20390
|
+
];
|
|
20391
|
+
const next = new Map(prev);
|
|
20392
|
+
next.set(sourceGroup, newSource);
|
|
20393
|
+
next.set(overGroup, newTarget);
|
|
20394
|
+
dndLog.debug("dragOver:cross-zone:splice", { sourceGroup, overGroup, sourceLen: newSource.length, targetLen: newTarget.length, insertAt });
|
|
20395
|
+
return next;
|
|
20323
20396
|
});
|
|
20324
20397
|
}, []);
|
|
20325
20398
|
const handleDragCancel = React75__default.useCallback((event) => {
|