@almadar/ui 4.50.22 → 4.51.1

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.js CHANGED
@@ -34,7 +34,7 @@ import langToml from 'react-syntax-highlighter/dist/esm/languages/prism/toml.js'
34
34
  import langGo from 'react-syntax-highlighter/dist/esm/languages/prism/go.js';
35
35
  import langGraphql from 'react-syntax-highlighter/dist/esm/languages/prism/graphql.js';
36
36
  import { FieldTypeSchema, isInlineTrait, isEntityCall, schemaToIR, getPage, isCircuitEvent } from '@almadar/core';
37
- import { useSensors, useSensor, PointerSensor, KeyboardSensor, pointerWithin, rectIntersection, closestCorners, DndContext, useDroppable } from '@dnd-kit/core';
37
+ import { useDroppable, useDraggable, DndContext, DragOverlay, useSensors, useSensor, PointerSensor, KeyboardSensor, pointerWithin, rectIntersection, closestCorners } from '@dnd-kit/core';
38
38
  import { sortableKeyboardCoordinates, useSortable, arrayMove, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
39
39
  import { CSS } from '@dnd-kit/utilities';
40
40
  import { useThree, useFrame, Canvas } from '@react-three/fiber';
@@ -13651,7 +13651,7 @@ var init_MapView = __esm({
13651
13651
  shadowSize: [41, 41]
13652
13652
  });
13653
13653
  L.Marker.prototype.options.icon = defaultIcon;
13654
- const { useEffect: useEffect87, useRef: useRef87, useCallback: useCallback128, useState: useState122 } = React93__default;
13654
+ const { useEffect: useEffect87, useRef: useRef87, useCallback: useCallback126, useState: useState120 } = React93__default;
13655
13655
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
13656
13656
  const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
13657
13657
  function MapUpdater({ centerLat, centerLng, zoom }) {
@@ -13696,8 +13696,8 @@ var init_MapView = __esm({
13696
13696
  showAttribution = true
13697
13697
  }) {
13698
13698
  const eventBus = useEventBus3();
13699
- const [clickedPosition, setClickedPosition] = useState122(null);
13700
- const handleMapClick = useCallback128((lat, lng) => {
13699
+ const [clickedPosition, setClickedPosition] = useState120(null);
13700
+ const handleMapClick = useCallback126((lat, lng) => {
13701
13701
  if (showClickedPin) {
13702
13702
  setClickedPosition({ lat, lng });
13703
13703
  }
@@ -13706,7 +13706,7 @@ var init_MapView = __esm({
13706
13706
  eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
13707
13707
  }
13708
13708
  }, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
13709
- const handleMarkerClick = useCallback128((marker) => {
13709
+ const handleMarkerClick = useCallback126((marker) => {
13710
13710
  onMarkerClick?.(marker);
13711
13711
  if (markerClickEvent) {
13712
13712
  eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
@@ -24860,6 +24860,31 @@ var init_DashboardLayout = __esm({
24860
24860
  NavLink.displayName = "NavLink";
24861
24861
  }
24862
24862
  });
24863
+ function useAlmadarDndSensors(withSortableKeyboard = true) {
24864
+ return useSensors(
24865
+ useSensor(PointerSensor, {
24866
+ activationConstraint: { distance: ALMADAR_DND_ACTIVATION_DISTANCE }
24867
+ }),
24868
+ useSensor(
24869
+ KeyboardSensor,
24870
+ withSortableKeyboard ? { coordinateGetter: sortableKeyboardCoordinates } : void 0
24871
+ )
24872
+ );
24873
+ }
24874
+ var ALMADAR_DND_ACTIVATION_DISTANCE, almadarDndCollisionDetection;
24875
+ var init_useAlmadarDndCollision = __esm({
24876
+ "hooks/useAlmadarDndCollision.ts"() {
24877
+ "use client";
24878
+ ALMADAR_DND_ACTIVATION_DISTANCE = 5;
24879
+ almadarDndCollisionDetection = (args) => {
24880
+ const pw = pointerWithin(args);
24881
+ if (pw.length > 0) return pw;
24882
+ const ri = rectIntersection(args);
24883
+ if (ri.length > 0) return ri;
24884
+ return closestCorners(args);
24885
+ };
24886
+ }
24887
+ });
24863
24888
  function useDataDnd(args) {
24864
24889
  const {
24865
24890
  dragGroup,
@@ -24955,25 +24980,8 @@ function useDataDnd(args) {
24955
24980
  dndLog.debug("zone:unregister", { zoneId, group: meta.group });
24956
24981
  };
24957
24982
  }, [parentRoot, isRoot, zoneId, meta]);
24958
- const sensors = useSensors(
24959
- useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
24960
- useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
24961
- );
24962
- const collisionDetection = React93__default.useCallback((args2) => {
24963
- const pointerCollisions = pointerWithin(args2);
24964
- if (pointerCollisions.length > 0) {
24965
- dndLog.debug("collision:pointerWithin", { count: pointerCollisions.length, ids: pointerCollisions.map((c) => c.id) });
24966
- return pointerCollisions;
24967
- }
24968
- const rectCollisions = rectIntersection(args2);
24969
- if (rectCollisions.length > 0) {
24970
- dndLog.debug("collision:rectIntersection", { count: rectCollisions.length, ids: rectCollisions.map((c) => c.id) });
24971
- return rectCollisions;
24972
- }
24973
- const cornerCollisions = closestCorners(args2);
24974
- dndLog.debug("collision:closestCorners", { count: cornerCollisions.length, ids: cornerCollisions.map((c) => c.id) });
24975
- return cornerCollisions;
24976
- }, []);
24983
+ const sensors = useAlmadarDndSensors(true);
24984
+ const collisionDetection = almadarDndCollisionDetection;
24977
24985
  const findZoneByItem = React93__default.useCallback(
24978
24986
  (id) => {
24979
24987
  for (const z of zonesRef.current.values()) {
@@ -25310,6 +25318,7 @@ var init_useDataDnd = __esm({
25310
25318
  "components/molecules/useDataDnd.tsx"() {
25311
25319
  "use client";
25312
25320
  init_useEventBus();
25321
+ init_useAlmadarDndCollision();
25313
25322
  init_Box();
25314
25323
  dndLog = createLogger("almadar:ui:dnd");
25315
25324
  RootCtx = React93__default.createContext(null);
@@ -42933,7 +42942,7 @@ function getAllEvents(traits2) {
42933
42942
  }
42934
42943
  function EventDispatcherTab({ traits: traits2, schema }) {
42935
42944
  const eventBus = useEventBus();
42936
- const [log19, setLog] = React93.useState([]);
42945
+ const [log20, setLog] = React93.useState([]);
42937
42946
  const prevStatesRef = React93.useRef(/* @__PURE__ */ new Map());
42938
42947
  React93.useEffect(() => {
42939
42948
  for (const trait of traits2) {
@@ -42997,9 +43006,9 @@ function EventDispatcherTab({ traits: traits2, schema }) {
42997
43006
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: "Other Events (not available from current state)" }),
42998
43007
  /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: unavailableEvents.map((event) => /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", className: "opacity-50", children: event }, event)) })
42999
43008
  ] }),
43000
- log19.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
43009
+ log20.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
43001
43010
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: "Recent Transitions" }),
43002
- /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log19.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
43011
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", children: log20.map((entry, i) => /* @__PURE__ */ jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
43003
43012
  /* @__PURE__ */ jsx("span", { className: "text-purple-400", children: entry.traitName }),
43004
43013
  " ",
43005
43014
  /* @__PURE__ */ jsx("span", { className: "text-gray-500", children: entry.from }),
@@ -57422,67 +57431,6 @@ function convertFnFormLambdasInProps(props) {
57422
57431
 
57423
57432
  // hooks/index.ts
57424
57433
  init_useEventBus();
57425
- var ALMADAR_DND_MIME = "application/x-almadar-dnd";
57426
-
57427
- // hooks/useDropZone.ts
57428
- init_useEventBus();
57429
- function parsePayload(e) {
57430
- try {
57431
- const raw = e.dataTransfer.getData(ALMADAR_DND_MIME);
57432
- if (!raw) return null;
57433
- const parsed = JSON.parse(raw);
57434
- if (typeof parsed.kind !== "string" || !parsed.data) return null;
57435
- return parsed;
57436
- } catch {
57437
- return null;
57438
- }
57439
- }
57440
- function hasAlmadarPayload(e) {
57441
- return e.dataTransfer.types.includes(ALMADAR_DND_MIME);
57442
- }
57443
- function useDropZone({ accepts, onDrop, disabled = false }) {
57444
- const [isOver, setIsOver] = useState(false);
57445
- const eventBus = useEventBus();
57446
- const handleDragOver = useCallback(
57447
- (e) => {
57448
- if (disabled) return;
57449
- if (!hasAlmadarPayload(e)) return;
57450
- e.preventDefault();
57451
- e.dataTransfer.dropEffect = "copy";
57452
- setIsOver(true);
57453
- },
57454
- [disabled]
57455
- );
57456
- const handleDragLeave = useCallback(
57457
- (e) => {
57458
- setIsOver(false);
57459
- },
57460
- []
57461
- );
57462
- const handleDrop = useCallback(
57463
- (e) => {
57464
- e.preventDefault();
57465
- setIsOver(false);
57466
- if (disabled) return;
57467
- const payload = parsePayload(e);
57468
- if (!payload) return;
57469
- if (!accepts.includes(payload.kind)) return;
57470
- const position = { x: e.clientX, y: e.clientY };
57471
- onDrop(payload, position);
57472
- eventBus.emit("UI:DROP", { kind: payload.kind, data: payload.data, ...position });
57473
- },
57474
- [disabled, accepts, onDrop, eventBus]
57475
- );
57476
- const dropProps = useMemo(
57477
- () => ({
57478
- onDragOver: handleDragOver,
57479
- onDragLeave: handleDragLeave,
57480
- onDrop: handleDrop
57481
- }),
57482
- [handleDragOver, handleDragLeave, handleDrop]
57483
- );
57484
- return { dropProps, isOver };
57485
- }
57486
57434
  var log16 = createLogger("almadar:ui:effects:client-handlers");
57487
57435
  function createClientEffectHandlers(options) {
57488
57436
  const { eventBus, slotSetter, navigate, notify, callService } = options;
@@ -59095,6 +59043,143 @@ function BrowserPlayground({
59095
59043
  // components/molecules/avl/OrbPreviewNode.tsx
59096
59044
  init_useEventBus();
59097
59045
 
59046
+ // components/molecules/avl/useCanvasDnd.tsx
59047
+ init_useEventBus();
59048
+ init_useAlmadarDndCollision();
59049
+ var log18 = createLogger("almadar:ui:canvas-dnd");
59050
+ function useCanvasDraggable({
59051
+ id,
59052
+ payload,
59053
+ disabled
59054
+ }) {
59055
+ const { setNodeRef, attributes, listeners: listeners6, isDragging, transform } = useDraggable({
59056
+ id,
59057
+ data: { payload },
59058
+ disabled
59059
+ });
59060
+ const style = {
59061
+ transform: CSS.Translate.toString(transform),
59062
+ cursor: disabled ? "not-allowed" : isDragging ? "grabbing" : "grab",
59063
+ opacity: isDragging ? 0.5 : 1,
59064
+ touchAction: "none"
59065
+ };
59066
+ return { setNodeRef, attributes, listeners: listeners6, isDragging, style };
59067
+ }
59068
+ var DEFAULT_ACCEPTS = ["pattern", "behavior"];
59069
+ function useCanvasDroppable({
59070
+ id,
59071
+ target,
59072
+ accepts,
59073
+ disabled
59074
+ }) {
59075
+ const acceptsList = accepts ?? DEFAULT_ACCEPTS;
59076
+ const { setNodeRef, isOver } = useDroppable({
59077
+ id,
59078
+ data: { target, accepts: acceptsList },
59079
+ disabled
59080
+ });
59081
+ return { setNodeRef, isOver };
59082
+ }
59083
+ function defaultEmit(eventBus, drop) {
59084
+ const { payload, target, resolved } = drop;
59085
+ if (payload.kind === "pattern") {
59086
+ const patternType = payload.data.type;
59087
+ if (typeof patternType !== "string") {
59088
+ log18.warn("default-emit:pattern:missing-type");
59089
+ return;
59090
+ }
59091
+ const out = { patternType, containerNode: target.containerNode };
59092
+ if (resolved) {
59093
+ out.parentPath = resolved.parentPath;
59094
+ out.index = resolved.index;
59095
+ }
59096
+ eventBus.emit("UI:PATTERN_DROP", out);
59097
+ log18.info("default-emit:pattern", { patternType, level: target.level });
59098
+ return;
59099
+ }
59100
+ if (payload.kind === "behavior") {
59101
+ const behaviorName = payload.data.name;
59102
+ if (typeof behaviorName !== "string") {
59103
+ log18.warn("default-emit:behavior:missing-name");
59104
+ return;
59105
+ }
59106
+ eventBus.emit("UI:BEHAVIOR_DROP", {
59107
+ behaviorName,
59108
+ containerNode: target.containerNode
59109
+ });
59110
+ log18.info("default-emit:behavior", { behaviorName, level: target.level });
59111
+ return;
59112
+ }
59113
+ log18.debug("default-emit:unhandled-kind", { kind: payload.kind });
59114
+ }
59115
+ function CanvasDndProvider({
59116
+ children,
59117
+ onDrop,
59118
+ renderOverlay
59119
+ }) {
59120
+ const eventBus = useEventBus();
59121
+ const sensors = useAlmadarDndSensors(false);
59122
+ const [activePayload, setActivePayload] = React93__default.useState(null);
59123
+ const handleDragStart = React93__default.useCallback((e) => {
59124
+ const data = e.active.data.current;
59125
+ const payload = data?.payload;
59126
+ if (payload) {
59127
+ setActivePayload(payload);
59128
+ eventBus.emit("UI:DRAG_START", { kind: payload.kind, data: payload.data });
59129
+ log18.info("dragStart", { id: e.active.id, kind: payload.kind });
59130
+ } else {
59131
+ log18.warn("dragStart:missing-payload", { id: e.active.id });
59132
+ }
59133
+ }, [eventBus]);
59134
+ const handleDragEnd = React93__default.useCallback((e) => {
59135
+ setActivePayload(null);
59136
+ const activeData = e.active.data.current;
59137
+ const payload = activeData?.payload;
59138
+ const overData = e.over?.data.current;
59139
+ const target = overData?.target;
59140
+ const accepts = overData?.accepts;
59141
+ log18.info("dragEnd", {
59142
+ activeId: e.active.id,
59143
+ overId: e.over?.id,
59144
+ hasPayload: !!payload,
59145
+ hasTarget: !!target,
59146
+ targetLevel: target?.level
59147
+ });
59148
+ if (payload) {
59149
+ eventBus.emit("UI:DRAG_END", { kind: payload.kind, data: payload.data });
59150
+ }
59151
+ if (!payload || !target) return;
59152
+ if (accepts && !accepts.includes(payload.kind)) {
59153
+ log18.debug("dragEnd:rejected:kind", { kind: payload.kind, accepts: [...accepts] });
59154
+ return;
59155
+ }
59156
+ const activator = e.activatorEvent;
59157
+ const cursor = activator && typeof activator.clientX === "number" && typeof activator.clientY === "number" ? { x: activator.clientX + e.delta.x, y: activator.clientY + e.delta.y } : null;
59158
+ const resolved = target.resolvePath && cursor ? target.resolvePath(cursor) : null;
59159
+ const drop = { payload, target, cursor, resolved };
59160
+ const suppressed = onDrop ? onDrop(drop) === true : false;
59161
+ if (!suppressed) defaultEmit(eventBus, drop);
59162
+ }, [eventBus, onDrop]);
59163
+ const handleDragCancel = React93__default.useCallback(() => {
59164
+ setActivePayload(null);
59165
+ log18.info("dragCancel");
59166
+ }, []);
59167
+ return /* @__PURE__ */ jsxs(
59168
+ DndContext,
59169
+ {
59170
+ sensors,
59171
+ collisionDetection: almadarDndCollisionDetection,
59172
+ onDragStart: handleDragStart,
59173
+ onDragEnd: handleDragEnd,
59174
+ onDragCancel: handleDragCancel,
59175
+ children: [
59176
+ children,
59177
+ renderOverlay ? /* @__PURE__ */ jsx(DragOverlay, { dropAnimation: null, children: activePayload ? renderOverlay(activePayload) : null }) : null
59178
+ ]
59179
+ }
59180
+ );
59181
+ }
59182
+
59098
59183
  // components/molecules/avl/wire-validation.ts
59099
59184
  function validateWire(sourcePayload, targetPayload) {
59100
59185
  const warnings = [];
@@ -59443,105 +59528,74 @@ var OrbPreviewNodeInner = (props) => {
59443
59528
  unsub2();
59444
59529
  };
59445
59530
  }, [eventBus]);
59446
- const handlePreviewDrop = useCallback((e) => {
59447
- e.preventDefault();
59448
- e.stopPropagation();
59449
- setDragActive(false);
59450
- contentRef.current?.querySelectorAll(".drag-hover, .drop-indicator").forEach((el2) => {
59451
- el2.classList.remove("drag-hover");
59452
- if (el2.classList.contains("drop-indicator")) el2.remove();
59453
- });
59454
- const raw = e.dataTransfer.getData(ALMADAR_DND_MIME);
59455
- if (!raw) return;
59456
- let payload;
59457
- try {
59458
- payload = JSON.parse(raw);
59459
- } catch {
59460
- return;
59461
- }
59462
- if (payload.kind !== "pattern") return;
59463
- let el = e.target;
59464
- while (el && el.dataset.acceptsChildren !== "true") {
59465
- el = el.parentElement;
59466
- if (!el || el === contentRef.current) break;
59467
- }
59468
- const containerNode = {
59469
- orbitalName: data.orbitalName,
59470
- traitName: data.traitName,
59471
- transitionEvent: data.transitionEvent
59472
- };
59473
- const containerPath = el?.dataset?.patternPath;
59474
- if (!containerPath) {
59475
- eventBus.emit("UI:PATTERN_DROP", {
59476
- parentPath: "root",
59477
- patternType: payload.data.type,
59478
- index: 0,
59479
- containerNode
59480
- });
59481
- return;
59482
- }
59483
- const pathChildren = el.querySelectorAll(":scope > [data-pattern-path]");
59484
- let insertIndex = pathChildren.length;
59485
- for (let i = 0; i < pathChildren.length; i++) {
59486
- const rect = pathChildren[i].getBoundingClientRect();
59531
+ const resolveL2Path = useCallback(
59532
+ (cursor) => {
59533
+ const hit = document.elementFromPoint(cursor.x, cursor.y);
59534
+ if (!hit) return null;
59535
+ let el = hit;
59536
+ while (el && el.dataset.acceptsChildren !== "true") {
59537
+ if (el === contentRef.current) break;
59538
+ el = el.parentElement;
59539
+ }
59540
+ if (!el) return null;
59541
+ const containerPath = el.dataset?.patternPath;
59542
+ if (!containerPath) return { parentPath: "root", index: 0 };
59543
+ const pathChildren = el.querySelectorAll(":scope > [data-pattern-path]");
59544
+ let insertIndex = pathChildren.length;
59487
59545
  const style = el.firstElementChild ? getComputedStyle(el.firstElementChild) : null;
59488
59546
  const isVertical = style?.flexDirection !== "row";
59489
- const mid = isVertical ? rect.top + rect.height / 2 : rect.left + rect.width / 2;
59490
- const cursor = isVertical ? e.clientY : e.clientX;
59491
- if (cursor < mid) {
59492
- insertIndex = i;
59493
- break;
59547
+ for (let i = 0; i < pathChildren.length; i++) {
59548
+ const rect = pathChildren[i].getBoundingClientRect();
59549
+ const mid = isVertical ? rect.top + rect.height / 2 : rect.left + rect.width / 2;
59550
+ const pos = isVertical ? cursor.y : cursor.x;
59551
+ if (pos < mid) {
59552
+ insertIndex = i;
59553
+ break;
59554
+ }
59494
59555
  }
59495
- }
59496
- eventBus.emit("UI:PATTERN_DROP", {
59497
- parentPath: containerPath,
59498
- patternType: payload.data.type,
59499
- index: insertIndex,
59500
- containerNode
59501
- });
59502
- }, [eventBus, data.orbitalName, data.traitName, data.transitionEvent]);
59503
- const handlePreviewDragOver = useCallback((e) => {
59504
- if (!e.dataTransfer.types.includes(ALMADAR_DND_MIME)) return;
59505
- e.preventDefault();
59506
- e.stopPropagation();
59507
- e.dataTransfer.dropEffect = "copy";
59508
- if (!dragActive) setDragActive(true);
59509
- let el = e.target;
59510
- while (el && el.dataset.acceptsChildren !== "true") {
59511
- el = el.parentElement;
59512
- if (!el || el === contentRef.current) break;
59513
- }
59514
- contentRef.current?.querySelectorAll(".drag-hover").forEach((c) => c.classList.remove("drag-hover"));
59515
- if (el?.dataset?.acceptsChildren === "true") {
59516
- el.classList.add("drag-hover");
59517
- }
59518
- }, [dragActive]);
59519
- const handlePreviewDragLeave = useCallback((e) => {
59520
- contentRef.current?.querySelectorAll(".drag-hover").forEach((c) => c.classList.remove("drag-hover"));
59521
- }, []);
59556
+ return { parentPath: containerPath, index: insertIndex };
59557
+ },
59558
+ []
59559
+ );
59560
+ const l2Target = useMemo(
59561
+ () => ({
59562
+ level: "l2",
59563
+ containerNode: {
59564
+ orbitalName: data.orbitalName,
59565
+ traitName: data.traitName,
59566
+ transitionEvent: data.transitionEvent
59567
+ },
59568
+ resolvePath: resolveL2Path
59569
+ }),
59570
+ [data.orbitalName, data.traitName, data.transitionEvent, resolveL2Path]
59571
+ );
59572
+ const { setNodeRef: l2SetNodeRef, isOver: l2IsOver } = useCanvasDroppable({
59573
+ id: `orb-l2-${data.orbitalName}-${data.traitName ?? ""}-${data.transitionEvent ?? ""}`,
59574
+ target: l2Target,
59575
+ accepts: ["pattern"],
59576
+ disabled: !isExpanded
59577
+ });
59578
+ const setContentRef = useCallback((el) => {
59579
+ contentRef.current = el;
59580
+ l2SetNodeRef(el);
59581
+ }, [l2SetNodeRef]);
59522
59582
  const statusBorder = isRunning ? "var(--color-primary)" : isError ? "var(--color-danger)" : isSuccess ? "var(--color-success)" : null;
59523
59583
  const borderWidth = isRunning || isError || isSuccess ? "2px" : "1.5px";
59524
59584
  const borderColor = statusBorder ?? (hovered ? "var(--color-primary)" : colors.border);
59525
- const handleL1Drop = useCallback(
59526
- (payload) => {
59527
- if (payload.kind !== "pattern") return;
59528
- if (typeof payload.data.type !== "string") return;
59529
- eventBus.emit("UI:PATTERN_DROP", {
59530
- patternType: payload.data.type,
59531
- containerNode: { orbitalName: data.orbitalName }
59532
- });
59533
- },
59534
- [eventBus, data.orbitalName]
59585
+ const l1Target = useMemo(
59586
+ () => ({ level: "l1", containerNode: { orbitalName: data.orbitalName } }),
59587
+ [data.orbitalName]
59535
59588
  );
59536
- const { dropProps: l1DropProps, isOver: l1IsOver } = useDropZone({
59589
+ const { setNodeRef: l1SetNodeRef, isOver: l1IsOver } = useCanvasDroppable({
59590
+ id: `orb-l1-${data.orbitalName}`,
59591
+ target: l1Target,
59537
59592
  accepts: ["pattern"],
59538
- onDrop: handleL1Drop,
59539
59593
  disabled: isExpanded
59540
59594
  });
59541
59595
  return /* @__PURE__ */ jsxs(
59542
59596
  Box,
59543
59597
  {
59544
- ...isExpanded ? {} : l1DropProps,
59598
+ ref: isExpanded ? void 0 : l1SetNodeRef,
59545
59599
  className: `rounded-lg border shadow-sm bg-card transition-all duration-200 overflow-hidden relative${isRunning ? " orb-preview-running" : ""}`,
59546
59600
  style: {
59547
59601
  borderColor: l1IsOver ? "var(--color-primary)" : borderColor,
@@ -59683,12 +59737,9 @@ var OrbPreviewNodeInner = (props) => {
59683
59737
  /* @__PURE__ */ jsx(
59684
59738
  Box,
59685
59739
  {
59686
- ref: contentRef,
59687
- className: `orb-preview-live nodrag${dragActive ? " drag-active" : ""}`,
59740
+ ref: setContentRef,
59741
+ className: `orb-preview-live nodrag${dragActive || l2IsOver ? " drag-active" : ""}`,
59688
59742
  onClick: handleContentClick,
59689
- onDrop: handlePreviewDrop,
59690
- onDragOver: handlePreviewDragOver,
59691
- onDragLeave: handlePreviewDragLeave,
59692
59743
  children: orbitalSchema ? /* @__PURE__ */ jsx(Box, { style: { minHeight: preset.minHeight }, children: /* @__PURE__ */ jsx(
59693
59744
  BrowserPlayground,
59694
59745
  {
@@ -61184,7 +61235,7 @@ init_AvlTransitionLane();
61184
61235
  init_AvlSwimLane();
61185
61236
  init_types();
61186
61237
  init_avl_elk_layout();
61187
- var log18 = createLogger("almadar:ui:avl:trait-scene");
61238
+ var log19 = createLogger("almadar:ui:avl:trait-scene");
61188
61239
  var SWIM_GUTTER2 = 120;
61189
61240
  var CENTER_W2 = 360;
61190
61241
  var AvlTraitScene = ({
@@ -61196,7 +61247,7 @@ var AvlTraitScene = ({
61196
61247
  const dataKey = useMemo(() => JSON.stringify(data), [data]);
61197
61248
  useEffect(() => {
61198
61249
  computeTraitLayout(data).then(setLayout).catch((error) => {
61199
- log18.error("computeTraitLayout failed", { error: error instanceof Error ? error : String(error) });
61250
+ log19.error("computeTraitLayout failed", { error: error instanceof Error ? error : String(error) });
61200
61251
  });
61201
61252
  }, [dataKey]);
61202
61253
  if (!layout) {
@@ -62338,4 +62389,4 @@ AvlClickTarget.displayName = "AvlClickTarget";
62338
62389
  // components/organisms/avl/index.ts
62339
62390
  init_avl_schema_parser();
62340
62391
 
62341
- export { AVL_FIELD_TYPE_SHAPES, AVL_OPERATOR_COLORS, AvlApplication, AvlBackwardEdge, AvlBehaviorGlyph, AvlBinding, AvlBindingEdge, AvlBindingRef, AvlClickTarget, AvlClosedCircuit, AvlCosmicZoom, AvlEffect, AvlEmitListen, AvlEntity, AvlEvent, AvlEventWireEdge, AvlExprTree, AvlField, AvlFieldType, AvlGuard, AvlLiteral, AvlOperator, AvlOrbital, AvlOrbitalNode, AvlOrbitalUnit, AvlOrbitalsCosmicZoom, AvlPage, AvlPageEdge, AvlPersistence, AvlSExpr, AvlSlotMap, AvlState, AvlStateMachine, AvlSwimLane, AvlTrait, AvlTraitScene, AvlTransition, AvlTransitionEdge, AvlTransitionLane, AvlTransitionScene, BehaviorComposeNode, BehaviorView, CONNECTION_COLORS, DOMAIN_COLORS, DetailView, EFFECT_CATEGORY_COLORS, EFFECT_TYPE_TO_CATEGORY, EventFlowEdge, FlowCanvas, MiniStateMachine, ModuleCard, OrbInspector, OrbPreviewNode, STATE_COLORS, SystemNode, ZOOM_BAND_THRESHOLDS, ZoomBandContext, ZoomBreadcrumb, ZoomLegend, arcPath, behaviorsToComposeGraph, computeTraitLayout, computeZoomBand, curveControlPoint, edgePath, getStateRole, gridPositions, orbitalToExpandedGraph, parseApplicationLevel, parseOrbitalLevel, parseTraitLevel, parseTransitionLevel, radialPositions, registryEntryToCanvasEntry, ringPositions, schemaToFlowGraph, schemaToOverviewGraph, useZoomBand, zoomProgress };
62392
+ export { AVL_FIELD_TYPE_SHAPES, AVL_OPERATOR_COLORS, AvlApplication, AvlBackwardEdge, AvlBehaviorGlyph, AvlBinding, AvlBindingEdge, AvlBindingRef, AvlClickTarget, AvlClosedCircuit, AvlCosmicZoom, AvlEffect, AvlEmitListen, AvlEntity, AvlEvent, AvlEventWireEdge, AvlExprTree, AvlField, AvlFieldType, AvlGuard, AvlLiteral, AvlOperator, AvlOrbital, AvlOrbitalNode, AvlOrbitalUnit, AvlOrbitalsCosmicZoom, AvlPage, AvlPageEdge, AvlPersistence, AvlSExpr, AvlSlotMap, AvlState, AvlStateMachine, AvlSwimLane, AvlTrait, AvlTraitScene, AvlTransition, AvlTransitionEdge, AvlTransitionLane, AvlTransitionScene, BehaviorComposeNode, BehaviorView, CONNECTION_COLORS, CanvasDndProvider, DOMAIN_COLORS, DetailView, EFFECT_CATEGORY_COLORS, EFFECT_TYPE_TO_CATEGORY, EventFlowEdge, FlowCanvas, MiniStateMachine, ModuleCard, OrbInspector, OrbPreviewNode, STATE_COLORS, SystemNode, ZOOM_BAND_THRESHOLDS, ZoomBandContext, ZoomBreadcrumb, ZoomLegend, arcPath, behaviorsToComposeGraph, computeTraitLayout, computeZoomBand, curveControlPoint, edgePath, getStateRole, gridPositions, orbitalToExpandedGraph, parseApplicationLevel, parseOrbitalLevel, parseTraitLevel, parseTransitionLevel, radialPositions, registryEntryToCanvasEntry, ringPositions, schemaToFlowGraph, schemaToOverviewGraph, useCanvasDraggable, useCanvasDroppable, useZoomBand, zoomProgress };
@@ -20073,6 +20073,31 @@ var init_DashboardLayout = __esm({
20073
20073
  NavLink.displayName = "NavLink";
20074
20074
  }
20075
20075
  });
20076
+ function useAlmadarDndSensors(withSortableKeyboard = true) {
20077
+ return core$1.useSensors(
20078
+ core$1.useSensor(core$1.PointerSensor, {
20079
+ activationConstraint: { distance: ALMADAR_DND_ACTIVATION_DISTANCE }
20080
+ }),
20081
+ core$1.useSensor(
20082
+ core$1.KeyboardSensor,
20083
+ withSortableKeyboard ? { coordinateGetter: sortable.sortableKeyboardCoordinates } : void 0
20084
+ )
20085
+ );
20086
+ }
20087
+ var ALMADAR_DND_ACTIVATION_DISTANCE, almadarDndCollisionDetection;
20088
+ var init_useAlmadarDndCollision = __esm({
20089
+ "hooks/useAlmadarDndCollision.ts"() {
20090
+ "use client";
20091
+ ALMADAR_DND_ACTIVATION_DISTANCE = 5;
20092
+ almadarDndCollisionDetection = (args) => {
20093
+ const pw = core$1.pointerWithin(args);
20094
+ if (pw.length > 0) return pw;
20095
+ const ri = core$1.rectIntersection(args);
20096
+ if (ri.length > 0) return ri;
20097
+ return core$1.closestCorners(args);
20098
+ };
20099
+ }
20100
+ });
20076
20101
  function useDataDnd(args) {
20077
20102
  const {
20078
20103
  dragGroup,
@@ -20168,25 +20193,8 @@ function useDataDnd(args) {
20168
20193
  dndLog.debug("zone:unregister", { zoneId, group: meta.group });
20169
20194
  };
20170
20195
  }, [parentRoot, isRoot, zoneId, meta]);
20171
- const sensors = core$1.useSensors(
20172
- core$1.useSensor(core$1.PointerSensor, { activationConstraint: { distance: 5 } }),
20173
- core$1.useSensor(core$1.KeyboardSensor, { coordinateGetter: sortable.sortableKeyboardCoordinates })
20174
- );
20175
- const collisionDetection = React75__namespace.default.useCallback((args2) => {
20176
- const pointerCollisions = core$1.pointerWithin(args2);
20177
- if (pointerCollisions.length > 0) {
20178
- dndLog.debug("collision:pointerWithin", { count: pointerCollisions.length, ids: pointerCollisions.map((c) => c.id) });
20179
- return pointerCollisions;
20180
- }
20181
- const rectCollisions = core$1.rectIntersection(args2);
20182
- if (rectCollisions.length > 0) {
20183
- dndLog.debug("collision:rectIntersection", { count: rectCollisions.length, ids: rectCollisions.map((c) => c.id) });
20184
- return rectCollisions;
20185
- }
20186
- const cornerCollisions = core$1.closestCorners(args2);
20187
- dndLog.debug("collision:closestCorners", { count: cornerCollisions.length, ids: cornerCollisions.map((c) => c.id) });
20188
- return cornerCollisions;
20189
- }, []);
20196
+ const sensors = useAlmadarDndSensors(true);
20197
+ const collisionDetection = almadarDndCollisionDetection;
20190
20198
  const findZoneByItem = React75__namespace.default.useCallback(
20191
20199
  (id) => {
20192
20200
  for (const z of zonesRef.current.values()) {
@@ -20523,6 +20531,7 @@ var init_useDataDnd = __esm({
20523
20531
  "components/molecules/useDataDnd.tsx"() {
20524
20532
  "use client";
20525
20533
  init_useEventBus();
20534
+ init_useAlmadarDndCollision();
20526
20535
  init_Box();
20527
20536
  dndLog = logger.createLogger("almadar:ui:dnd");
20528
20537
  RootCtx = React75__namespace.default.createContext(null);