@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
package/dist/runtime/index.cjs
CHANGED
|
@@ -21104,11 +21104,32 @@ function useDataDnd(args) {
|
|
|
21104
21104
|
const eventBus = useEventBus();
|
|
21105
21105
|
const parentRoot = React80__namespace.default.useContext(RootCtx);
|
|
21106
21106
|
const isRoot = enabled && parentRoot === null;
|
|
21107
|
-
const
|
|
21108
|
-
const
|
|
21109
|
-
React80__namespace.default.
|
|
21110
|
-
|
|
21111
|
-
|
|
21107
|
+
const zoneId = React80__namespace.default.useId();
|
|
21108
|
+
const ownGroup = dragGroup ?? accepts ?? zoneId;
|
|
21109
|
+
const [optimisticOrders, setOptimisticOrders] = React80__namespace.default.useState(() => /* @__PURE__ */ new Map());
|
|
21110
|
+
const optimisticOrdersRef = React80__namespace.default.useRef(optimisticOrders);
|
|
21111
|
+
optimisticOrdersRef.current = optimisticOrders;
|
|
21112
|
+
const clearOptimisticOrder = React80__namespace.default.useCallback((group) => {
|
|
21113
|
+
setOptimisticOrders((prev) => {
|
|
21114
|
+
if (!prev.has(group)) return prev;
|
|
21115
|
+
const next = new Map(prev);
|
|
21116
|
+
next.delete(group);
|
|
21117
|
+
return next;
|
|
21118
|
+
});
|
|
21119
|
+
}, []);
|
|
21120
|
+
const sharedOptimistic = isRoot ? optimisticOrders : parentRoot?.optimisticOrders ?? /* @__PURE__ */ new Map();
|
|
21121
|
+
const optimisticEntry = sharedOptimistic.get(ownGroup);
|
|
21122
|
+
const orderedItems = optimisticEntry ?? items;
|
|
21123
|
+
if (isZone && enabled) {
|
|
21124
|
+
dndLog.debug("hook:render", {
|
|
21125
|
+
group: ownGroup,
|
|
21126
|
+
isRoot,
|
|
21127
|
+
itemsLen: items.length,
|
|
21128
|
+
optimisticEntryLen: optimisticEntry ? optimisticEntry.length : null,
|
|
21129
|
+
orderedLen: orderedItems.length,
|
|
21130
|
+
sharedKeys: Array.from(sharedOptimistic.keys())
|
|
21131
|
+
});
|
|
21132
|
+
}
|
|
21112
21133
|
const itemIdsSignature = orderedItems.map((it, idx) => {
|
|
21113
21134
|
const raw = it[dndItemIdField];
|
|
21114
21135
|
return String(raw ?? `__idx_${idx}`);
|
|
@@ -21121,6 +21142,15 @@ function useDataDnd(args) {
|
|
|
21121
21142
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
21122
21143
|
[itemIdsSignature]
|
|
21123
21144
|
);
|
|
21145
|
+
const itemsContentSig = items.map((it, idx) => String(it[dndItemIdField] ?? `__${idx}`)).join("|");
|
|
21146
|
+
React80__namespace.default.useEffect(() => {
|
|
21147
|
+
const root = isRoot ? null : parentRoot;
|
|
21148
|
+
if (root) {
|
|
21149
|
+
root.clearOptimisticOrder(ownGroup);
|
|
21150
|
+
} else {
|
|
21151
|
+
clearOptimisticOrder(ownGroup);
|
|
21152
|
+
}
|
|
21153
|
+
}, [itemsContentSig, ownGroup]);
|
|
21124
21154
|
const zonesRef = React80__namespace.default.useRef(/* @__PURE__ */ new Map());
|
|
21125
21155
|
const registerZone = React80__namespace.default.useCallback((zoneId2, meta2) => {
|
|
21126
21156
|
zonesRef.current.set(zoneId2, meta2);
|
|
@@ -21130,11 +21160,9 @@ function useDataDnd(args) {
|
|
|
21130
21160
|
}, []);
|
|
21131
21161
|
const [activeDrag, setActiveDrag] = React80__namespace.default.useState(null);
|
|
21132
21162
|
const [overZoneGroup, setOverZoneGroup] = React80__namespace.default.useState(null);
|
|
21133
|
-
const zoneId = React80__namespace.default.useId();
|
|
21134
|
-
const ownGroup = dragGroup ?? accepts ?? zoneId;
|
|
21135
21163
|
const meta = React80__namespace.default.useMemo(
|
|
21136
|
-
() => ({ group: ownGroup, dropEvent, reorderEvent, itemIds }),
|
|
21137
|
-
[ownGroup, dropEvent, reorderEvent, itemIds]
|
|
21164
|
+
() => ({ group: ownGroup, dropEvent, reorderEvent, itemIds, rawItems: items, idField: dndItemIdField }),
|
|
21165
|
+
[ownGroup, dropEvent, reorderEvent, itemIds, items, dndItemIdField]
|
|
21138
21166
|
);
|
|
21139
21167
|
React80__namespace.default.useEffect(() => {
|
|
21140
21168
|
const target = isRoot ? null : parentRoot;
|
|
@@ -21181,7 +21209,7 @@ function useDataDnd(args) {
|
|
|
21181
21209
|
},
|
|
21182
21210
|
[]
|
|
21183
21211
|
);
|
|
21184
|
-
|
|
21212
|
+
React80__namespace.default.useCallback(
|
|
21185
21213
|
(group) => {
|
|
21186
21214
|
for (const z of zonesRef.current.values()) {
|
|
21187
21215
|
if (z.group === group) return z;
|
|
@@ -21193,81 +21221,76 @@ function useDataDnd(args) {
|
|
|
21193
21221
|
const handleDragEnd = React80__namespace.default.useCallback(
|
|
21194
21222
|
(event) => {
|
|
21195
21223
|
const { active, over } = event;
|
|
21196
|
-
const
|
|
21224
|
+
const activeIdStr = String(active.id);
|
|
21197
21225
|
dndLog.debug("dragEnd:received", {
|
|
21198
21226
|
activeId: active.id,
|
|
21199
21227
|
overId: over?.id,
|
|
21200
|
-
overData: over?.data?.current
|
|
21201
|
-
zones: allZones
|
|
21228
|
+
overData: over?.data?.current
|
|
21202
21229
|
});
|
|
21203
|
-
|
|
21204
|
-
|
|
21205
|
-
|
|
21206
|
-
|
|
21207
|
-
const
|
|
21208
|
-
|
|
21209
|
-
|
|
21210
|
-
|
|
21211
|
-
|
|
21212
|
-
|
|
21213
|
-
|
|
21214
|
-
|
|
21215
|
-
|
|
21216
|
-
|
|
21217
|
-
|
|
21218
|
-
|
|
21219
|
-
|
|
21220
|
-
if (!
|
|
21221
|
-
dndLog.warn("dragEnd:abort:
|
|
21230
|
+
let sourceMeta;
|
|
21231
|
+
let oldIndex = -1;
|
|
21232
|
+
let targetMeta;
|
|
21233
|
+
let newIndex = -1;
|
|
21234
|
+
for (const m of zonesRef.current.values()) {
|
|
21235
|
+
const rawIdx = m.rawItems.findIndex((it) => String(it[m.idField]) === activeIdStr);
|
|
21236
|
+
if (rawIdx >= 0) {
|
|
21237
|
+
sourceMeta = m;
|
|
21238
|
+
oldIndex = rawIdx;
|
|
21239
|
+
}
|
|
21240
|
+
const currentItems = optimisticOrdersRef.current.get(m.group) ?? m.rawItems;
|
|
21241
|
+
const curIdx = currentItems.findIndex((it) => String(it[m.idField]) === activeIdStr);
|
|
21242
|
+
if (curIdx >= 0) {
|
|
21243
|
+
targetMeta = m;
|
|
21244
|
+
newIndex = curIdx;
|
|
21245
|
+
}
|
|
21246
|
+
}
|
|
21247
|
+
if (!sourceMeta || !targetMeta) {
|
|
21248
|
+
dndLog.warn("dragEnd:abort:no-zone-resolved", { activeId: active.id, hasSource: !!sourceMeta, hasTarget: !!targetMeta });
|
|
21222
21249
|
return;
|
|
21223
21250
|
}
|
|
21224
|
-
if (
|
|
21225
|
-
if (
|
|
21226
|
-
const
|
|
21227
|
-
const evt = `UI:${targetZone.dropEvent}`;
|
|
21251
|
+
if (sourceMeta.group !== targetMeta.group) {
|
|
21252
|
+
if (targetMeta.dropEvent) {
|
|
21253
|
+
const evt = `UI:${targetMeta.dropEvent}`;
|
|
21228
21254
|
dndLog.info("dragEnd:cross-container:emit", {
|
|
21229
21255
|
event: evt,
|
|
21230
|
-
id:
|
|
21231
|
-
sourceGroup:
|
|
21232
|
-
targetGroup:
|
|
21233
|
-
newIndex
|
|
21256
|
+
id: activeIdStr,
|
|
21257
|
+
sourceGroup: sourceMeta.group,
|
|
21258
|
+
targetGroup: targetMeta.group,
|
|
21259
|
+
newIndex
|
|
21234
21260
|
});
|
|
21235
21261
|
eventBus.emit(evt, {
|
|
21236
|
-
id:
|
|
21237
|
-
sourceGroup:
|
|
21238
|
-
targetGroup:
|
|
21239
|
-
newIndex
|
|
21262
|
+
id: activeIdStr,
|
|
21263
|
+
sourceGroup: sourceMeta.group,
|
|
21264
|
+
targetGroup: targetMeta.group,
|
|
21265
|
+
newIndex
|
|
21240
21266
|
});
|
|
21241
21267
|
} else {
|
|
21242
|
-
dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup:
|
|
21268
|
+
dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup: targetMeta.group });
|
|
21243
21269
|
}
|
|
21244
21270
|
return;
|
|
21245
21271
|
}
|
|
21246
|
-
|
|
21247
|
-
|
|
21248
|
-
|
|
21249
|
-
if (sourceZone.group === ownGroup) {
|
|
21250
|
-
const reordered = sortable.arrayMove(orderedItems, oldIndex, newIndex);
|
|
21251
|
-
setLocalOrder(reordered);
|
|
21272
|
+
if (oldIndex === newIndex) {
|
|
21273
|
+
dndLog.debug("dragEnd:reorder:no-op", { sourceGroup: sourceMeta.group, oldIndex });
|
|
21274
|
+
return;
|
|
21252
21275
|
}
|
|
21253
|
-
if (
|
|
21254
|
-
const evt = `UI:${
|
|
21276
|
+
if (sourceMeta.reorderEvent) {
|
|
21277
|
+
const evt = `UI:${sourceMeta.reorderEvent}`;
|
|
21255
21278
|
dndLog.info("dragEnd:reorder:emit", {
|
|
21256
21279
|
event: evt,
|
|
21257
|
-
id:
|
|
21280
|
+
id: activeIdStr,
|
|
21258
21281
|
oldIndex,
|
|
21259
21282
|
newIndex
|
|
21260
21283
|
});
|
|
21261
21284
|
eventBus.emit(evt, {
|
|
21262
|
-
id:
|
|
21285
|
+
id: activeIdStr,
|
|
21263
21286
|
oldIndex,
|
|
21264
21287
|
newIndex
|
|
21265
21288
|
});
|
|
21266
21289
|
} else {
|
|
21267
|
-
dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup:
|
|
21290
|
+
dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup: sourceMeta.group });
|
|
21268
21291
|
}
|
|
21269
21292
|
},
|
|
21270
|
-
[
|
|
21293
|
+
[eventBus]
|
|
21271
21294
|
);
|
|
21272
21295
|
const sortableData = React80__namespace.default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
|
|
21273
21296
|
const SortableItem = React80__namespace.default.useCallback(
|
|
@@ -21328,30 +21351,20 @@ function useDataDnd(args) {
|
|
|
21328
21351
|
React80__namespace.default.useEffect(() => {
|
|
21329
21352
|
dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
|
|
21330
21353
|
}, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
|
|
21331
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
21354
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
21332
21355
|
Box,
|
|
21333
21356
|
{
|
|
21334
21357
|
ref: setNodeRef,
|
|
21335
21358
|
"data-dnd-zone": ownGroup,
|
|
21336
21359
|
"data-dnd-is-over": isThisZoneOver ? "true" : "false",
|
|
21337
|
-
className: isThisZoneOver ? "ring-2 ring-primary ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
|
|
21338
|
-
children
|
|
21339
|
-
children,
|
|
21340
|
-
showForeignPlaceholder ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
21341
|
-
Box,
|
|
21342
|
-
{
|
|
21343
|
-
"data-dnd-placeholder": true,
|
|
21344
|
-
style: { height: activeDrag2.height },
|
|
21345
|
-
className: "border-2 border-dashed border-primary/60 bg-primary/5 rounded-md my-1 transition-all"
|
|
21346
|
-
}
|
|
21347
|
-
) : null
|
|
21348
|
-
]
|
|
21360
|
+
className: isThisZoneOver ? "ring-2 ring-primary/40 ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
|
|
21361
|
+
children
|
|
21349
21362
|
}
|
|
21350
21363
|
);
|
|
21351
21364
|
};
|
|
21352
21365
|
const rootContextValue = React80__namespace.default.useMemo(
|
|
21353
|
-
() => ({ registerZone, unregisterZone, activeDrag, overZoneGroup }),
|
|
21354
|
-
[registerZone, unregisterZone, activeDrag, overZoneGroup]
|
|
21366
|
+
() => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
|
|
21367
|
+
[registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
|
|
21355
21368
|
);
|
|
21356
21369
|
const handleDragStart = React80__namespace.default.useCallback((event) => {
|
|
21357
21370
|
const sourceZone = findZoneByItem(event.active.id);
|
|
@@ -21373,13 +21386,73 @@ function useDataDnd(args) {
|
|
|
21373
21386
|
});
|
|
21374
21387
|
}, [findZoneByItem, isRoot, zoneId]);
|
|
21375
21388
|
const handleDragOver = React80__namespace.default.useCallback((event) => {
|
|
21376
|
-
const
|
|
21377
|
-
const
|
|
21378
|
-
|
|
21379
|
-
|
|
21380
|
-
|
|
21381
|
-
|
|
21382
|
-
|
|
21389
|
+
const { active, over } = event;
|
|
21390
|
+
const overData = over?.data?.current;
|
|
21391
|
+
const overGroup = overData?.dndGroup ?? null;
|
|
21392
|
+
setOverZoneGroup(overGroup);
|
|
21393
|
+
if (!over || !overGroup) return;
|
|
21394
|
+
const activeIdStr = String(active.id);
|
|
21395
|
+
let sourceMeta;
|
|
21396
|
+
let sourceGroup;
|
|
21397
|
+
for (const m of zonesRef.current.values()) {
|
|
21398
|
+
const currentItems = optimisticOrdersRef.current.get(m.group) ?? m.rawItems;
|
|
21399
|
+
const found = currentItems.find((it) => String(it[m.idField]) === activeIdStr);
|
|
21400
|
+
if (found) {
|
|
21401
|
+
sourceMeta = m;
|
|
21402
|
+
sourceGroup = m.group;
|
|
21403
|
+
break;
|
|
21404
|
+
}
|
|
21405
|
+
}
|
|
21406
|
+
if (!sourceMeta || !sourceGroup) {
|
|
21407
|
+
dndLog.debug("dragOver:no-source-zone", { activeId: active.id });
|
|
21408
|
+
return;
|
|
21409
|
+
}
|
|
21410
|
+
let targetMeta;
|
|
21411
|
+
for (const m of zonesRef.current.values()) {
|
|
21412
|
+
if (m.group === overGroup) {
|
|
21413
|
+
targetMeta = m;
|
|
21414
|
+
break;
|
|
21415
|
+
}
|
|
21416
|
+
}
|
|
21417
|
+
if (!targetMeta) {
|
|
21418
|
+
dndLog.debug("dragOver:no-target-zone", { overGroup });
|
|
21419
|
+
return;
|
|
21420
|
+
}
|
|
21421
|
+
if (sourceGroup === overGroup) {
|
|
21422
|
+
setOptimisticOrders((prev) => {
|
|
21423
|
+
const currentItems = prev.get(sourceGroup) ?? sourceMeta.rawItems;
|
|
21424
|
+
const oldIndex = currentItems.findIndex((it) => String(it[sourceMeta.idField]) === activeIdStr);
|
|
21425
|
+
const newIndex = currentItems.findIndex((it) => String(it[sourceMeta.idField]) === String(over.id));
|
|
21426
|
+
if (oldIndex === -1 || newIndex === -1 || oldIndex === newIndex) return prev;
|
|
21427
|
+
const reordered = sortable.arrayMove([...currentItems], oldIndex, newIndex);
|
|
21428
|
+
const next = new Map(prev);
|
|
21429
|
+
next.set(sourceGroup, reordered);
|
|
21430
|
+
return next;
|
|
21431
|
+
});
|
|
21432
|
+
return;
|
|
21433
|
+
}
|
|
21434
|
+
setOptimisticOrders((prev) => {
|
|
21435
|
+
const currentSource = prev.get(sourceGroup) ?? sourceMeta.rawItems;
|
|
21436
|
+
const currentTarget = prev.get(overGroup) ?? targetMeta.rawItems;
|
|
21437
|
+
const activeItem = currentSource.find((it) => String(it[sourceMeta.idField]) === activeIdStr);
|
|
21438
|
+
if (!activeItem) return prev;
|
|
21439
|
+
if (currentTarget.some((it) => String(it[targetMeta.idField]) === activeIdStr)) {
|
|
21440
|
+
return prev;
|
|
21441
|
+
}
|
|
21442
|
+
const newSource = currentSource.filter((it) => String(it[sourceMeta.idField]) !== activeIdStr);
|
|
21443
|
+
const overIdStr = String(over.id);
|
|
21444
|
+
const overIndex = currentTarget.findIndex((it) => String(it[targetMeta.idField]) === overIdStr);
|
|
21445
|
+
const insertAt = overIndex >= 0 ? overIndex : currentTarget.length;
|
|
21446
|
+
const newTarget = [
|
|
21447
|
+
...currentTarget.slice(0, insertAt),
|
|
21448
|
+
activeItem,
|
|
21449
|
+
...currentTarget.slice(insertAt)
|
|
21450
|
+
];
|
|
21451
|
+
const next = new Map(prev);
|
|
21452
|
+
next.set(sourceGroup, newSource);
|
|
21453
|
+
next.set(overGroup, newTarget);
|
|
21454
|
+
dndLog.debug("dragOver:cross-zone:splice", { sourceGroup, overGroup, sourceLen: newSource.length, targetLen: newTarget.length, insertAt });
|
|
21455
|
+
return next;
|
|
21383
21456
|
});
|
|
21384
21457
|
}, []);
|
|
21385
21458
|
const handleDragCancel = React80__namespace.default.useCallback((event) => {
|
package/dist/runtime/index.js
CHANGED
|
@@ -37,7 +37,7 @@ import langGo from 'react-syntax-highlighter/dist/esm/languages/prism/go.js';
|
|
|
37
37
|
import langGraphql from 'react-syntax-highlighter/dist/esm/languages/prism/graphql.js';
|
|
38
38
|
import { isCircuitEvent, schemaToIR, getPage, clearSchemaCache as clearSchemaCache$1, isEntityCall, isInlineTrait } from '@almadar/core';
|
|
39
39
|
import { useSensors, useSensor, PointerSensor, KeyboardSensor, pointerWithin, rectIntersection, closestCorners, DndContext, useDroppable } from '@dnd-kit/core';
|
|
40
|
-
import { sortableKeyboardCoordinates,
|
|
40
|
+
import { sortableKeyboardCoordinates, useSortable, arrayMove, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
|
41
41
|
import { CSS } from '@dnd-kit/utilities';
|
|
42
42
|
import { Handle, Position } from '@xyflow/react';
|
|
43
43
|
import { getPatternDefinition, getComponentForPattern as getComponentForPattern$1 } from '@almadar/patterns';
|
|
@@ -21058,11 +21058,32 @@ function useDataDnd(args) {
|
|
|
21058
21058
|
const eventBus = useEventBus();
|
|
21059
21059
|
const parentRoot = React80__default.useContext(RootCtx);
|
|
21060
21060
|
const isRoot = enabled && parentRoot === null;
|
|
21061
|
-
const
|
|
21062
|
-
const
|
|
21063
|
-
React80__default.
|
|
21064
|
-
|
|
21065
|
-
|
|
21061
|
+
const zoneId = React80__default.useId();
|
|
21062
|
+
const ownGroup = dragGroup ?? accepts ?? zoneId;
|
|
21063
|
+
const [optimisticOrders, setOptimisticOrders] = React80__default.useState(() => /* @__PURE__ */ new Map());
|
|
21064
|
+
const optimisticOrdersRef = React80__default.useRef(optimisticOrders);
|
|
21065
|
+
optimisticOrdersRef.current = optimisticOrders;
|
|
21066
|
+
const clearOptimisticOrder = React80__default.useCallback((group) => {
|
|
21067
|
+
setOptimisticOrders((prev) => {
|
|
21068
|
+
if (!prev.has(group)) return prev;
|
|
21069
|
+
const next = new Map(prev);
|
|
21070
|
+
next.delete(group);
|
|
21071
|
+
return next;
|
|
21072
|
+
});
|
|
21073
|
+
}, []);
|
|
21074
|
+
const sharedOptimistic = isRoot ? optimisticOrders : parentRoot?.optimisticOrders ?? /* @__PURE__ */ new Map();
|
|
21075
|
+
const optimisticEntry = sharedOptimistic.get(ownGroup);
|
|
21076
|
+
const orderedItems = optimisticEntry ?? items;
|
|
21077
|
+
if (isZone && enabled) {
|
|
21078
|
+
dndLog.debug("hook:render", {
|
|
21079
|
+
group: ownGroup,
|
|
21080
|
+
isRoot,
|
|
21081
|
+
itemsLen: items.length,
|
|
21082
|
+
optimisticEntryLen: optimisticEntry ? optimisticEntry.length : null,
|
|
21083
|
+
orderedLen: orderedItems.length,
|
|
21084
|
+
sharedKeys: Array.from(sharedOptimistic.keys())
|
|
21085
|
+
});
|
|
21086
|
+
}
|
|
21066
21087
|
const itemIdsSignature = orderedItems.map((it, idx) => {
|
|
21067
21088
|
const raw = it[dndItemIdField];
|
|
21068
21089
|
return String(raw ?? `__idx_${idx}`);
|
|
@@ -21075,6 +21096,15 @@ function useDataDnd(args) {
|
|
|
21075
21096
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
21076
21097
|
[itemIdsSignature]
|
|
21077
21098
|
);
|
|
21099
|
+
const itemsContentSig = items.map((it, idx) => String(it[dndItemIdField] ?? `__${idx}`)).join("|");
|
|
21100
|
+
React80__default.useEffect(() => {
|
|
21101
|
+
const root = isRoot ? null : parentRoot;
|
|
21102
|
+
if (root) {
|
|
21103
|
+
root.clearOptimisticOrder(ownGroup);
|
|
21104
|
+
} else {
|
|
21105
|
+
clearOptimisticOrder(ownGroup);
|
|
21106
|
+
}
|
|
21107
|
+
}, [itemsContentSig, ownGroup]);
|
|
21078
21108
|
const zonesRef = React80__default.useRef(/* @__PURE__ */ new Map());
|
|
21079
21109
|
const registerZone = React80__default.useCallback((zoneId2, meta2) => {
|
|
21080
21110
|
zonesRef.current.set(zoneId2, meta2);
|
|
@@ -21084,11 +21114,9 @@ function useDataDnd(args) {
|
|
|
21084
21114
|
}, []);
|
|
21085
21115
|
const [activeDrag, setActiveDrag] = React80__default.useState(null);
|
|
21086
21116
|
const [overZoneGroup, setOverZoneGroup] = React80__default.useState(null);
|
|
21087
|
-
const zoneId = React80__default.useId();
|
|
21088
|
-
const ownGroup = dragGroup ?? accepts ?? zoneId;
|
|
21089
21117
|
const meta = React80__default.useMemo(
|
|
21090
|
-
() => ({ group: ownGroup, dropEvent, reorderEvent, itemIds }),
|
|
21091
|
-
[ownGroup, dropEvent, reorderEvent, itemIds]
|
|
21118
|
+
() => ({ group: ownGroup, dropEvent, reorderEvent, itemIds, rawItems: items, idField: dndItemIdField }),
|
|
21119
|
+
[ownGroup, dropEvent, reorderEvent, itemIds, items, dndItemIdField]
|
|
21092
21120
|
);
|
|
21093
21121
|
React80__default.useEffect(() => {
|
|
21094
21122
|
const target = isRoot ? null : parentRoot;
|
|
@@ -21135,7 +21163,7 @@ function useDataDnd(args) {
|
|
|
21135
21163
|
},
|
|
21136
21164
|
[]
|
|
21137
21165
|
);
|
|
21138
|
-
|
|
21166
|
+
React80__default.useCallback(
|
|
21139
21167
|
(group) => {
|
|
21140
21168
|
for (const z of zonesRef.current.values()) {
|
|
21141
21169
|
if (z.group === group) return z;
|
|
@@ -21147,81 +21175,76 @@ function useDataDnd(args) {
|
|
|
21147
21175
|
const handleDragEnd = React80__default.useCallback(
|
|
21148
21176
|
(event) => {
|
|
21149
21177
|
const { active, over } = event;
|
|
21150
|
-
const
|
|
21178
|
+
const activeIdStr = String(active.id);
|
|
21151
21179
|
dndLog.debug("dragEnd:received", {
|
|
21152
21180
|
activeId: active.id,
|
|
21153
21181
|
overId: over?.id,
|
|
21154
|
-
overData: over?.data?.current
|
|
21155
|
-
zones: allZones
|
|
21182
|
+
overData: over?.data?.current
|
|
21156
21183
|
});
|
|
21157
|
-
|
|
21158
|
-
|
|
21159
|
-
|
|
21160
|
-
|
|
21161
|
-
const
|
|
21162
|
-
|
|
21163
|
-
|
|
21164
|
-
|
|
21165
|
-
|
|
21166
|
-
|
|
21167
|
-
|
|
21168
|
-
|
|
21169
|
-
|
|
21170
|
-
|
|
21171
|
-
|
|
21172
|
-
|
|
21173
|
-
|
|
21174
|
-
if (!
|
|
21175
|
-
dndLog.warn("dragEnd:abort:
|
|
21184
|
+
let sourceMeta;
|
|
21185
|
+
let oldIndex = -1;
|
|
21186
|
+
let targetMeta;
|
|
21187
|
+
let newIndex = -1;
|
|
21188
|
+
for (const m of zonesRef.current.values()) {
|
|
21189
|
+
const rawIdx = m.rawItems.findIndex((it) => String(it[m.idField]) === activeIdStr);
|
|
21190
|
+
if (rawIdx >= 0) {
|
|
21191
|
+
sourceMeta = m;
|
|
21192
|
+
oldIndex = rawIdx;
|
|
21193
|
+
}
|
|
21194
|
+
const currentItems = optimisticOrdersRef.current.get(m.group) ?? m.rawItems;
|
|
21195
|
+
const curIdx = currentItems.findIndex((it) => String(it[m.idField]) === activeIdStr);
|
|
21196
|
+
if (curIdx >= 0) {
|
|
21197
|
+
targetMeta = m;
|
|
21198
|
+
newIndex = curIdx;
|
|
21199
|
+
}
|
|
21200
|
+
}
|
|
21201
|
+
if (!sourceMeta || !targetMeta) {
|
|
21202
|
+
dndLog.warn("dragEnd:abort:no-zone-resolved", { activeId: active.id, hasSource: !!sourceMeta, hasTarget: !!targetMeta });
|
|
21176
21203
|
return;
|
|
21177
21204
|
}
|
|
21178
|
-
if (
|
|
21179
|
-
if (
|
|
21180
|
-
const
|
|
21181
|
-
const evt = `UI:${targetZone.dropEvent}`;
|
|
21205
|
+
if (sourceMeta.group !== targetMeta.group) {
|
|
21206
|
+
if (targetMeta.dropEvent) {
|
|
21207
|
+
const evt = `UI:${targetMeta.dropEvent}`;
|
|
21182
21208
|
dndLog.info("dragEnd:cross-container:emit", {
|
|
21183
21209
|
event: evt,
|
|
21184
|
-
id:
|
|
21185
|
-
sourceGroup:
|
|
21186
|
-
targetGroup:
|
|
21187
|
-
newIndex
|
|
21210
|
+
id: activeIdStr,
|
|
21211
|
+
sourceGroup: sourceMeta.group,
|
|
21212
|
+
targetGroup: targetMeta.group,
|
|
21213
|
+
newIndex
|
|
21188
21214
|
});
|
|
21189
21215
|
eventBus.emit(evt, {
|
|
21190
|
-
id:
|
|
21191
|
-
sourceGroup:
|
|
21192
|
-
targetGroup:
|
|
21193
|
-
newIndex
|
|
21216
|
+
id: activeIdStr,
|
|
21217
|
+
sourceGroup: sourceMeta.group,
|
|
21218
|
+
targetGroup: targetMeta.group,
|
|
21219
|
+
newIndex
|
|
21194
21220
|
});
|
|
21195
21221
|
} else {
|
|
21196
|
-
dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup:
|
|
21222
|
+
dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup: targetMeta.group });
|
|
21197
21223
|
}
|
|
21198
21224
|
return;
|
|
21199
21225
|
}
|
|
21200
|
-
|
|
21201
|
-
|
|
21202
|
-
|
|
21203
|
-
if (sourceZone.group === ownGroup) {
|
|
21204
|
-
const reordered = arrayMove(orderedItems, oldIndex, newIndex);
|
|
21205
|
-
setLocalOrder(reordered);
|
|
21226
|
+
if (oldIndex === newIndex) {
|
|
21227
|
+
dndLog.debug("dragEnd:reorder:no-op", { sourceGroup: sourceMeta.group, oldIndex });
|
|
21228
|
+
return;
|
|
21206
21229
|
}
|
|
21207
|
-
if (
|
|
21208
|
-
const evt = `UI:${
|
|
21230
|
+
if (sourceMeta.reorderEvent) {
|
|
21231
|
+
const evt = `UI:${sourceMeta.reorderEvent}`;
|
|
21209
21232
|
dndLog.info("dragEnd:reorder:emit", {
|
|
21210
21233
|
event: evt,
|
|
21211
|
-
id:
|
|
21234
|
+
id: activeIdStr,
|
|
21212
21235
|
oldIndex,
|
|
21213
21236
|
newIndex
|
|
21214
21237
|
});
|
|
21215
21238
|
eventBus.emit(evt, {
|
|
21216
|
-
id:
|
|
21239
|
+
id: activeIdStr,
|
|
21217
21240
|
oldIndex,
|
|
21218
21241
|
newIndex
|
|
21219
21242
|
});
|
|
21220
21243
|
} else {
|
|
21221
|
-
dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup:
|
|
21244
|
+
dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup: sourceMeta.group });
|
|
21222
21245
|
}
|
|
21223
21246
|
},
|
|
21224
|
-
[
|
|
21247
|
+
[eventBus]
|
|
21225
21248
|
);
|
|
21226
21249
|
const sortableData = React80__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
|
|
21227
21250
|
const SortableItem = React80__default.useCallback(
|
|
@@ -21282,30 +21305,20 @@ function useDataDnd(args) {
|
|
|
21282
21305
|
React80__default.useEffect(() => {
|
|
21283
21306
|
dndLog.info("dropzone:isOver:change", { droppableId, group: ownGroup, isOver, isThisZoneOver, showForeignPlaceholder, activeDragSourceGroup: activeDrag2?.sourceGroup ?? null });
|
|
21284
21307
|
}, [droppableId, isOver, isThisZoneOver, showForeignPlaceholder]);
|
|
21285
|
-
return /* @__PURE__ */
|
|
21308
|
+
return /* @__PURE__ */ jsx(
|
|
21286
21309
|
Box,
|
|
21287
21310
|
{
|
|
21288
21311
|
ref: setNodeRef,
|
|
21289
21312
|
"data-dnd-zone": ownGroup,
|
|
21290
21313
|
"data-dnd-is-over": isThisZoneOver ? "true" : "false",
|
|
21291
|
-
className: isThisZoneOver ? "ring-2 ring-primary ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
|
|
21292
|
-
children
|
|
21293
|
-
children,
|
|
21294
|
-
showForeignPlaceholder ? /* @__PURE__ */ jsx(
|
|
21295
|
-
Box,
|
|
21296
|
-
{
|
|
21297
|
-
"data-dnd-placeholder": true,
|
|
21298
|
-
style: { height: activeDrag2.height },
|
|
21299
|
-
className: "border-2 border-dashed border-primary/60 bg-primary/5 rounded-md my-1 transition-all"
|
|
21300
|
-
}
|
|
21301
|
-
) : null
|
|
21302
|
-
]
|
|
21314
|
+
className: isThisZoneOver ? "ring-2 ring-primary/40 ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
|
|
21315
|
+
children
|
|
21303
21316
|
}
|
|
21304
21317
|
);
|
|
21305
21318
|
};
|
|
21306
21319
|
const rootContextValue = React80__default.useMemo(
|
|
21307
|
-
() => ({ registerZone, unregisterZone, activeDrag, overZoneGroup }),
|
|
21308
|
-
[registerZone, unregisterZone, activeDrag, overZoneGroup]
|
|
21320
|
+
() => ({ registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder }),
|
|
21321
|
+
[registerZone, unregisterZone, activeDrag, overZoneGroup, optimisticOrders, clearOptimisticOrder]
|
|
21309
21322
|
);
|
|
21310
21323
|
const handleDragStart = React80__default.useCallback((event) => {
|
|
21311
21324
|
const sourceZone = findZoneByItem(event.active.id);
|
|
@@ -21327,13 +21340,73 @@ function useDataDnd(args) {
|
|
|
21327
21340
|
});
|
|
21328
21341
|
}, [findZoneByItem, isRoot, zoneId]);
|
|
21329
21342
|
const handleDragOver = React80__default.useCallback((event) => {
|
|
21330
|
-
const
|
|
21331
|
-
const
|
|
21332
|
-
|
|
21333
|
-
|
|
21334
|
-
|
|
21335
|
-
|
|
21336
|
-
|
|
21343
|
+
const { active, over } = event;
|
|
21344
|
+
const overData = over?.data?.current;
|
|
21345
|
+
const overGroup = overData?.dndGroup ?? null;
|
|
21346
|
+
setOverZoneGroup(overGroup);
|
|
21347
|
+
if (!over || !overGroup) return;
|
|
21348
|
+
const activeIdStr = String(active.id);
|
|
21349
|
+
let sourceMeta;
|
|
21350
|
+
let sourceGroup;
|
|
21351
|
+
for (const m of zonesRef.current.values()) {
|
|
21352
|
+
const currentItems = optimisticOrdersRef.current.get(m.group) ?? m.rawItems;
|
|
21353
|
+
const found = currentItems.find((it) => String(it[m.idField]) === activeIdStr);
|
|
21354
|
+
if (found) {
|
|
21355
|
+
sourceMeta = m;
|
|
21356
|
+
sourceGroup = m.group;
|
|
21357
|
+
break;
|
|
21358
|
+
}
|
|
21359
|
+
}
|
|
21360
|
+
if (!sourceMeta || !sourceGroup) {
|
|
21361
|
+
dndLog.debug("dragOver:no-source-zone", { activeId: active.id });
|
|
21362
|
+
return;
|
|
21363
|
+
}
|
|
21364
|
+
let targetMeta;
|
|
21365
|
+
for (const m of zonesRef.current.values()) {
|
|
21366
|
+
if (m.group === overGroup) {
|
|
21367
|
+
targetMeta = m;
|
|
21368
|
+
break;
|
|
21369
|
+
}
|
|
21370
|
+
}
|
|
21371
|
+
if (!targetMeta) {
|
|
21372
|
+
dndLog.debug("dragOver:no-target-zone", { overGroup });
|
|
21373
|
+
return;
|
|
21374
|
+
}
|
|
21375
|
+
if (sourceGroup === overGroup) {
|
|
21376
|
+
setOptimisticOrders((prev) => {
|
|
21377
|
+
const currentItems = prev.get(sourceGroup) ?? sourceMeta.rawItems;
|
|
21378
|
+
const oldIndex = currentItems.findIndex((it) => String(it[sourceMeta.idField]) === activeIdStr);
|
|
21379
|
+
const newIndex = currentItems.findIndex((it) => String(it[sourceMeta.idField]) === String(over.id));
|
|
21380
|
+
if (oldIndex === -1 || newIndex === -1 || oldIndex === newIndex) return prev;
|
|
21381
|
+
const reordered = arrayMove([...currentItems], oldIndex, newIndex);
|
|
21382
|
+
const next = new Map(prev);
|
|
21383
|
+
next.set(sourceGroup, reordered);
|
|
21384
|
+
return next;
|
|
21385
|
+
});
|
|
21386
|
+
return;
|
|
21387
|
+
}
|
|
21388
|
+
setOptimisticOrders((prev) => {
|
|
21389
|
+
const currentSource = prev.get(sourceGroup) ?? sourceMeta.rawItems;
|
|
21390
|
+
const currentTarget = prev.get(overGroup) ?? targetMeta.rawItems;
|
|
21391
|
+
const activeItem = currentSource.find((it) => String(it[sourceMeta.idField]) === activeIdStr);
|
|
21392
|
+
if (!activeItem) return prev;
|
|
21393
|
+
if (currentTarget.some((it) => String(it[targetMeta.idField]) === activeIdStr)) {
|
|
21394
|
+
return prev;
|
|
21395
|
+
}
|
|
21396
|
+
const newSource = currentSource.filter((it) => String(it[sourceMeta.idField]) !== activeIdStr);
|
|
21397
|
+
const overIdStr = String(over.id);
|
|
21398
|
+
const overIndex = currentTarget.findIndex((it) => String(it[targetMeta.idField]) === overIdStr);
|
|
21399
|
+
const insertAt = overIndex >= 0 ? overIndex : currentTarget.length;
|
|
21400
|
+
const newTarget = [
|
|
21401
|
+
...currentTarget.slice(0, insertAt),
|
|
21402
|
+
activeItem,
|
|
21403
|
+
...currentTarget.slice(insertAt)
|
|
21404
|
+
];
|
|
21405
|
+
const next = new Map(prev);
|
|
21406
|
+
next.set(sourceGroup, newSource);
|
|
21407
|
+
next.set(overGroup, newTarget);
|
|
21408
|
+
dndLog.debug("dragOver:cross-zone:splice", { sourceGroup, overGroup, sourceLen: newSource.length, targetLen: newTarget.length, insertAt });
|
|
21409
|
+
return next;
|
|
21337
21410
|
});
|
|
21338
21411
|
}, []);
|
|
21339
21412
|
const handleDragCancel = React80__default.useCallback((event) => {
|