@bemedev/mind-flow 0.3.1 → 0.3.2

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/lib/server.es.js CHANGED
@@ -459,6 +459,11 @@ var machine = createMachine({
459
459
  dimensions[id] = calculateDimensions(position);
460
460
  });
461
461
  } })),
462
+ setBoard: assign("board", { SET_BOARD: ({ payload }) => payload }),
463
+ generateID: action(({ pContext }) => pContext.generatedId = nanoid()),
464
+ select: assign("selected", { SELECT: ({ payload }) => payload }),
465
+ clearNewEdge: erase("newEdge"),
466
+ deselect: erase("selected"),
462
467
  startNewEdge: assign("newEdge", { START_NEW_EDGE: ({ payload: from, pContext: { dimensions } }) => {
463
468
  const { x, y } = dimensions[from].output;
464
469
  return {
@@ -469,7 +474,6 @@ var machine = createMachine({
469
474
  y1: y
470
475
  };
471
476
  } }),
472
- setBoard: assign("board", { SET_BOARD: ({ payload }) => payload }),
473
477
  buildUI: batch(assign("edgesPositions", {
474
478
  MOVE: ({ context: { data, edgesPositions }, payload, pContext: { dimensions } }) => {
475
479
  const edges = data?.edges;
@@ -502,26 +506,27 @@ var machine = createMachine({
502
506
  },
503
507
  MOVE_IMMEDIATE: ({ context: { data, edgesPositions }, payload, pContext: { dimensions } }) => {
504
508
  (data?.edges)?.forEach(({ from, to, id }) => {
509
+ const dimension = dimensions[payload.id];
510
+ const edgePosition = edgesPositions[id];
511
+ if (!edgePosition || !dimension) return;
505
512
  if (from === payload.id) {
506
- const dimension = dimensions[payload.id];
507
- const offset = dimension?.outputOffset ?? getDefaultOutputOffset(dimension?.width);
513
+ const offset = dimension.outputOffset ?? getDefaultOutputOffset(dimension.width);
508
514
  const x0 = payload.x + offset.x;
509
515
  const y0 = payload.y + offset.y;
510
- edgesPositions[id].x0 = x0;
511
- edgesPositions[id].y0 = y0;
512
- if (dimension) {
513
- dimension.output.x = x0;
514
- dimension.output.y = y0;
515
- }
516
+ edgePosition.x0 = x0;
517
+ edgePosition.y0 = y0;
518
+ dimension.output = {
519
+ x: x0,
520
+ y: y0
521
+ };
516
522
  }
517
523
  if (to === payload.id) {
518
- const dimension = dimensions[payload.id];
519
524
  const offset = dimension?.inputOffset ?? DEFAULT_INPUT_OFFSET;
520
525
  const x1 = payload.x + offset.x;
521
526
  const y1 = payload.y + offset.y;
522
- edgesPositions[id].x1 = x1;
523
- edgesPositions[id].y1 = y1;
524
- if (dimension) dimension.input = {
527
+ edgePosition.x1 = x1;
528
+ edgePosition.y1 = y1;
529
+ dimension.input = {
525
530
  x: x1,
526
531
  y: y1
527
532
  };
@@ -530,7 +535,7 @@ var machine = createMachine({
530
535
  return edgesPositions;
531
536
  },
532
537
  else: ({ context: { data, edgesPositions }, pContext: { dimensions } }) => {
533
- const edges = data?.edges ?? [];
538
+ const edges = toArray$1.typed(data?.edges);
534
539
  edgesPositions = {};
535
540
  edges.forEach(({ from, id, to }) => {
536
541
  const output = dimensions[from]?.output;
@@ -549,9 +554,6 @@ var machine = createMachine({
549
554
  addDimension: action({ ADD_DIMENSION: ({ payload: { id, dimension }, pContext: { dimensions } }) => {
550
555
  dimensions[id] = dimension;
551
556
  } }),
552
- generateID: action(({ pContext }) => {
553
- pContext.generatedId = nanoid();
554
- }),
555
557
  linkChild: batch(assign("data.edges", { ADD_CHILD: ({ context: { data }, pContext, payload }) => {
556
558
  const edges = toArray$1.typed(data?.edges);
557
559
  const from = payload;
@@ -580,20 +582,18 @@ var machine = createMachine({
580
582
  return edges;
581
583
  } }), assign("selected", ({ pContext: { generatedId } }) => buildNodeID(generatedId))),
582
584
  selectParent: assign("selected", ({ pContext: { generatedId } }) => buildNodeID(generatedId)),
583
- moveNode: assign("data.nodes", { MOVE: ({ context: { data }, payload }) => {
584
- const { id, x, y } = payload;
585
- return data?.nodes?.map((d) => {
586
- if (d.id === id) return {
587
- ...d,
585
+ moveNode: assign("data.nodes", { MOVE: ({ context: { data }, payload: { id, x, y } }) => {
586
+ return data?.nodes?.map((node) => {
587
+ if (node.id === id) return {
588
+ ...node,
588
589
  position: {
589
590
  x,
590
591
  y
591
592
  }
592
593
  };
593
- return d;
594
- }) ?? [];
594
+ return node;
595
+ });
595
596
  } }),
596
- select: assign("selected", { SELECT: ({ payload }) => payload }),
597
597
  delete: batch(filter("data.edges", { DELETE: ({ id, from, to }, _, { payload }) => {
598
598
  return id !== payload && from !== payload && to !== payload;
599
599
  } }), filter("data.nodes", { DELETE: ({ id }, _, { payload }) => id !== payload })),
@@ -607,8 +607,6 @@ var machine = createMachine({
607
607
  to
608
608
  }];
609
609
  } }), erase("newEdge")),
610
- clearNewEdge: erase("newEdge"),
611
- deselect: erase("selected"),
612
610
  zoom: assign("zoom", { ZOOM: ({ context: { zoom }, payload, pContext }) => {
613
611
  const next = zoom + payload;
614
612
  const clamped = Math.min(Math.max(Number(next.toFixed(2)), .2), 3);
@@ -623,6 +621,87 @@ var machine = createMachine({
623
621
  }
624
622
  pContext.previousZoom = zoom;
625
623
  return 1;
624
+ } }),
625
+ placeChild: assign("data.nodes", { ADD_CHILD: ({ payload, context: { data, board }, pContext }) => {
626
+ if (!board) return data?.nodes;
627
+ const nodes = data?.nodes;
628
+ if (!payload) return nodes;
629
+ const parentNode = nodes?.find((node) => node.id === payload);
630
+ if (!parentNode) return nodes;
631
+ const parentDimension = pContext.dimensions[payload];
632
+ const id = `node-${pContext.generatedId}`;
633
+ const width = parentDimension?.width ?? 192;
634
+ const height = parentDimension?.height ?? 50;
635
+ const initialX = parentNode.position.x + width + 100;
636
+ const initialY = parentNode.position.y;
637
+ const position = pContext.clampPosition(board, initialX, initialY, width, height);
638
+ const dimension = pContext.calculateDimensions(position, parentDimension);
639
+ nodes?.push({
640
+ id,
641
+ data: { content: "<Nouveau nœud>" },
642
+ input: true,
643
+ position
644
+ });
645
+ pContext.dimensions[id] = dimension;
646
+ return nodes;
647
+ } }),
648
+ placeParent: assign("data.nodes", { ADD_PARENT: ({ context: { data, zoom = 1, board }, pContext }) => {
649
+ if (!board) return data?.nodes;
650
+ const nodes = data?.nodes;
651
+ const id = `node-${pContext.generatedId}`;
652
+ const container = board.parent;
653
+ const scrollLeft = container?.scrollLeft ?? 0;
654
+ const scrollTop = container?.scrollTop ?? 0;
655
+ const width = container?.width ?? 0;
656
+ const height = container?.height ?? 0;
657
+ const currentZoom = zoom;
658
+ const x = (scrollLeft + width / 2) / currentZoom;
659
+ const y = (scrollTop + height / 2) / currentZoom;
660
+ const position = pContext.clampPosition(board, x, y);
661
+ const dimension = pContext.calculateDimensions(position);
662
+ nodes?.push({
663
+ id,
664
+ data: { content: "<Nouveau nœud>" },
665
+ input: false,
666
+ position
667
+ });
668
+ pContext.dimensions[id] = dimension;
669
+ return nodes;
670
+ } }),
671
+ placeSibling: assign("data.nodes", { ADD_SIBLING: ({ payload, context: { data, board }, pContext }) => {
672
+ if (!board) return data?.nodes;
673
+ const edges = data?.edges;
674
+ const nodes = data?.nodes;
675
+ const parentID = edges?.find((edge) => edge.to === payload)?.from;
676
+ if (!parentID) return nodes;
677
+ const parentNode = nodes?.find((node) => node.id === parentID);
678
+ if (!parentNode) return nodes;
679
+ const parentDimension = pContext.dimensions[parentID];
680
+ const id = `node-${pContext.generatedId}`;
681
+ const width = parentDimension?.width ?? 192;
682
+ const height = parentDimension?.height ?? 50;
683
+ const initialX = parentNode.position.x + width + 100;
684
+ const initialY = parentNode.position.y + 100;
685
+ const position = pContext.clampPosition(board, initialX, initialY, width, height);
686
+ const dimension = pContext.calculateDimensions(position, parentDimension);
687
+ nodes?.push({
688
+ id,
689
+ data: { content: "<Nouveau nœud>" },
690
+ input: true,
691
+ position
692
+ });
693
+ pContext.dimensions[id] = dimension;
694
+ return nodes;
695
+ } }),
696
+ moveNewEdge: assign("newEdge", { MOVE_NEW_EDGE: ({ context: { newEdge, board }, payload, pContext }) => {
697
+ if (!board) return void 0;
698
+ if (!newEdge) return void 0;
699
+ const { x: x1, y: y1 } = pContext.getBoardPosition(payload.x, payload.y, board);
700
+ return {
701
+ ...newEdge,
702
+ x1,
703
+ y1
704
+ };
626
705
  } })
627
706
  } }));
628
707
  //#endregion
@@ -656,7 +735,7 @@ var [Provider, useFlow] = createContext$1(() => {
656
735
  *
657
736
  * @returns Calculated 2D coordinate of type {@linkcode Point}.
658
737
  */
659
- getBoardPosition(clientX, clientY, el) {
738
+ getBoardPosition: (clientX, clientY, el) => {
660
739
  if (!el) return {
661
740
  x: clientX,
662
741
  y: clientY
@@ -681,7 +760,7 @@ var [Provider, useFlow] = createContext$1(() => {
681
760
  *
682
761
  * @see {@linkcode BOUNDS_CONSTRAINTS}
683
762
  */
684
- clampPosition(board, x, y, nodeWidth = 192, nodeHeight = 50) {
763
+ clampPosition: (board, x, y, nodeWidth = 192, nodeHeight = 50) => {
685
764
  const container = board?.parent;
686
765
  if (!container) return {
687
766
  x,
@@ -733,89 +812,6 @@ var [Provider, useFlow] = createContext$1(() => {
733
812
  }
734
813
  }
735
814
  });
736
- service.addOptions(({ assign }) => ({ actions: {
737
- placeChild: assign("data.nodes", { ADD_CHILD: ({ payload, context: { data, board }, pContext }) => {
738
- if (!board) return data?.nodes;
739
- const nodes = data?.nodes;
740
- if (!payload) return nodes;
741
- const parentNode = nodes?.find((node) => node.id === payload);
742
- if (!parentNode) return nodes;
743
- const parentDimension = pContext.dimensions[payload];
744
- const id = `node-${pContext.generatedId}`;
745
- const width = parentDimension?.width ?? 192;
746
- const height = parentDimension?.height ?? 50;
747
- const initialX = parentNode.position.x + width + 100;
748
- const initialY = parentNode.position.y;
749
- const position = pContext.clampPosition(board, initialX, initialY, width, height);
750
- const dimension = pContext.calculateDimensions(position, parentDimension);
751
- nodes?.push({
752
- id,
753
- data: { content: "<Nouveau nœud>" },
754
- input: true,
755
- position
756
- });
757
- pContext.dimensions[id] = dimension;
758
- return nodes;
759
- } }),
760
- placeParent: assign("data.nodes", { ADD_PARENT: ({ context: { data, zoom = 1, board }, pContext }) => {
761
- if (!board) return data?.nodes;
762
- const nodes = data?.nodes;
763
- const id = `node-${pContext.generatedId}`;
764
- const container = board.parent;
765
- const scrollLeft = container?.scrollLeft ?? 0;
766
- const scrollTop = container?.scrollTop ?? 0;
767
- const width = container?.width ?? 0;
768
- const height = container?.height ?? 0;
769
- const currentZoom = zoom;
770
- const x = (scrollLeft + width / 2) / currentZoom;
771
- const y = (scrollTop + height / 2) / currentZoom;
772
- const position = pContext.clampPosition(board, x, y);
773
- const dimension = pContext.calculateDimensions(position);
774
- nodes?.push({
775
- id,
776
- data: { content: "<Nouveau nœud>" },
777
- input: false,
778
- position
779
- });
780
- pContext.dimensions[id] = dimension;
781
- return nodes;
782
- } }),
783
- placeSibling: assign("data.nodes", { ADD_SIBLING: ({ payload, context: { data, board }, pContext }) => {
784
- if (!board) return data?.nodes;
785
- const edges = data?.edges;
786
- const nodes = data?.nodes;
787
- const parentID = edges?.find((edge) => edge.to === payload)?.from;
788
- if (!parentID) return nodes;
789
- const parentNode = nodes?.find((node) => node.id === parentID);
790
- if (!parentNode) return nodes;
791
- const parentDimension = pContext.dimensions[parentID];
792
- const id = `node-${pContext.generatedId}`;
793
- const width = parentDimension?.width ?? 192;
794
- const height = parentDimension?.height ?? 50;
795
- const initialX = parentNode.position.x + width + 100;
796
- const initialY = parentNode.position.y + 100;
797
- const position = pContext.clampPosition(board, initialX, initialY, width, height);
798
- const dimension = pContext.calculateDimensions(position, parentDimension);
799
- nodes?.push({
800
- id,
801
- data: { content: "<Nouveau nœud>" },
802
- input: true,
803
- position
804
- });
805
- pContext.dimensions[id] = dimension;
806
- return nodes;
807
- } }),
808
- moveNewEdge: assign("newEdge", { MOVE_NEW_EDGE: ({ context: { newEdge, board }, payload, pContext }) => {
809
- if (!board) return void 0;
810
- if (!newEdge) return void 0;
811
- const { x: x1, y: y1 } = pContext.getBoardPosition(payload.x, payload.y, board);
812
- return {
813
- ...newEdge,
814
- x1,
815
- y1
816
- };
817
- } })
818
- } }));
819
815
  service.start();
820
816
  return service;
821
817
  }, { name: "FlowContext" });
@@ -989,7 +985,7 @@ var _tmpl$$2 = [
989
985
  ];
990
986
  var _tmpl$2$1 = [
991
987
  "<div",
992
- " id=\"outputs\" class=\"pointer-events-none absolute top-0 z-10 flex cursor-default flex-col\" style=\"",
988
+ " id=\"inputs\" class=\"pointer-events-none absolute top-0 z-10 flex cursor-default flex-col\" style=\"",
993
989
  "\"><div class=\"cursor-default rounded-full bg-[#e38b29] shadow-md\" style=\"",
994
990
  "\"></div></div>"
995
991
  ];
@@ -1005,7 +1001,7 @@ var _tmpl$3$1 = [
1005
1001
  "\"><path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\"></path></svg></div><!--$-->",
1006
1002
  "<!--/--><!--$-->",
1007
1003
  "<!--/--><!--$-->",
1008
- "<!--/--><div id=\"inputs\" class=\"pointer-events-none absolute top-0 z-10 flex flex-col\" style=\"",
1004
+ "<!--/--><div id=\"outputs\" class=\"pointer-events-none absolute top-0 z-10 flex flex-col\" style=\"",
1009
1005
  "\"><div class=\"cursor-crosshair rounded-full bg-[#e38b29] shadow-md\" style=\"",
1010
1006
  "\"></div></div></div>"
1011
1007
  ];
@@ -1031,6 +1027,8 @@ var _tmpl$5 = [
1031
1027
  */
1032
1028
  var NodeComponent = (props) => {
1033
1029
  const service = useFlow();
1030
+ createState(service, { selector: (s) => s.context.newEdge });
1031
+ createDraggable(props.id);
1034
1032
  const node = createState(service, {
1035
1033
  selector: ({ context }) => {
1036
1034
  const item = toArray.typed(context.data?.nodes).find((n) => n.id === props.id);
@@ -1044,14 +1042,12 @@ var NodeComponent = (props) => {
1044
1042
  },
1045
1043
  equals: dequal
1046
1044
  });
1047
- createState(service, { selector: (s) => s.context.newEdge });
1048
- const selected = createState(service, { selector: (s) => s.context.selected === props.id });
1045
+ const selected = createState(service, { selector: ({ context }) => context.selected === props.id });
1049
1046
  const hasParent = createState(service, { selector: ({ context: { data } }) => {
1050
1047
  const edges = data?.edges;
1051
1048
  if (!edges) return false;
1052
1049
  return edges.some(({ to }) => to === props.id);
1053
1050
  } });
1054
- createDraggable(props.id);
1055
1051
  return ssr(_tmpl$3$1, ssrHydrationKey(), `flex flex-col absolute cursor-grab bg-white rounded-md shadow-md select-none transition-[border,box-shadow] duration-200 ease-in-out hover:shadow-lg draggable ${selected() ? "border border-[#e38c29] z-[100]" : ""} ${!selected() ? "border border-[#e6d4be] z-[1]" : ""} min-w-48`, ssrStyleProperty("top:", `${escape(node().y, true)}px`) + ssrStyleProperty(";left:", `${escape(node().x, true)}px`), ssrAttribute("id", escape(props.id, true), false), `pointer-events-none absolute flex items-center justify-end -top-7.5 right-0 transition-all duration-200 ease-in-out space-x-2 ${selected() ? "w-full opacity-100" : ""} ${!selected() ? "w-0 -right-3 opacity-0 overflow-hidden" : ""}`, ssrStyleProperty("overflow:", "visible") + ssrStyleProperty(";pointer-events:", "all") + ssrStyleProperty(";width:", `${escape(12, true) * 2}px`) + ssrStyleProperty(";height:", `${escape(12, true) * 2}px`), escape(createComponent(Show, {
1056
1052
  get when() {
1057
1053
  return hasParent();
@@ -1118,7 +1114,6 @@ var NodesBoard = () => {
1118
1114
  x: 0,
1119
1115
  y: 0
1120
1116
  });
1121
- const [id, setId] = createSignal("");
1122
1117
  const [ref, setRef] = createSignal();
1123
1118
  let percentX = 0;
1124
1119
  let percentY = 0;
@@ -1164,14 +1159,6 @@ var NodesBoard = () => {
1164
1159
  }, { defer: true }));
1165
1160
  onMount(sendBoard);
1166
1161
  const selectedId = createState(service, { selector: (s) => s.context?.selected });
1167
- /**
1168
- * Determines whether the given element ID matches the currently selected entity.
1169
- *
1170
- * @param id - The node or edge identifier to check.
1171
- *
1172
- * @returns `true` if the item is currently selected, otherwise `false`.
1173
- */
1174
- const selected = (id) => selectedId() === id;
1175
1162
  const nodeIds = createState(service, {
1176
1163
  selector: ({ context }) => {
1177
1164
  return toArray.typed(context.data?.nodes).map((item) => item.id);
@@ -1187,37 +1174,33 @@ var NodesBoard = () => {
1187
1174
  const cHeight = () => `calc((${CANVAS_SIZE}vh - ${MARGIN_Y}px) * ${zoom()})`;
1188
1175
  return ssr(_tmpl$3, ssrHydrationKey(), escape(createComponent(DragDropProvider, {
1189
1176
  onDragMove: ({ draggable: { transform: _transform, node, id } }) => {
1190
- setId(id);
1191
- if (selected(id)) {
1192
- const grandParent = node.parentElement?.parentElement;
1193
- const currentZoom = zoom();
1194
- const minX = 0;
1195
- const maxX = grandParent ? Math.max(0, grandParent.clientWidth / currentZoom - node.offsetWidth) : Infinity;
1196
- const minY = 0;
1197
- const maxY = grandParent ? Math.max(0, grandParent.clientHeight / currentZoom - node.offsetHeight) : Infinity;
1198
- const targetX = node.offsetLeft + _transform.x / currentZoom;
1199
- const targetY = node.offsetTop + _transform.y / currentZoom;
1200
- const x = Math.min(Math.max(targetX, minX), maxX);
1201
- const y = Math.min(Math.max(targetY, minY), maxY);
1202
- const deltaX = x - node.offsetLeft;
1203
- const deltaY = y - node.offsetTop;
1204
- node.style.setProperty("transform", `translate3d(${deltaX}px, ${deltaY}px, 0)`);
1205
- service.send({
1206
- type: "MOVE_IMMEDIATE",
1207
- payload: {
1208
- id: `${id}`,
1209
- x,
1210
- y
1211
- }
1212
- });
1213
- setTransform({
1214
- x: deltaX * currentZoom,
1215
- y: deltaY * currentZoom
1216
- });
1217
- }
1177
+ const grandParent = node.parentElement?.parentElement;
1178
+ const currentZoom = zoom();
1179
+ const minX = 0;
1180
+ const maxX = grandParent ? Math.max(0, grandParent.clientWidth / currentZoom - node.offsetWidth) : Infinity;
1181
+ const minY = 0;
1182
+ const maxY = grandParent ? Math.max(0, grandParent.clientHeight / currentZoom - node.offsetHeight) : Infinity;
1183
+ const targetX = node.offsetLeft + _transform.x / currentZoom;
1184
+ const targetY = node.offsetTop + _transform.y / currentZoom;
1185
+ const x = Math.min(Math.max(targetX, minX), maxX);
1186
+ const y = Math.min(Math.max(targetY, minY), maxY);
1187
+ const deltaX = x - node.offsetLeft;
1188
+ const deltaY = y - node.offsetTop;
1189
+ node.style.setProperty("transform", `translate3d(${deltaX}px, ${deltaY}px, 0)`);
1190
+ service.send({
1191
+ type: "MOVE_IMMEDIATE",
1192
+ payload: {
1193
+ id: `${id}`,
1194
+ x,
1195
+ y
1196
+ }
1197
+ });
1198
+ setTransform({
1199
+ x: deltaX * currentZoom,
1200
+ y: deltaY * currentZoom
1201
+ });
1218
1202
  },
1219
1203
  onDragEnd: ({ draggable: { node, id } }) => {
1220
- if (!selected(id)) return;
1221
1204
  const grandParent = node.parentElement?.parentElement;
1222
1205
  const currentZoom = zoom();
1223
1206
  const minX = 0;
@@ -1257,7 +1240,7 @@ var NodesBoard = () => {
1257
1240
  ssr(_tmpl$2, ssrHydrationKey(), escape(Math.round(zoom() * 100))),
1258
1241
  createComponent(Show, {
1259
1242
  get when() {
1260
- return !id() || !selected(id());
1243
+ return !selectedId();
1261
1244
  },
1262
1245
  get children() {
1263
1246
  return createComponent(DragOverlay, { children: "" });
@@ -1291,6 +1274,7 @@ var FlowChart = (props) => {
1291
1274
  const primaryEdges = props.config?.edges;
1292
1275
  const service = useFlow();
1293
1276
  const hasNewEdge = createState(service, { selector: (s) => !!s.context.newEdge });
1277
+ onCleanup(service.pause);
1294
1278
  onMount(() => {
1295
1279
  service.resume();
1296
1280
  service.send({
@@ -1301,7 +1285,6 @@ var FlowChart = (props) => {
1301
1285
  }
1302
1286
  });
1303
1287
  });
1304
- onCleanup(service.pause);
1305
1288
  return ssr(_tmpl$, ssrHydrationKey(), ssrStyleProperty("cursor:", hasNewEdge() ? "inherit" : "crosshair") + ssrStyleProperty(";background-image:", "radial-gradient(circle, #b8b8b8bf 1px, rgba(0, 0, 0, 0) 1px)"), escape(createComponent(NodesBoard, {})));
1306
1289
  };
1307
1290
  //#endregion