@likec4/diagram 1.0.1 → 1.1.0

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.
Files changed (33) hide show
  1. package/dist/KeepAspectRatioContainer.d.ts +9 -0
  2. package/dist/LikeC4Diagram.css.d.ts +1 -0
  3. package/dist/index.mjs +243 -678
  4. package/dist/state/DiagramContext.d.ts +36 -9
  5. package/dist/state/diagramStore.d.ts +42 -12
  6. package/dist/state/useDiagramStore.d.ts +36 -9
  7. package/dist/style.css +600 -53
  8. package/dist/ui/index.d.ts +0 -1
  9. package/dist/xyflow/{XYFlowWrapper.d.ts → XYFlow.d.ts} +2 -2
  10. package/dist/xyflow/XYFlowEvents.d.ts +127 -13
  11. package/dist/xyflow/edges/RelationshipEdge.d.ts +2 -2
  12. package/dist/xyflow/hooks/useXYFlow.d.ts +20 -20
  13. package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +7 -5
  14. package/dist/xyflow/types.d.ts +2 -2
  15. package/package.json +9 -9
  16. package/src/{ui/KeepAspectRatio.tsx → KeepAspectRatioContainer.tsx} +7 -6
  17. package/src/LikeC4Diagram.css.ts +6 -0
  18. package/src/LikeC4Diagram.tsx +6 -6
  19. package/src/globals.css.ts +42 -37
  20. package/src/state/diagramStore.ts +26 -7
  21. package/src/ui/index.ts +0 -1
  22. package/src/xyflow/FitviewOnDiagramChange.tsx +24 -18
  23. package/src/xyflow/SyncWithDiagram.tsx +16 -10
  24. package/src/xyflow/{XYFlowWrapper.tsx → XYFlow.tsx} +17 -24
  25. package/src/xyflow/XYFlowEvents.tsx +96 -43
  26. package/src/xyflow/diagram-to-xyflow.ts +4 -4
  27. package/src/xyflow/nodes/compound/CompoundNode.css.ts +85 -39
  28. package/src/xyflow/nodes/compound/CompoundNode.tsx +29 -31
  29. package/src/xyflow/nodes/element/ElementNode.tsx +2 -2
  30. package/src/xyflow/nodes/shared/NavigateToBtn.tsx +2 -1
  31. package/dist/ui/KeepAspectRatio.css.d.ts +0 -1
  32. package/dist/ui/KeepAspectRatio.d.ts +0 -9
  33. package/src/ui/KeepAspectRatio.css.ts +0 -7
package/dist/index.mjs CHANGED
@@ -6,12 +6,12 @@ import { createContext, memo, useState, forwardRef, useCallback, useMemo, useEff
6
6
  import { createWithEqualityFn, useStoreWithEqualityFn } from "zustand/traditional";
7
7
  import { shallow } from "zustand/shallow";
8
8
  import { createPortal } from "react-dom";
9
- import { MantineContext, Box, Stack, Text, TooltipGroup, Divider, Flex, Tooltip, ColorSwatch, CheckIcon, rem, Select, Card, ActionIcon, HoverCard, HoverCardTarget, UnstyledButton, HoverCardDropdown, Group, Anchor, CopyButton, Button, useMantineColorScheme } from "@mantine/core";
9
+ import { Box, MantineContext, Stack, Text, TooltipGroup, Divider, Flex, Tooltip, ColorSwatch, CheckIcon, rem, Select, Card, ActionIcon, HoverCard, HoverCardTarget, UnstyledButton, HoverCardDropdown, Group, Anchor, CopyButton, Button, useMantineColorScheme } from "@mantine/core";
10
10
  import { invariant, isAncestor, nonNullable, nonexhaustive, defaultTheme, ElementShapes } from "@likec4/core";
11
11
  import { DEV } from "esm-env";
12
12
  import { shallowEqual, deepEqual } from "fast-equals";
13
13
  import { subscribeWithSelector, devtools } from "zustand/middleware";
14
- import { useFirstMountState, useCustomCompareEffect, useDebouncedState, useRafEffect, useDebouncedEffect } from "@react-hookz/web";
14
+ import { useFirstMountState, useCustomCompareEffect, useDebouncedCallback, useRafEffect, useDebouncedEffect } from "@react-hookz/web";
15
15
  import { AnimatePresence, motion } from "framer-motion";
16
16
  import { isNullish, keys, hasAtLeast, takeWhile, clamp as clamp$1, isNumber } from "remeda";
17
17
  var rootClassName = "likec4-diagram-root";
@@ -874,7 +874,7 @@ function extend(parent, definition) {
874
874
  prototype[key] = definition[key];
875
875
  return prototype;
876
876
  }
877
- function Color$1() {
877
+ function Color() {
878
878
  }
879
879
  var darker = 0.7, brighter = 1 / darker, reI = "\\s*([+-]?\\d+)\\s*", reN = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*", reP = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*", reHex = /^#([0-9a-f]{3,8})$/, reRgbInteger = new RegExp(`^rgb\\(${reI},${reI},${reI}\\)$`), reRgbPercent = new RegExp(`^rgb\\(${reP},${reP},${reP}\\)$`), reRgbaInteger = new RegExp(`^rgba\\(${reI},${reI},${reI},${reN}\\)$`), reRgbaPercent = new RegExp(`^rgba\\(${reP},${reP},${reP},${reN}\\)$`), reHslPercent = new RegExp(`^hsl\\(${reN},${reP},${reP}\\)$`), reHslaPercent = new RegExp(`^hsla\\(${reN},${reP},${reP},${reN}\\)$`), named = {
880
880
  aliceblue: 15792383,
@@ -1026,9 +1026,9 @@ var darker = 0.7, brighter = 1 / darker, reI = "\\s*([+-]?\\d+)\\s*", reN = "\\s
1026
1026
  yellow: 16776960,
1027
1027
  yellowgreen: 10145074
1028
1028
  };
1029
- define(Color$1, color, {
1030
- copy(channels2) {
1031
- return Object.assign(new this.constructor(), this, channels2);
1029
+ define(Color, color, {
1030
+ copy(channels) {
1031
+ return Object.assign(new this.constructor(), this, channels);
1032
1032
  },
1033
1033
  displayable() {
1034
1034
  return this.rgb().displayable();
@@ -1064,7 +1064,7 @@ function rgba(r2, g, b, a) {
1064
1064
  return a <= 0 && (r2 = g = b = NaN), new Rgb(r2, g, b, a);
1065
1065
  }
1066
1066
  function rgbConvert(o) {
1067
- return o instanceof Color$1 || (o = color(o)), o ? (o = o.rgb(), new Rgb(o.r, o.g, o.b, o.opacity)) : new Rgb();
1067
+ return o instanceof Color || (o = color(o)), o ? (o = o.rgb(), new Rgb(o.r, o.g, o.b, o.opacity)) : new Rgb();
1068
1068
  }
1069
1069
  function rgb(r2, g, b, opacity) {
1070
1070
  return arguments.length === 1 ? rgbConvert(r2) : new Rgb(r2, g, b, opacity ?? 1);
@@ -1072,7 +1072,7 @@ function rgb(r2, g, b, opacity) {
1072
1072
  function Rgb(r2, g, b, opacity) {
1073
1073
  this.r = +r2, this.g = +g, this.b = +b, this.opacity = +opacity;
1074
1074
  }
1075
- define(Rgb, rgb, extend(Color$1, {
1075
+ define(Rgb, rgb, extend(Color, {
1076
1076
  brighter(k) {
1077
1077
  return k = k == null ? brighter : Math.pow(brighter, k), new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
1078
1078
  },
@@ -1120,7 +1120,7 @@ function hsla(h, s, l, a) {
1120
1120
  function hslConvert(o) {
1121
1121
  if (o instanceof Hsl)
1122
1122
  return new Hsl(o.h, o.s, o.l, o.opacity);
1123
- if (o instanceof Color$1 || (o = color(o)), !o)
1123
+ if (o instanceof Color || (o = color(o)), !o)
1124
1124
  return new Hsl();
1125
1125
  if (o instanceof Hsl)
1126
1126
  return o;
@@ -1134,7 +1134,7 @@ function hsl(h, s, l, opacity) {
1134
1134
  function Hsl(h, s, l, opacity) {
1135
1135
  this.h = +h, this.s = +s, this.l = +l, this.opacity = +opacity;
1136
1136
  }
1137
- define(Hsl, hsl, extend(Color$1, {
1137
+ define(Hsl, hsl, extend(Color, {
1138
1138
  brighter(k) {
1139
1139
  return k = k == null ? brighter : Math.pow(brighter, k), new Hsl(this.h, this.s, this.l * k, this.opacity);
1140
1140
  },
@@ -1270,7 +1270,7 @@ function interpolateTransform(parse, pxComma, pxParen, degParen) {
1270
1270
  function skewX(a, b, s, q) {
1271
1271
  a !== b ? q.push({ i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: interpolateNumber(a, b) }) : b && s.push(pop(s) + "skewX(" + b + degParen);
1272
1272
  }
1273
- function scale2(xa, ya, xb, yb, s, q) {
1273
+ function scale(xa, ya, xb, yb, s, q) {
1274
1274
  if (xa !== xb || ya !== yb) {
1275
1275
  var i = s.push(pop(s) + "scale(", null, ",", null, ")");
1276
1276
  q.push({ i: i - 4, x: interpolateNumber(xa, xb) }, { i: i - 2, x: interpolateNumber(ya, yb) });
@@ -1279,7 +1279,7 @@ function interpolateTransform(parse, pxComma, pxParen, degParen) {
1279
1279
  }
1280
1280
  return function(a, b) {
1281
1281
  var s = [], q = [];
1282
- return a = parse(a), b = parse(b), translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q), rotate(a.rotate, b.rotate, s, q), skewX(a.skewX, b.skewX, s, q), scale2(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q), a = b = null, function(t) {
1282
+ return a = parse(a), b = parse(b), translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q), rotate(a.rotate, b.rotate, s, q), skewX(a.skewX, b.skewX, s, q), scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q), a = b = null, function(t) {
1283
1283
  for (var i = -1, n = q.length, o; ++i < n; )
1284
1284
  s[(o = q[i]).i] = o.x(t);
1285
1285
  return s.join("");
@@ -2039,7 +2039,7 @@ function zoom() {
2039
2039
  }, zoom2.scaleTo = function(selection2, k, p, event) {
2040
2040
  zoom2.transform(selection2, function() {
2041
2041
  var e = extent.apply(this, arguments), t0 = this.__zoom, p0 = p == null ? centroid(e) : typeof p == "function" ? p.apply(this, arguments) : p, p1 = t0.invert(p0), k1 = typeof k == "function" ? k.apply(this, arguments) : k;
2042
- return constrain(translate(scale2(t0, k1), p0, p1), e, translateExtent);
2042
+ return constrain(translate(scale(t0, k1), p0, p1), e, translateExtent);
2043
2043
  }, p, event);
2044
2044
  }, zoom2.translateBy = function(selection2, x, y, event) {
2045
2045
  zoom2.transform(selection2, function() {
@@ -2057,7 +2057,7 @@ function zoom() {
2057
2057
  ), e, translateExtent);
2058
2058
  }, p, event);
2059
2059
  };
2060
- function scale2(transform2, k) {
2060
+ function scale(transform2, k) {
2061
2061
  return k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], k)), k === transform2.k ? transform2 : new Transform(k, transform2.x, transform2.y);
2062
2062
  }
2063
2063
  function translate(transform2, p0, p1) {
@@ -2131,7 +2131,7 @@ function zoom() {
2131
2131
  return;
2132
2132
  g.mouse = [p, t.invert(p)], interrupt(this), g.start();
2133
2133
  }
2134
- noevent(event), g.wheel = setTimeout(wheelidled, wheelDelay), g.zoom("mouse", constrain(translate(scale2(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent));
2134
+ noevent(event), g.wheel = setTimeout(wheelidled, wheelDelay), g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent));
2135
2135
  function wheelidled() {
2136
2136
  g.wheel = null, g.end();
2137
2137
  }
@@ -2154,7 +2154,7 @@ function zoom() {
2154
2154
  }
2155
2155
  function dblclicked(event, ...args) {
2156
2156
  if (filter2.apply(this, arguments)) {
2157
- var t0 = this.__zoom, p0 = pointer(event.changedTouches ? event.changedTouches[0] : event, this), p1 = t0.invert(p0), k1 = t0.k * (event.shiftKey ? 0.5 : 2), t1 = constrain(translate(scale2(t0, k1), p0, p1), extent.apply(this, args), translateExtent);
2157
+ var t0 = this.__zoom, p0 = pointer(event.changedTouches ? event.changedTouches[0] : event, this), p1 = t0.invert(p0), k1 = t0.k * (event.shiftKey ? 0.5 : 2), t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, args), translateExtent);
2158
2158
  noevent(event), duration > 0 ? select(this).transition().duration(duration).call(schedule2, t1, p0, event) : select(this).call(zoom2.transform, t1, p0, event);
2159
2159
  }
2160
2160
  }
@@ -2175,7 +2175,7 @@ function zoom() {
2175
2175
  t = touches[i], p = pointer(t, this), g.touch0 && g.touch0[2] === t.identifier ? g.touch0[0] = p : g.touch1 && g.touch1[2] === t.identifier && (g.touch1[0] = p);
2176
2176
  if (t = g.that.__zoom, g.touch1) {
2177
2177
  var p0 = g.touch0[0], l0 = g.touch0[1], p1 = g.touch1[0], l1 = g.touch1[1], dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp, dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;
2178
- t = scale2(t, Math.sqrt(dp / dl)), p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2], l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
2178
+ t = scale(t, Math.sqrt(dp / dl)), p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2], l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
2179
2179
  } else if (g.touch0)
2180
2180
  p = g.touch0[0], l = g.touch0[1];
2181
2181
  else
@@ -3625,10 +3625,10 @@ function XYResizer({ domNode, nodeId, getStoreItems, onChange, onEnd }) {
3625
3625
  const { transform: transform2, snapGrid, snapToGrid, nodeOrigin: storeNodeOrigin } = getStoreItems(), pointerPosition = getPointerPosition(event.sourceEvent, { transform: transform2, snapGrid, snapToGrid }), childChanges = [];
3626
3626
  if (!node)
3627
3627
  return;
3628
- const { x: prevX, y: prevY, width: prevWidth, height: prevHeight } = prevValues, change2 = {}, nodeOrigin = node.origin ?? storeNodeOrigin, { width, height, x, y } = getDimensionsAfterResize(startValues, controlDirection, pointerPosition, boundaries, keepAspectRatio, nodeOrigin, parentExtent, childExtent), isWidthChange = width !== prevWidth, isHeightChange = height !== prevHeight, isXPosChange = x !== prevX && isWidthChange, isYPosChange = y !== prevY && isHeightChange;
3628
+ const { x: prevX, y: prevY, width: prevWidth, height: prevHeight } = prevValues, change = {}, nodeOrigin = node.origin ?? storeNodeOrigin, { width, height, x, y } = getDimensionsAfterResize(startValues, controlDirection, pointerPosition, boundaries, keepAspectRatio, nodeOrigin, parentExtent, childExtent), isWidthChange = width !== prevWidth, isHeightChange = height !== prevHeight, isXPosChange = x !== prevX && isWidthChange, isYPosChange = y !== prevY && isHeightChange;
3629
3629
  if (!isXPosChange && !isYPosChange && !isWidthChange && !isHeightChange)
3630
3630
  return;
3631
- if ((isXPosChange || isYPosChange || nodeOrigin[0] === 1 || nodeOrigin[1] == 1) && (change2.x = isXPosChange ? x : prevValues.x, change2.y = isYPosChange ? y : prevValues.y, prevValues.x = change2.x, prevValues.y = change2.y, parentNode && node.expandParent && (change2.x && change2.x < 0 && (prevValues.x = 0, startValues.x = startValues.x - change2.x), change2.y && change2.y < 0 && (prevValues.y = 0, startValues.y = startValues.y - change2.y)), childNodes.length > 0)) {
3631
+ if ((isXPosChange || isYPosChange || nodeOrigin[0] === 1 || nodeOrigin[1] == 1) && (change.x = isXPosChange ? x : prevValues.x, change.y = isYPosChange ? y : prevValues.y, prevValues.x = change.x, prevValues.y = change.y, parentNode && node.expandParent && (change.x && change.x < 0 && (prevValues.x = 0, startValues.x = startValues.x - change.x), change.y && change.y < 0 && (prevValues.y = 0, startValues.y = startValues.y - change.y)), childNodes.length > 0)) {
3632
3632
  const xChange = x - prevX, yChange = y - prevY;
3633
3633
  for (const childNode of childNodes)
3634
3634
  childNode.position = {
@@ -3636,7 +3636,7 @@ function XYResizer({ domNode, nodeId, getStoreItems, onChange, onEnd }) {
3636
3636
  y: childNode.position.y - yChange + nodeOrigin[1] * (height - prevHeight)
3637
3637
  }, childChanges.push(childNode);
3638
3638
  }
3639
- (isWidthChange || isHeightChange) && (change2.width = isWidthChange ? width : prevValues.width, change2.height = isHeightChange ? height : prevValues.height, prevValues.width = change2.width, prevValues.height = change2.height);
3639
+ (isWidthChange || isHeightChange) && (change.width = isWidthChange ? width : prevValues.width, change.height = isHeightChange ? height : prevValues.height, prevValues.width = change.width, prevValues.height = change.height);
3640
3640
  const direction = getResizeDirection({
3641
3641
  width: prevValues.width,
3642
3642
  prevWidth,
@@ -3645,7 +3645,7 @@ function XYResizer({ domNode, nodeId, getStoreItems, onChange, onEnd }) {
3645
3645
  affectsX: controlDirection.affectsX,
3646
3646
  affectsY: controlDirection.affectsY
3647
3647
  }), nextValues = { ...prevValues, direction };
3648
- (shouldResize == null ? void 0 : shouldResize(event, nextValues)) !== !1 && (onResize == null || onResize(event, nextValues), onChange(change2, childChanges));
3648
+ (shouldResize == null ? void 0 : shouldResize(event, nextValues)) !== !1 && (onResize == null || onResize(event, nextValues), onChange(change, childChanges));
3649
3649
  }).on("end", (event) => {
3650
3650
  onResizeEnd == null || onResizeEnd(event, { ...prevValues }), onEnd == null || onEnd();
3651
3651
  });
@@ -3948,15 +3948,15 @@ const useViewportHelper = () => {
3948
3948
  };
3949
3949
  function applyChanges(changes, elements) {
3950
3950
  const updatedElements = [], changesMap = /* @__PURE__ */ new Map();
3951
- for (const change2 of changes)
3952
- if (change2.type === "add") {
3953
- updatedElements.push(change2.item);
3951
+ for (const change of changes)
3952
+ if (change.type === "add") {
3953
+ updatedElements.push(change.item);
3954
3954
  continue;
3955
- } else if (change2.type === "remove" || change2.type === "replace")
3956
- changesMap.set(change2.id, [change2]);
3955
+ } else if (change.type === "remove" || change.type === "replace")
3956
+ changesMap.set(change.id, [change]);
3957
3957
  else {
3958
- const elementChanges = changesMap.get(change2.id);
3959
- elementChanges ? elementChanges.push(change2) : changesMap.set(change2.id, [change2]);
3958
+ const elementChanges = changesMap.get(change.id);
3959
+ elementChanges ? elementChanges.push(change) : changesMap.set(change.id, [change]);
3960
3960
  }
3961
3961
  for (const element of elements) {
3962
3962
  const changes2 = changesMap.get(element.id);
@@ -3971,24 +3971,24 @@ function applyChanges(changes, elements) {
3971
3971
  continue;
3972
3972
  }
3973
3973
  const updatedElement = { ...element };
3974
- for (const change2 of changes2)
3975
- applyChange(change2, updatedElement);
3974
+ for (const change of changes2)
3975
+ applyChange(change, updatedElement);
3976
3976
  updatedElements.push(updatedElement);
3977
3977
  }
3978
3978
  return updatedElements;
3979
3979
  }
3980
- function applyChange(change2, element) {
3981
- switch (change2.type) {
3980
+ function applyChange(change, element) {
3981
+ switch (change.type) {
3982
3982
  case "select": {
3983
- element.selected = change2.selected;
3983
+ element.selected = change.selected;
3984
3984
  break;
3985
3985
  }
3986
3986
  case "position": {
3987
- typeof change2.position < "u" && (element.position = change2.position), typeof change2.dragging < "u" && (element.dragging = change2.dragging);
3987
+ typeof change.position < "u" && (element.position = change.position), typeof change.dragging < "u" && (element.dragging = change.dragging);
3988
3988
  break;
3989
3989
  }
3990
3990
  case "dimensions": {
3991
- typeof change2.dimensions < "u" && (element.measured ?? (element.measured = {}), element.measured.width = change2.dimensions.width, element.measured.height = change2.dimensions.height, change2.setAttributes && (element.width = change2.dimensions.width, element.height = change2.dimensions.height)), typeof change2.resizing == "boolean" && (element.resizing = change2.resizing);
3991
+ typeof change.dimensions < "u" && (element.measured ?? (element.measured = {}), element.measured.width = change.dimensions.width, element.measured.height = change.dimensions.height, change.setAttributes && (element.width = change.dimensions.width, element.height = change.dimensions.height)), typeof change.resizing == "boolean" && (element.resizing = change.resizing);
3992
3992
  break;
3993
3993
  }
3994
3994
  }
@@ -5320,13 +5320,13 @@ const GraphView = memo(GraphViewComponent), getInitialState = ({ nodes, edges, d
5320
5320
  updateNodePositions: (nodeDragItems, dragging = !1) => {
5321
5321
  const parentExpandChildren = [], changes = [];
5322
5322
  for (const [id2, dragItem] of nodeDragItems) {
5323
- const change2 = {
5323
+ const change = {
5324
5324
  id: id2,
5325
5325
  type: "position",
5326
5326
  position: dragItem.position,
5327
5327
  dragging
5328
5328
  };
5329
- dragItem != null && dragItem.expandParent && (dragItem != null && dragItem.parentId) && change2.position && (parentExpandChildren.push({
5329
+ dragItem != null && dragItem.expandParent && (dragItem != null && dragItem.parentId) && change.position && (parentExpandChildren.push({
5330
5330
  id: id2,
5331
5331
  parentId: dragItem.parentId,
5332
5332
  rect: {
@@ -5334,7 +5334,7 @@ const GraphView = memo(GraphViewComponent), getInitialState = ({ nodes, edges, d
5334
5334
  width: dragItem.measured.width,
5335
5335
  height: dragItem.measured.height
5336
5336
  }
5337
- }), change2.position.x = Math.max(0, change2.position.x), change2.position.y = Math.max(0, change2.position.y)), changes.push(change2);
5337
+ }), change.position.x = Math.max(0, change.position.x), change.position.y = Math.max(0, change.position.y)), changes.push(change);
5338
5338
  }
5339
5339
  if (parentExpandChildren.length > 0) {
5340
5340
  const { nodeLookup, parentLookup } = get2(), parentExpandChanges = handleExpandParent(parentExpandChildren, nodeLookup, parentLookup);
@@ -5751,22 +5751,22 @@ function ResizeControl({ nodeId, position, variant = ResizeControlVariant.Handle
5751
5751
  nodeOrigin
5752
5752
  };
5753
5753
  },
5754
- onChange: (change2, childChanges) => {
5755
- const { triggerNodeChanges, nodeLookup, parentLookup, nodeOrigin } = store.getState(), changes = [], nextPosition = { x: change2.x, y: change2.y }, node = nodeLookup.get(id2);
5754
+ onChange: (change, childChanges) => {
5755
+ const { triggerNodeChanges, nodeLookup, parentLookup, nodeOrigin } = store.getState(), changes = [], nextPosition = { x: change.x, y: change.y }, node = nodeLookup.get(id2);
5756
5756
  if (node && node.expandParent && node.parentId) {
5757
5757
  const child = {
5758
5758
  id: node.id,
5759
5759
  parentId: node.parentId,
5760
5760
  rect: {
5761
- width: change2.width ?? node.measured.width,
5762
- height: change2.height ?? node.measured.height,
5761
+ width: change.width ?? node.measured.width,
5762
+ height: change.height ?? node.measured.height,
5763
5763
  ...evaluateAbsolutePosition({
5764
- x: change2.x ?? node.position.x,
5765
- y: change2.y ?? node.position.y
5764
+ x: change.x ?? node.position.x,
5765
+ y: change.y ?? node.position.y
5766
5766
  }, node.parentId, nodeLookup, node.origin ?? nodeOrigin)
5767
5767
  }
5768
5768
  }, parentExpandChanges = handleExpandParent([child], nodeLookup, parentLookup, nodeOrigin);
5769
- changes.push(...parentExpandChanges), nextPosition.x = change2.x ? Math.max(0, change2.x) : void 0, nextPosition.y = change2.y ? Math.max(0, change2.y) : void 0;
5769
+ changes.push(...parentExpandChanges), nextPosition.x = change.x ? Math.max(0, change.x) : void 0, nextPosition.y = change.y ? Math.max(0, change.y) : void 0;
5770
5770
  }
5771
5771
  if (nextPosition.x !== void 0 && nextPosition.y !== void 0) {
5772
5772
  const positionChange = {
@@ -5776,15 +5776,15 @@ function ResizeControl({ nodeId, position, variant = ResizeControlVariant.Handle
5776
5776
  };
5777
5777
  changes.push(positionChange);
5778
5778
  }
5779
- if (change2.width !== void 0 && change2.height !== void 0) {
5779
+ if (change.width !== void 0 && change.height !== void 0) {
5780
5780
  const dimensionChange = {
5781
5781
  id: id2,
5782
5782
  type: "dimensions",
5783
5783
  resizing: !0,
5784
5784
  setAttributes: !0,
5785
5785
  dimensions: {
5786
- width: change2.width,
5787
- height: change2.height
5786
+ width: change.width,
5787
+ height: change.height
5788
5788
  }
5789
5789
  };
5790
5790
  changes.push(dimensionChange);
@@ -5858,7 +5858,30 @@ function clsx() {
5858
5858
  (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
5859
5859
  return n;
5860
5860
  }
5861
- var cssReactFlow = "_2h8g8h0", cssDisablePan = "_2h8g8h1", cssTransparentBg = "_2h8g8h2", cssNoControls = "_2h8g8h3";
5861
+ var keepAspectRatioContainer = "_2h8g8h0", cssReactFlow = "_2h8g8h1", cssDisablePan = "_2h8g8h2", cssTransparentBg = "_2h8g8h3", cssNoControls = "_2h8g8h4";
5862
+ function KeepAspectRatioContainer({
5863
+ children: children2,
5864
+ width,
5865
+ height,
5866
+ enabled,
5867
+ className,
5868
+ style: style2,
5869
+ ...rest
5870
+ }) {
5871
+ return /* @__PURE__ */ jsx(
5872
+ Box,
5873
+ {
5874
+ ...rest,
5875
+ className: clsx(keepAspectRatioContainer, className),
5876
+ style: enabled ? {
5877
+ ...style2,
5878
+ aspectRatio: `${Math.ceil(width)}/${Math.ceil(height)}`,
5879
+ maxHeight: Math.ceil(height)
5880
+ } : style2,
5881
+ children: children2
5882
+ }
5883
+ );
5884
+ }
5862
5885
  function EnsureMantine({ children: children2 }) {
5863
5886
  if (!useContext(MantineContext))
5864
5887
  throw new Error("LikeC4Diagram must be a child of MantineProvider");
@@ -6481,9 +6504,9 @@ class Solver {
6481
6504
  * Update the values of the variables.
6482
6505
  */
6483
6506
  updateVariables() {
6484
- let vars2 = this._varMap, rows = this._rowMap;
6485
- for (let i = 0, n = vars2.size(); i < n; ++i) {
6486
- let pair = vars2.itemAt(i), rowPair = rows.find(pair.second);
6507
+ let vars = this._varMap, rows = this._rowMap;
6508
+ for (let i = 0, n = vars.size(); i < n; ++i) {
6509
+ let pair = vars.itemAt(i), rowPair = rows.find(pair.second);
6487
6510
  rowPair !== void 0 ? pair.first.setValue(rowPair.second.constant()) : pair.first.setValue(0);
6488
6511
  }
6489
6512
  }
@@ -7201,6 +7224,7 @@ const ZIndexes = {
7201
7224
  initialized: !1,
7202
7225
  previousViews: [],
7203
7226
  viewportChanged: !1,
7227
+ focusedNodeId: null,
7204
7228
  hoveredNodeId: null,
7205
7229
  hoveredEdgeId: null,
7206
7230
  lastClickedNodeId: null,
@@ -7230,6 +7254,7 @@ function createDiagramStore(props) {
7230
7254
  view: currentView,
7231
7255
  lastOnNavigate,
7232
7256
  previousViews,
7257
+ focusedNodeId,
7233
7258
  lastClickedNodeId,
7234
7259
  lastClickedEdgeId,
7235
7260
  hoveredEdgeId,
@@ -7239,7 +7264,7 @@ function createDiagramStore(props) {
7239
7264
  DEV && console.debug("store: skip updateView");
7240
7265
  return;
7241
7266
  }
7242
- lastOnNavigate && lastOnNavigate.toView !== view.id && lastOnNavigate.fromView !== view.id && (lastOnNavigate = null), currentView.id === view.id ? (lastClickedNodeId && !containsWithId(view.nodes, lastClickedNodeId) && (lastClickedNodeId = null), hoveredNodeId && !containsWithId(view.nodes, hoveredNodeId) && (hoveredNodeId = null), lastClickedEdgeId && !containsWithId(view.edges, lastClickedEdgeId) && (lastClickedEdgeId = null), hoveredEdgeId && !containsWithId(view.edges, hoveredEdgeId) && (hoveredEdgeId = null)) : (lastClickedEdgeId = null, lastClickedNodeId = null, hoveredEdgeId = null, hoveredNodeId = null, previousViews = [
7267
+ lastOnNavigate && lastOnNavigate.toView !== view.id && lastOnNavigate.fromView !== view.id && (lastOnNavigate = null), currentView.id === view.id ? (lastClickedNodeId && !containsWithId(view.nodes, lastClickedNodeId) && (lastClickedNodeId = null), hoveredNodeId && !containsWithId(view.nodes, hoveredNodeId) && (hoveredNodeId = null), focusedNodeId && !containsWithId(view.nodes, focusedNodeId) && (focusedNodeId = null), lastClickedEdgeId && !containsWithId(view.edges, lastClickedEdgeId) && (lastClickedEdgeId = null), hoveredEdgeId && !containsWithId(view.edges, hoveredEdgeId) && (hoveredEdgeId = null)) : (lastClickedEdgeId = null, lastClickedNodeId = null, hoveredEdgeId = null, hoveredNodeId = null, focusedNodeId = null, previousViews = [
7243
7268
  currentView,
7244
7269
  ...previousViews.filter((v) => v.id !== view.id && v.id !== currentView.id)
7245
7270
  ]), set2(
@@ -7249,6 +7274,7 @@ function createDiagramStore(props) {
7249
7274
  previousViews,
7250
7275
  lastClickedNodeId,
7251
7276
  lastClickedEdgeId,
7277
+ focusedNodeId,
7252
7278
  hoveredEdgeId,
7253
7279
  hoveredNodeId
7254
7280
  },
@@ -7275,18 +7301,18 @@ function createDiagramStore(props) {
7275
7301
  triggerOnChange: (changes) => {
7276
7302
  var _a, _b;
7277
7303
  const newShapes = /* @__PURE__ */ new Map(), newColor = /* @__PURE__ */ new Map();
7278
- for (const change2 of changes) {
7279
- if (change2.op === "change-shape") {
7280
- for (const target of change2.targets)
7281
- newShapes.set(target, change2.shape);
7304
+ for (const change of changes) {
7305
+ if (change.op === "change-shape") {
7306
+ for (const target of change.targets)
7307
+ newShapes.set(target, change.shape);
7282
7308
  continue;
7283
7309
  }
7284
- if (change2.op === "change-color") {
7285
- for (const target of change2.targets)
7286
- newColor.set(target, change2.color);
7310
+ if (change.op === "change-color") {
7311
+ for (const target of change.targets)
7312
+ newColor.set(target, change.color);
7287
7313
  continue;
7288
7314
  }
7289
- nonexhaustive(change2);
7315
+ nonexhaustive(change);
7290
7316
  }
7291
7317
  get2().xyflow.setNodes(
7292
7318
  (nodes) => nodes.map((node) => {
@@ -7345,15 +7371,16 @@ function createDiagramStore(props) {
7345
7371
  xynode.internals.userNode
7346
7372
  );
7347
7373
  },
7348
- fitDiagram: () => {
7349
- const { fitViewPadding, xyflow } = get2();
7374
+ fitDiagram: (centerNode) => {
7375
+ const { fitViewPadding, xyflow, focusedNodeId } = get2();
7350
7376
  xyflow.fitView({
7351
7377
  includeHiddenNodes: !0,
7352
- duration: 400,
7353
- padding: fitViewPadding,
7378
+ duration: centerNode && focusedNodeId ? 300 : 400,
7379
+ padding: centerNode ? 0 : fitViewPadding,
7354
7380
  minZoom: MinZoom,
7355
- maxZoom: 1
7356
- });
7381
+ maxZoom: 1,
7382
+ ...centerNode && { nodes: [centerNode] }
7383
+ }), centerNode && focusedNodeId !== centerNode.id && set2({ focusedNodeId: centerNode.id }, noReplace, "focus node"), !centerNode && focusedNodeId && set2({ focusedNodeId: null }, noReplace, "unfocus");
7357
7384
  }
7358
7385
  }),
7359
7386
  {
@@ -7393,30 +7420,6 @@ function DiagramContextProvider({ children: children2, view, ...props }) {
7393
7420
  [props]
7394
7421
  ), /* @__PURE__ */ jsx(DiagramContext.Provider, { value: store.current, children: children2 });
7395
7422
  }
7396
- var wrapper = "_14qhjro0";
7397
- function KeepAspectRatio({
7398
- children: children2,
7399
- width,
7400
- height,
7401
- enabled,
7402
- className,
7403
- style: style2,
7404
- ...rest
7405
- }) {
7406
- return /* @__PURE__ */ jsx(
7407
- Box,
7408
- {
7409
- ...rest,
7410
- className: clsx(wrapper, className),
7411
- style: enabled ? {
7412
- ...style2,
7413
- aspectRatio: `${Math.ceil(width)}/${Math.ceil(height)}`,
7414
- maxHeight: Math.ceil(height)
7415
- } : style2,
7416
- children: children2
7417
- }
7418
- );
7419
- }
7420
7423
  const {
7421
7424
  primary,
7422
7425
  secondary,
@@ -7660,10 +7663,10 @@ function diagramViewToXYFlowData(view, opts) {
7660
7663
  initialHeight: node.height, */
7661
7664
  width: node.width,
7662
7665
  height: node.height,
7663
- measured: {
7664
- width: node.width,
7665
- height: node.height
7666
- },
7666
+ // measured: {
7667
+ // width: node.width,
7668
+ // height: node.height
7669
+ // },
7667
7670
  ...parent && {
7668
7671
  parentId: ns + parent.id
7669
7672
  }
@@ -7735,21 +7738,25 @@ function FitViewOnViewportResize({ diagramApi }) {
7735
7738
  }
7736
7739
  const diagramChangeId = (s) => s.view.id + "_" + s.view.autoLayout + "_" + s.fitViewPadding;
7737
7740
  function FitViewOnDiagramChanges() {
7738
- const diagramApi = useDiagramStoreApi(), [viewportMoved, setViewportMoved] = useState(diagramApi.getState().viewportChanged), [processedChangeId, setProcessed] = useState(diagramChangeId(diagramApi.getState())), [pendingChangeId, setPending] = useDebouncedState(processedChangeId, 100), isReady = useNodesInitialized({
7741
+ const diagramApi = useDiagramStoreApi(), [viewportMoved, setViewportMoved] = useState(diagramApi.getState().viewportChanged), [processedChangeId, setProcessed] = useState(diagramChangeId(diagramApi.getState())), [pendingChangeId, setPending] = useState(processedChangeId), isReady = useNodesInitialized({
7739
7742
  includeHiddenNodes: !0
7740
- });
7743
+ }), schedulePending = useDebouncedCallback(
7744
+ (pendingChangeId2) => {
7745
+ setPending(pendingChangeId2);
7746
+ },
7747
+ [setPending],
7748
+ 75
7749
+ );
7741
7750
  return useEffect(
7742
7751
  () => diagramApi.subscribe(
7743
- (s) => ({
7744
- viewportMoved: s.viewportChanged,
7745
- changeid: diagramChangeId(s)
7746
- }),
7747
- ({ viewportMoved: viewportMoved2, changeid }) => {
7748
- setPending(changeid), setViewportMoved(viewportMoved2);
7749
- },
7750
- {
7751
- equalityFn: shallowEqual
7752
- }
7752
+ (s) => diagramChangeId(s),
7753
+ schedulePending
7754
+ ),
7755
+ [diagramApi, schedulePending]
7756
+ ), useEffect(
7757
+ () => diagramApi.subscribe(
7758
+ (s) => s.viewportChanged,
7759
+ setViewportMoved
7753
7760
  ),
7754
7761
  [diagramApi]
7755
7762
  ), useRafEffect(
@@ -7764,7 +7771,9 @@ function toDomPrecision(v) {
7764
7771
  return v === null ? 0.01 : Math.round(v * 100) / 100;
7765
7772
  }
7766
7773
  const isSameNode = (a) => (b) => a.id === b.id && a.type === b.type && Object.is(a.parentId, b.parentId), SyncWithDiagram = memo(() => {
7767
- const xyflow = useXYFlow(), xyflowApi = useXYStoreApi(), diagramStoreApi = useDiagramStoreApi();
7774
+ const _xyflow = useXYFlow(), xyflowRef = useRef(_xyflow);
7775
+ xyflowRef.current = _xyflow;
7776
+ const xyflowApi = useXYStoreApi(), diagramStoreApi = useDiagramStoreApi();
7768
7777
  return useEffect(() => diagramStoreApi.subscribe(
7769
7778
  // selector
7770
7779
  (state) => ({
@@ -7777,7 +7786,7 @@ const isSameNode = (a) => (b) => a.id === b.id && a.type === b.type && Object.is
7777
7786
  // listener
7778
7787
  ({ viewId, nodes, edges, ...opts }) => {
7779
7788
  const { lastOnNavigate } = diagramStoreApi.getState(), updates = diagramViewToXYFlowData({ nodes, edges }, opts);
7780
- if (xyflow.setNodes(
7789
+ if (xyflowRef.current.setNodes(
7781
7790
  (prev) => updates.nodes.map((update) => {
7782
7791
  const existing = prev.find(isSameNode(update));
7783
7792
  return existing ? deepEqual(existing.data.element, update.data.element) ? existing : {
@@ -7785,7 +7794,7 @@ const isSameNode = (a) => (b) => a.id === b.id && a.type === b.type && Object.is
7785
7794
  ...update
7786
7795
  } : update;
7787
7796
  })
7788
- ), xyflow.setEdges(
7797
+ ), xyflowRef.current.setEdges(
7789
7798
  (prev) => updates.edges.map((update) => {
7790
7799
  const existing = prev.find((e) => e.id === update.id);
7791
7800
  return existing ? deepEqual(existing.data, update.data) ? existing : {
@@ -7793,19 +7802,20 @@ const isSameNode = (a) => (b) => a.id === b.id && a.type === b.type && Object.is
7793
7802
  ...update
7794
7803
  } : update;
7795
7804
  })
7796
- ), (lastOnNavigate == null ? void 0 : lastOnNavigate.toView) === viewId && !lastOnNavigate.positionCorrected) {
7805
+ ), (lastOnNavigate == null ? void 0 : lastOnNavigate.toView) === viewId && lastOnNavigate.positionCorrected !== !0) {
7797
7806
  const elFrom = lastOnNavigate.element, elTo = nodes.find((n) => n.id === elFrom.id);
7798
7807
  if (elTo) {
7799
- const centerFrom = lastOnNavigate.elementCenterScreenPosition, nextZoom = Math.min(elFrom.width / elTo.width, elFrom.height / elTo.height);
7808
+ const centerFrom = lastOnNavigate.elementCenterScreenPosition;
7809
+ let nextZoom = Math.min(elFrom.width / elTo.width, elFrom.height / elTo.height);
7800
7810
  requestAnimationFrame(() => {
7801
7811
  requestAnimationFrame(() => {
7802
- const v = xyflow.getViewport();
7803
- nextZoom < v.zoom && xyflow.setViewport({
7812
+ const v = xyflowRef.current.getViewport();
7813
+ nextZoom < v.zoom && (nextZoom = Math.max(nextZoom, v.zoom * 0.5), xyflowRef.current.setViewport({
7804
7814
  x: v.x,
7805
7815
  y: v.y,
7806
7816
  zoom: nextZoom
7807
- });
7808
- const centerTo = xyflow.flowToScreenPosition({
7817
+ }));
7818
+ const centerTo = xyflowRef.current.flowToScreenPosition({
7809
7819
  x: elTo.position[0] + elTo.width / 2,
7810
7820
  y: elTo.position[1] + elTo.height / 2
7811
7821
  }), diff = {
@@ -7831,7 +7841,7 @@ const isSameNode = (a) => (b) => a.id === b.id && a.type === b.type && Object.is
7831
7841
  {
7832
7842
  equalityFn: shallowEqual
7833
7843
  }
7834
- ), [xyflow, xyflowApi, diagramStoreApi]), null;
7844
+ ), [xyflowApi, diagramStoreApi]), null;
7835
7845
  });
7836
7846
  function getVarName(variable) {
7837
7847
  var matches = variable.match(/^var\((.*)\)$/);
@@ -7878,7 +7888,7 @@ function assignInlineVars(varsOrContract, tokens) {
7878
7888
  writable: !1
7879
7889
  }), styles;
7880
7890
  }
7881
- var container$1 = "bexn7q0", edgePathBg = "bexn7q1", fillStrokeCtx = "bexn7q2", cssEdgePath = "bexn7q3", varLabelX = "var(--bexn7q4)", varLabelY = "var(--bexn7q5)", edgeLabel = "bexn7q7", edgeLabelBody = "bexn7q8";
7891
+ var container$2 = "bexn7q0", edgePathBg = "bexn7q1", fillStrokeCtx = "bexn7q2", cssEdgePath = "bexn7q3", varLabelX = "var(--bexn7q4)", varLabelY = "var(--bexn7q5)", edgeLabel = "bexn7q7", edgeLabelBody = "bexn7q8";
7882
7892
  function getNodeIntersection(intersectionNode, targetNode) {
7883
7893
  const {
7884
7894
  width: intersectionNodeWidth,
@@ -7973,7 +7983,7 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, b
7973
7983
  });
7974
7984
  edgePath = _edgePath, labelX = _labelX, labelY = _labelY;
7975
7985
  }
7976
- return /* @__PURE__ */ jsxs("g", { className: clsx(container$1), "data-likec4-color": color2, "data-edge-hovered": isHovered, children: [
7986
+ return /* @__PURE__ */ jsxs("g", { className: clsx(container$2), "data-likec4-color": color2, "data-edge-hovered": isHovered, children: [
7977
7987
  /* @__PURE__ */ jsx("g", { className: clsx(fillStrokeCtx), children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
7978
7988
  "marker",
7979
7989
  {
@@ -8003,7 +8013,7 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, b
8003
8013
  data.label && /* @__PURE__ */ jsx(EdgeLabelRenderer, { children: /* @__PURE__ */ jsx(
8004
8014
  Box,
8005
8015
  {
8006
- className: clsx(container$1, edgeLabel),
8016
+ className: clsx(container$2, edgeLabel),
8007
8017
  "data-likec4-color": color2,
8008
8018
  style: {
8009
8019
  ...assignInlineVars({
@@ -8059,475 +8069,7 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, b
8059
8069
  strokeWidth: interactionWidth
8060
8070
  }
8061
8071
  )
8062
- ] })), Channel = {
8063
- /* CLAMP */
8064
- min: {
8065
- r: 0,
8066
- g: 0,
8067
- b: 0,
8068
- s: 0,
8069
- l: 0,
8070
- a: 0
8071
- },
8072
- max: {
8073
- r: 255,
8074
- g: 255,
8075
- b: 255,
8076
- h: 360,
8077
- s: 100,
8078
- l: 100,
8079
- a: 1
8080
- },
8081
- clamp: {
8082
- r: (r2) => r2 >= 255 ? 255 : r2 < 0 ? 0 : r2,
8083
- g: (g) => g >= 255 ? 255 : g < 0 ? 0 : g,
8084
- b: (b) => b >= 255 ? 255 : b < 0 ? 0 : b,
8085
- h: (h) => h % 360,
8086
- s: (s) => s >= 100 ? 100 : s < 0 ? 0 : s,
8087
- l: (l) => l >= 100 ? 100 : l < 0 ? 0 : l,
8088
- a: (a) => a >= 1 ? 1 : a < 0 ? 0 : a
8089
- },
8090
- /* CONVERSION */
8091
- //SOURCE: https://planetcalc.com/7779
8092
- toLinear: (c) => {
8093
- const n = c / 255;
8094
- return c > 0.03928 ? Math.pow((n + 0.055) / 1.055, 2.4) : n / 12.92;
8095
- },
8096
- //SOURCE: https://gist.github.com/mjackson/5311256
8097
- hue2rgb: (p, q, t) => (t < 0 && (t += 1), t > 1 && (t -= 1), t < 1 / 6 ? p + (q - p) * 6 * t : t < 1 / 2 ? q : t < 2 / 3 ? p + (q - p) * (2 / 3 - t) * 6 : p),
8098
- hsl2rgb: ({ h, s, l }, channel) => {
8099
- if (!s)
8100
- return l * 2.55;
8101
- h /= 360, s /= 100, l /= 100;
8102
- const q = l < 0.5 ? l * (1 + s) : l + s - l * s, p = 2 * l - q;
8103
- switch (channel) {
8104
- case "r":
8105
- return Channel.hue2rgb(p, q, h + 1 / 3) * 255;
8106
- case "g":
8107
- return Channel.hue2rgb(p, q, h) * 255;
8108
- case "b":
8109
- return Channel.hue2rgb(p, q, h - 1 / 3) * 255;
8110
- }
8111
- },
8112
- rgb2hsl: ({ r: r2, g, b }, channel) => {
8113
- r2 /= 255, g /= 255, b /= 255;
8114
- const max = Math.max(r2, g, b), min = Math.min(r2, g, b), l = (max + min) / 2;
8115
- if (channel === "l")
8116
- return l * 100;
8117
- if (max === min)
8118
- return 0;
8119
- const d = max - min, s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
8120
- if (channel === "s")
8121
- return s * 100;
8122
- switch (max) {
8123
- case r2:
8124
- return ((g - b) / d + (g < b ? 6 : 0)) * 60;
8125
- case g:
8126
- return ((b - r2) / d + 2) * 60;
8127
- case b:
8128
- return ((r2 - g) / d + 4) * 60;
8129
- default:
8130
- return -1;
8131
- }
8132
- }
8133
- }, Lang = {
8134
- /* API */
8135
- clamp: (number, lower2, upper) => lower2 > upper ? Math.min(lower2, Math.max(upper, number)) : Math.min(upper, Math.max(lower2, number)),
8136
- round: (number) => Math.round(number * 1e10) / 1e10
8137
- }, lang = Lang, Unit = {
8138
- /* API */
8139
- dec2hex: (dec) => {
8140
- const hex2 = Math.round(dec).toString(16);
8141
- return hex2.length > 1 ? hex2 : `0${hex2}`;
8142
- }
8143
- }, unit = Unit, Utils = {
8144
- channel: Channel,
8145
- lang,
8146
- unit
8147
- }, DEC2HEX = {};
8148
- for (let i = 0; i <= 255; i++)
8149
- DEC2HEX[i] = Utils.unit.dec2hex(i);
8150
- const TYPE = {
8151
- ALL: 0,
8152
- RGB: 1,
8153
- HSL: 2
8154
- };
8155
- class Type {
8156
- constructor() {
8157
- this.type = TYPE.ALL;
8158
- }
8159
- /* API */
8160
- get() {
8161
- return this.type;
8162
- }
8163
- set(type) {
8164
- if (this.type && this.type !== type)
8165
- throw new Error("Cannot change both RGB and HSL channels at the same time");
8166
- this.type = type;
8167
- }
8168
- reset() {
8169
- this.type = TYPE.ALL;
8170
- }
8171
- is(type) {
8172
- return this.type === type;
8173
- }
8174
- }
8175
- class Channels {
8176
- /* CONSTRUCTOR */
8177
- constructor(data, color2) {
8178
- this.color = color2, this.changed = !1, this.data = data, this.type = new Type();
8179
- }
8180
- /* API */
8181
- set(data, color2) {
8182
- return this.color = color2, this.changed = !1, this.data = data, this.type.type = TYPE.ALL, this;
8183
- }
8184
- /* HELPERS */
8185
- _ensureHSL() {
8186
- const data = this.data, { h, s, l } = data;
8187
- h === void 0 && (data.h = Utils.channel.rgb2hsl(data, "h")), s === void 0 && (data.s = Utils.channel.rgb2hsl(data, "s")), l === void 0 && (data.l = Utils.channel.rgb2hsl(data, "l"));
8188
- }
8189
- _ensureRGB() {
8190
- const data = this.data, { r: r2, g, b } = data;
8191
- r2 === void 0 && (data.r = Utils.channel.hsl2rgb(data, "r")), g === void 0 && (data.g = Utils.channel.hsl2rgb(data, "g")), b === void 0 && (data.b = Utils.channel.hsl2rgb(data, "b"));
8192
- }
8193
- /* GETTERS */
8194
- get r() {
8195
- const data = this.data, r2 = data.r;
8196
- return !this.type.is(TYPE.HSL) && r2 !== void 0 ? r2 : (this._ensureHSL(), Utils.channel.hsl2rgb(data, "r"));
8197
- }
8198
- get g() {
8199
- const data = this.data, g = data.g;
8200
- return !this.type.is(TYPE.HSL) && g !== void 0 ? g : (this._ensureHSL(), Utils.channel.hsl2rgb(data, "g"));
8201
- }
8202
- get b() {
8203
- const data = this.data, b = data.b;
8204
- return !this.type.is(TYPE.HSL) && b !== void 0 ? b : (this._ensureHSL(), Utils.channel.hsl2rgb(data, "b"));
8205
- }
8206
- get h() {
8207
- const data = this.data, h = data.h;
8208
- return !this.type.is(TYPE.RGB) && h !== void 0 ? h : (this._ensureRGB(), Utils.channel.rgb2hsl(data, "h"));
8209
- }
8210
- get s() {
8211
- const data = this.data, s = data.s;
8212
- return !this.type.is(TYPE.RGB) && s !== void 0 ? s : (this._ensureRGB(), Utils.channel.rgb2hsl(data, "s"));
8213
- }
8214
- get l() {
8215
- const data = this.data, l = data.l;
8216
- return !this.type.is(TYPE.RGB) && l !== void 0 ? l : (this._ensureRGB(), Utils.channel.rgb2hsl(data, "l"));
8217
- }
8218
- get a() {
8219
- return this.data.a;
8220
- }
8221
- /* SETTERS */
8222
- set r(r2) {
8223
- this.type.set(TYPE.RGB), this.changed = !0, this.data.r = r2;
8224
- }
8225
- set g(g) {
8226
- this.type.set(TYPE.RGB), this.changed = !0, this.data.g = g;
8227
- }
8228
- set b(b) {
8229
- this.type.set(TYPE.RGB), this.changed = !0, this.data.b = b;
8230
- }
8231
- set h(h) {
8232
- this.type.set(TYPE.HSL), this.changed = !0, this.data.h = h;
8233
- }
8234
- set s(s) {
8235
- this.type.set(TYPE.HSL), this.changed = !0, this.data.s = s;
8236
- }
8237
- set l(l) {
8238
- this.type.set(TYPE.HSL), this.changed = !0, this.data.l = l;
8239
- }
8240
- set a(a) {
8241
- this.changed = !0, this.data.a = a;
8242
- }
8243
- }
8244
- const Channels$1 = Channels, channels = new Channels$1({ r: 0, g: 0, b: 0, a: 0 }, "transparent"), Hex = {
8245
- /* VARIABLES */
8246
- re: /^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,
8247
- /* API */
8248
- parse: (color2) => {
8249
- if (color2.charCodeAt(0) !== 35)
8250
- return;
8251
- const match = color2.match(Hex.re);
8252
- if (!match)
8253
- return;
8254
- const hex2 = match[1], dec = parseInt(hex2, 16), length = hex2.length, hasAlpha = length % 4 === 0, isFullLength = length > 4, multiplier = isFullLength ? 1 : 17, bits = isFullLength ? 8 : 4, bitsOffset = hasAlpha ? 0 : -1, mask = isFullLength ? 255 : 15;
8255
- return channels.set({
8256
- r: (dec >> bits * (bitsOffset + 3) & mask) * multiplier,
8257
- g: (dec >> bits * (bitsOffset + 2) & mask) * multiplier,
8258
- b: (dec >> bits * (bitsOffset + 1) & mask) * multiplier,
8259
- a: hasAlpha ? (dec & mask) * multiplier / 255 : 1
8260
- }, color2);
8261
- },
8262
- stringify: (channels2) => {
8263
- const { r: r2, g, b, a } = channels2;
8264
- return a < 1 ? `#${DEC2HEX[Math.round(r2)]}${DEC2HEX[Math.round(g)]}${DEC2HEX[Math.round(b)]}${DEC2HEX[Math.round(a * 255)]}` : `#${DEC2HEX[Math.round(r2)]}${DEC2HEX[Math.round(g)]}${DEC2HEX[Math.round(b)]}`;
8265
- }
8266
- }, HSL = {
8267
- /* VARIABLES */
8268
- re: /^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,
8269
- hueRe: /^(.+?)(deg|grad|rad|turn)$/i,
8270
- /* HELPERS */
8271
- _hue2deg: (hue) => {
8272
- const match = hue.match(HSL.hueRe);
8273
- if (match) {
8274
- const [, number, unit2] = match;
8275
- switch (unit2) {
8276
- case "grad":
8277
- return Utils.channel.clamp.h(parseFloat(number) * 0.9);
8278
- case "rad":
8279
- return Utils.channel.clamp.h(parseFloat(number) * 180 / Math.PI);
8280
- case "turn":
8281
- return Utils.channel.clamp.h(parseFloat(number) * 360);
8282
- }
8283
- }
8284
- return Utils.channel.clamp.h(parseFloat(hue));
8285
- },
8286
- /* API */
8287
- parse: (color2) => {
8288
- const charCode = color2.charCodeAt(0);
8289
- if (charCode !== 104 && charCode !== 72)
8290
- return;
8291
- const match = color2.match(HSL.re);
8292
- if (!match)
8293
- return;
8294
- const [, h, s, l, a, isAlphaPercentage] = match;
8295
- return channels.set({
8296
- h: HSL._hue2deg(h),
8297
- s: Utils.channel.clamp.s(parseFloat(s)),
8298
- l: Utils.channel.clamp.l(parseFloat(l)),
8299
- a: a ? Utils.channel.clamp.a(isAlphaPercentage ? parseFloat(a) / 100 : parseFloat(a)) : 1
8300
- }, color2);
8301
- },
8302
- stringify: (channels2) => {
8303
- const { h, s, l, a } = channels2;
8304
- return a < 1 ? `hsla(${Utils.lang.round(h)}, ${Utils.lang.round(s)}%, ${Utils.lang.round(l)}%, ${a})` : `hsl(${Utils.lang.round(h)}, ${Utils.lang.round(s)}%, ${Utils.lang.round(l)}%)`;
8305
- }
8306
- }, Keyword = {
8307
- /* VARIABLES */
8308
- colors: {
8309
- aliceblue: "#f0f8ff",
8310
- antiquewhite: "#faebd7",
8311
- aqua: "#00ffff",
8312
- aquamarine: "#7fffd4",
8313
- azure: "#f0ffff",
8314
- beige: "#f5f5dc",
8315
- bisque: "#ffe4c4",
8316
- black: "#000000",
8317
- blanchedalmond: "#ffebcd",
8318
- blue: "#0000ff",
8319
- blueviolet: "#8a2be2",
8320
- brown: "#a52a2a",
8321
- burlywood: "#deb887",
8322
- cadetblue: "#5f9ea0",
8323
- chartreuse: "#7fff00",
8324
- chocolate: "#d2691e",
8325
- coral: "#ff7f50",
8326
- cornflowerblue: "#6495ed",
8327
- cornsilk: "#fff8dc",
8328
- crimson: "#dc143c",
8329
- cyanaqua: "#00ffff",
8330
- darkblue: "#00008b",
8331
- darkcyan: "#008b8b",
8332
- darkgoldenrod: "#b8860b",
8333
- darkgray: "#a9a9a9",
8334
- darkgreen: "#006400",
8335
- darkgrey: "#a9a9a9",
8336
- darkkhaki: "#bdb76b",
8337
- darkmagenta: "#8b008b",
8338
- darkolivegreen: "#556b2f",
8339
- darkorange: "#ff8c00",
8340
- darkorchid: "#9932cc",
8341
- darkred: "#8b0000",
8342
- darksalmon: "#e9967a",
8343
- darkseagreen: "#8fbc8f",
8344
- darkslateblue: "#483d8b",
8345
- darkslategray: "#2f4f4f",
8346
- darkslategrey: "#2f4f4f",
8347
- darkturquoise: "#00ced1",
8348
- darkviolet: "#9400d3",
8349
- deeppink: "#ff1493",
8350
- deepskyblue: "#00bfff",
8351
- dimgray: "#696969",
8352
- dimgrey: "#696969",
8353
- dodgerblue: "#1e90ff",
8354
- firebrick: "#b22222",
8355
- floralwhite: "#fffaf0",
8356
- forestgreen: "#228b22",
8357
- fuchsia: "#ff00ff",
8358
- gainsboro: "#dcdcdc",
8359
- ghostwhite: "#f8f8ff",
8360
- gold: "#ffd700",
8361
- goldenrod: "#daa520",
8362
- gray: "#808080",
8363
- green: "#008000",
8364
- greenyellow: "#adff2f",
8365
- grey: "#808080",
8366
- honeydew: "#f0fff0",
8367
- hotpink: "#ff69b4",
8368
- indianred: "#cd5c5c",
8369
- indigo: "#4b0082",
8370
- ivory: "#fffff0",
8371
- khaki: "#f0e68c",
8372
- lavender: "#e6e6fa",
8373
- lavenderblush: "#fff0f5",
8374
- lawngreen: "#7cfc00",
8375
- lemonchiffon: "#fffacd",
8376
- lightblue: "#add8e6",
8377
- lightcoral: "#f08080",
8378
- lightcyan: "#e0ffff",
8379
- lightgoldenrodyellow: "#fafad2",
8380
- lightgray: "#d3d3d3",
8381
- lightgreen: "#90ee90",
8382
- lightgrey: "#d3d3d3",
8383
- lightpink: "#ffb6c1",
8384
- lightsalmon: "#ffa07a",
8385
- lightseagreen: "#20b2aa",
8386
- lightskyblue: "#87cefa",
8387
- lightslategray: "#778899",
8388
- lightslategrey: "#778899",
8389
- lightsteelblue: "#b0c4de",
8390
- lightyellow: "#ffffe0",
8391
- lime: "#00ff00",
8392
- limegreen: "#32cd32",
8393
- linen: "#faf0e6",
8394
- magenta: "#ff00ff",
8395
- maroon: "#800000",
8396
- mediumaquamarine: "#66cdaa",
8397
- mediumblue: "#0000cd",
8398
- mediumorchid: "#ba55d3",
8399
- mediumpurple: "#9370db",
8400
- mediumseagreen: "#3cb371",
8401
- mediumslateblue: "#7b68ee",
8402
- mediumspringgreen: "#00fa9a",
8403
- mediumturquoise: "#48d1cc",
8404
- mediumvioletred: "#c71585",
8405
- midnightblue: "#191970",
8406
- mintcream: "#f5fffa",
8407
- mistyrose: "#ffe4e1",
8408
- moccasin: "#ffe4b5",
8409
- navajowhite: "#ffdead",
8410
- navy: "#000080",
8411
- oldlace: "#fdf5e6",
8412
- olive: "#808000",
8413
- olivedrab: "#6b8e23",
8414
- orange: "#ffa500",
8415
- orangered: "#ff4500",
8416
- orchid: "#da70d6",
8417
- palegoldenrod: "#eee8aa",
8418
- palegreen: "#98fb98",
8419
- paleturquoise: "#afeeee",
8420
- palevioletred: "#db7093",
8421
- papayawhip: "#ffefd5",
8422
- peachpuff: "#ffdab9",
8423
- peru: "#cd853f",
8424
- pink: "#ffc0cb",
8425
- plum: "#dda0dd",
8426
- powderblue: "#b0e0e6",
8427
- purple: "#800080",
8428
- rebeccapurple: "#663399",
8429
- red: "#ff0000",
8430
- rosybrown: "#bc8f8f",
8431
- royalblue: "#4169e1",
8432
- saddlebrown: "#8b4513",
8433
- salmon: "#fa8072",
8434
- sandybrown: "#f4a460",
8435
- seagreen: "#2e8b57",
8436
- seashell: "#fff5ee",
8437
- sienna: "#a0522d",
8438
- silver: "#c0c0c0",
8439
- skyblue: "#87ceeb",
8440
- slateblue: "#6a5acd",
8441
- slategray: "#708090",
8442
- slategrey: "#708090",
8443
- snow: "#fffafa",
8444
- springgreen: "#00ff7f",
8445
- tan: "#d2b48c",
8446
- teal: "#008080",
8447
- thistle: "#d8bfd8",
8448
- transparent: "#00000000",
8449
- turquoise: "#40e0d0",
8450
- violet: "#ee82ee",
8451
- wheat: "#f5deb3",
8452
- white: "#ffffff",
8453
- whitesmoke: "#f5f5f5",
8454
- yellow: "#ffff00",
8455
- yellowgreen: "#9acd32"
8456
- },
8457
- /* API */
8458
- parse: (color2) => {
8459
- color2 = color2.toLowerCase();
8460
- const hex2 = Keyword.colors[color2];
8461
- if (hex2)
8462
- return Hex.parse(hex2);
8463
- },
8464
- stringify: (channels2) => {
8465
- const hex2 = Hex.stringify(channels2);
8466
- for (const name in Keyword.colors)
8467
- if (Keyword.colors[name] === hex2)
8468
- return name;
8469
- }
8470
- }, RGB = {
8471
- /* VARIABLES */
8472
- re: /^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,
8473
- /* API */
8474
- parse: (color2) => {
8475
- const charCode = color2.charCodeAt(0);
8476
- if (charCode !== 114 && charCode !== 82)
8477
- return;
8478
- const match = color2.match(RGB.re);
8479
- if (!match)
8480
- return;
8481
- const [, r2, isRedPercentage, g, isGreenPercentage, b, isBluePercentage, a, isAlphaPercentage] = match;
8482
- return channels.set({
8483
- r: Utils.channel.clamp.r(isRedPercentage ? parseFloat(r2) * 2.55 : parseFloat(r2)),
8484
- g: Utils.channel.clamp.g(isGreenPercentage ? parseFloat(g) * 2.55 : parseFloat(g)),
8485
- b: Utils.channel.clamp.b(isBluePercentage ? parseFloat(b) * 2.55 : parseFloat(b)),
8486
- a: a ? Utils.channel.clamp.a(isAlphaPercentage ? parseFloat(a) / 100 : parseFloat(a)) : 1
8487
- }, color2);
8488
- },
8489
- stringify: (channels2) => {
8490
- const { r: r2, g, b, a } = channels2;
8491
- return a < 1 ? `rgba(${Utils.lang.round(r2)}, ${Utils.lang.round(g)}, ${Utils.lang.round(b)}, ${Utils.lang.round(a)})` : `rgb(${Utils.lang.round(r2)}, ${Utils.lang.round(g)}, ${Utils.lang.round(b)})`;
8492
- }
8493
- }, Color = {
8494
- /* VARIABLES */
8495
- format: {
8496
- keyword: Keyword,
8497
- hex: Hex,
8498
- rgb: RGB,
8499
- rgba: RGB,
8500
- hsl: HSL,
8501
- hsla: HSL
8502
- },
8503
- /* API */
8504
- parse: (color2) => {
8505
- if (typeof color2 != "string")
8506
- return color2;
8507
- const channels2 = Hex.parse(color2) || RGB.parse(color2) || HSL.parse(color2) || Keyword.parse(color2);
8508
- if (channels2)
8509
- return channels2;
8510
- throw new Error(`Unsupported color format: "${color2}"`);
8511
- },
8512
- stringify: (channels2) => !channels2.changed && channels2.color ? channels2.color : channels2.type.is(TYPE.HSL) || channels2.data.r === void 0 ? HSL.stringify(channels2) : channels2.a < 1 || !Number.isInteger(channels2.r) || !Number.isInteger(channels2.g) || !Number.isInteger(channels2.b) ? RGB.stringify(channels2) : Hex.stringify(channels2)
8513
- }, change = (color2, channels2) => {
8514
- const ch = Color.parse(color2);
8515
- for (const c in channels2)
8516
- ch[c] = Utils.channel.clamp[c](channels2[c]);
8517
- return Color.stringify(ch);
8518
- }, toHex = (color2) => Color.format.hex.stringify(Color.parse(color2)), adjust = (color2, channels2) => {
8519
- const ch = Color.parse(color2), changes = {};
8520
- for (const c in channels2)
8521
- channels2[c] && (changes[c] = ch[c] + channels2[c]);
8522
- return change(color2, changes);
8523
- }, scale = (color2, channels2) => {
8524
- const ch = Color.parse(color2), adjustments = {}, delta = (amount, weight, max) => weight > 0 ? (max - amount) * weight / 100 : amount * weight / 100;
8525
- for (const c in channels2)
8526
- adjustments[c] = delta(ch[c], channels2[c], Utils.channel.max[c]);
8527
- return adjust(color2, adjustments);
8528
- };
8529
- var vars = { default: { font: "var(--likec4-default-font-family)" }, likec4: { font: "var(--likec4-font-family)", background: { color: "var(--likec4-background-color)", pattern: { color: "var(--likec4-background-pattern-color)" } } }, compound: { font: "var(--likec4-compound-font-family)", titleColor: "var(--likec4-compound-title-color)" }, element: { font: "var(--likec4-element-font-family)", fill: "var(--likec4-element-fill)", stroke: "var(--likec4-element-stroke)", hiContrast: "var(--likec4-element-hiContrast)", loContrast: "var(--likec4-element-loContrast)" }, relation: { lineColor: "var(--likec4-relation-lineColor)", labelColor: "var(--likec4-relation-labelColor)", labelBgColor: "var(--likec4-relation-labelBg)" }, optionsPanel: { top: "var(--likec4-options-panel-top)", right: "var(--likec4-options-panel-right)" } };
8530
- const Link = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
8072
+ ] })), Link = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
8531
8073
  "svg",
8532
8074
  {
8533
8075
  ref,
@@ -8581,48 +8123,45 @@ function NavigateToBtn({ xynodeId, className }) {
8581
8123
  className: clsx("nodrag nopan", className),
8582
8124
  radius: "xl",
8583
8125
  onClick: (event) => {
8584
- diagramApi.getState().triggerOnNavigateTo(xynodeId, event), event.stopPropagation();
8126
+ event.stopPropagation(), diagramApi.getState().triggerOnNavigateTo(xynodeId, event);
8585
8127
  },
8128
+ onDoubleClick: (event) => event.stopPropagation(),
8586
8129
  children: /* @__PURE__ */ jsx(ZoomIn, {})
8587
8130
  }
8588
8131
  );
8589
8132
  }
8590
- var cssContainer = "lbtzdo0", cssCompound = "lbtzdo2", cssTitle = "lbtzdo4", cssIndicator = "lbtzdo6", cssNavigateBtn$1 = "lbtzdo7";
8591
- const compoundColor = (color2, depth) => toHex(
8592
- scale(color2, {
8593
- l: -35 - 5 * depth,
8594
- s: -15 - 5 * depth
8595
- })
8596
- ), CompoundNodeMemo = /* @__PURE__ */ memo(function({
8133
+ var container$1 = "lbtzdo0", varTransparency = "var(--lbtzdo1)", compoundBody = "lbtzdo2", transparent = "lbtzdo5", title$1 = "lbtzdo6", indicator$1 = "lbtzdoa", navigateBtn = "lbtzdoc";
8134
+ const CompoundNodeMemo = /* @__PURE__ */ memo(function({
8597
8135
  id: id2,
8598
8136
  data: {
8599
8137
  element
8600
8138
  }
8601
8139
  }) {
8602
- const { color: color2, depth = 0, ...compound } = element, colors2 = useMemo(() => {
8603
- const colors22 = defaultTheme.elements[color2];
8604
- return {
8605
- fill: compoundColor(colors22.fill, depth),
8606
- stroke: compoundColor(colors22.stroke, depth)
8607
- };
8608
- }, [color2, depth]), { isHovered, hasOnNavigateTo } = useDiagramState((s) => ({
8140
+ const { color: color2, style: style2, depth = 1, ...compound } = element, opacity = style2.opacity ?? 100, { isHovered, hasOnNavigateTo } = useDiagramState((s) => ({
8609
8141
  isHovered: s.hoveredNodeId === id2,
8610
8142
  hasOnNavigateTo: !!s.onNavigateTo
8611
- })), isnavigable = !!compound.navigateTo && hasOnNavigateTo;
8143
+ })), isnavigable = !!compound.navigateTo && hasOnNavigateTo, transparency = clamp$1(100 - opacity, {
8144
+ min: 0,
8145
+ max: 98
8146
+ });
8612
8147
  return /* @__PURE__ */ jsxs(
8613
8148
  Box,
8614
8149
  {
8615
- className: clsx(cssContainer, "likec4-compound-node"),
8616
- style: assignInlineVars({ fill: vars.element.fill, stroke: vars.element.stroke }, {
8617
- fill: colors2.fill,
8618
- stroke: colors2.stroke
8619
- }),
8150
+ className: clsx(
8151
+ container$1,
8152
+ "likec4-compound-node",
8153
+ opacity < 100 && "likec4-compound-transparent"
8154
+ ),
8620
8155
  mod: {
8156
+ "compound-depth": depth,
8621
8157
  "likec4-color": color2,
8622
8158
  "likec4-shape": compound.shape,
8623
8159
  "likec4-navigable": isnavigable,
8624
8160
  hovered: isHovered
8625
8161
  },
8162
+ style: assignInlineVars({
8163
+ [varTransparency]: transparency + "%"
8164
+ }),
8626
8165
  children: [
8627
8166
  /* @__PURE__ */ jsx(
8628
8167
  Handle,
@@ -8632,7 +8171,7 @@ const compoundColor = (color2, depth) => toHex(
8632
8171
  style: { visibility: "hidden" }
8633
8172
  }
8634
8173
  ),
8635
- /* @__PURE__ */ jsx("svg", { className: cssIndicator, children: /* @__PURE__ */ jsx(
8174
+ /* @__PURE__ */ jsx("svg", { className: indicator$1, children: /* @__PURE__ */ jsx(
8636
8175
  "rect",
8637
8176
  {
8638
8177
  x: 0,
@@ -8642,15 +8181,24 @@ const compoundColor = (color2, depth) => toHex(
8642
8181
  rx: 6
8643
8182
  }
8644
8183
  ) }),
8645
- /* @__PURE__ */ jsx("div", { className: clsx(cssCompound, "likec4-compound"), children: /* @__PURE__ */ jsx(
8646
- Text,
8184
+ /* @__PURE__ */ jsx(
8185
+ "div",
8647
8186
  {
8648
- component: "div",
8649
- className: clsx(cssTitle, "likec4-compound-title"),
8650
- children: compound.title
8187
+ className: clsx(compoundBody, opacity < 100 && transparent, "likec4-compound"),
8188
+ style: {
8189
+ borderStyle: opacity < 100 ? style2.border : void 0
8190
+ },
8191
+ children: /* @__PURE__ */ jsx(
8192
+ Text,
8193
+ {
8194
+ component: "div",
8195
+ className: clsx(title$1, "likec4-compound-title"),
8196
+ children: compound.title
8197
+ }
8198
+ )
8651
8199
  }
8652
- ) }),
8653
- isnavigable && /* @__PURE__ */ jsx(NavigateToBtn, { xynodeId: id2, className: cssNavigateBtn$1 }),
8200
+ ),
8201
+ isnavigable && /* @__PURE__ */ jsx(NavigateToBtn, { xynodeId: id2, className: navigateBtn }),
8654
8202
  /* @__PURE__ */ jsx(
8655
8203
  Handle,
8656
8204
  {
@@ -8888,16 +8436,16 @@ function SelectedIndicator({ shape, w, h }) {
8888
8436
  }
8889
8437
  }
8890
8438
  const selectedScale = 1.015, variants = {
8891
- idle: (_, { scale: scale2 }) => ({
8439
+ idle: (_, { scale }) => ({
8892
8440
  scale: 1,
8893
8441
  transition: {
8894
- delay: isNumber(scale2) && scale2 > selectedScale ? 0.075 : 0
8442
+ delay: isNumber(scale) && scale > selectedScale ? 0.075 : 0
8895
8443
  }
8896
8444
  }),
8897
- selected: (_, { scale: scale2 }) => ({
8445
+ selected: (_, { scale }) => ({
8898
8446
  scale: selectedScale,
8899
8447
  transition: {
8900
- delay: isNumber(scale2) && scale2 > selectedScale ? 0.075 : 0
8448
+ delay: isNumber(scale) && scale > selectedScale ? 0.075 : 0
8901
8449
  }
8902
8450
  }),
8903
8451
  // dragging: {
@@ -8914,10 +8462,10 @@ const selectedScale = 1.015, variants = {
8914
8462
  // delay: 1
8915
8463
  // }
8916
8464
  // }),
8917
- hovered: (_, { scale: scale2 }) => ({
8465
+ hovered: (_, { scale }) => ({
8918
8466
  scale: 1.06,
8919
8467
  transition: {
8920
- delay: isNumber(scale2) && scale2 !== 1 && scale2 !== selectedScale ? 0 : 0.15
8468
+ delay: isNumber(scale) && scale !== 1 && scale !== selectedScale ? 0 : 0.15
8921
8469
  }
8922
8470
  }),
8923
8471
  tap: {
@@ -8939,7 +8487,7 @@ function ElementNode({
8939
8487
  }) {
8940
8488
  const { isHovered, hasOnNavigateTo, isHovercards, isInteractive } = useDiagramState((s) => ({
8941
8489
  isHovered: s.hoveredNodeId === id2,
8942
- isInteractive: s.nodesDraggable || s.nodesSelectable,
8490
+ isInteractive: s.nodesDraggable || s.nodesSelectable || !!s.onNavigateTo,
8943
8491
  isHovercards: s.showElementLinks,
8944
8492
  hasOnNavigateTo: !!s.onNavigateTo
8945
8493
  })), isNavigable = hasOnNavigateTo && !!element.navigateTo, w = toDomPrecision(width ?? element.width), h = toDomPrecision(height ?? element.height);
@@ -8951,7 +8499,7 @@ function ElementNode({
8951
8499
  case dragging:
8952
8500
  animate = "idle";
8953
8501
  break;
8954
- case ((isInteractive || hasOnNavigateTo) && isHovered):
8502
+ case (isInteractive && isHovered):
8955
8503
  animate = "hovered";
8956
8504
  break;
8957
8505
  case selected2:
@@ -9067,31 +8615,32 @@ const XYFlowBackground = memo(({ background }) => {
9067
8615
  return /* @__PURE__ */ jsx(Background, { variant: literalToEnum(variant), ...rest });
9068
8616
  }, deepEqual);
9069
8617
  function useXYFlowEvents() {
9070
- const diagramApi = useDiagramStoreApi(), xyflowApi = useXYStoreApi(), dblclickTimeout = useRef();
8618
+ const diagramApi = useDiagramStoreApi(), xyflowApi = useXYStoreApi(), dblclickTimeout = useRef(), dbclickGuarg = () => dblclickTimeout.current !== void 0 ? !0 : (dblclickTimeout.current = window.setTimeout(() => {
8619
+ dblclickTimeout.current = void 0;
8620
+ }, 250), !1);
9071
8621
  return useMemo(() => ({
9072
- onPaneClick: (event) => {
9073
- var _a;
9074
- diagramApi.setState(
9075
- {
9076
- lastClickedNodeId: null,
9077
- lastClickedEdgeId: null
9078
- },
9079
- !1,
9080
- "onPaneClick"
9081
- );
8622
+ onDoubleClick: (event) => {
8623
+ diagramApi.getState().setLastClickedNode(null), diagramApi.getState().setLastClickedEdge(null);
9082
8624
  const diagramState = diagramApi.getState();
9083
- if (dblclickTimeout.current) {
9084
- if (window.clearTimeout(dblclickTimeout.current), dblclickTimeout.current = void 0, diagramState.onCanvasDblClick) {
9085
- diagramState.onCanvasDblClick(event);
9086
- return;
9087
- }
9088
- (_a = diagramState.onCanvasClick) == null || _a.call(diagramState, event), diagramState.fitViewEnabled && diagramState.viewportChanged && diagramState.fitDiagram();
8625
+ if (diagramState.onCanvasDblClick) {
8626
+ diagramState.onCanvasDblClick(event);
8627
+ return;
8628
+ }
8629
+ if (diagramState.fitViewEnabled && diagramState.zoomable) {
8630
+ diagramState.fitDiagram(), event.stopPropagation();
9089
8631
  return;
9090
8632
  }
9091
- dblclickTimeout.current = window.setTimeout(() => {
9092
- var _a2, _b;
9093
- dblclickTimeout.current = void 0, (_b = (_a2 = diagramApi.getState()).onCanvasClick) == null || _b.call(_a2, event);
9094
- }, 300);
8633
+ },
8634
+ onPaneClick: (event) => {
8635
+ if (dbclickGuarg())
8636
+ return;
8637
+ diagramApi.getState().setLastClickedNode(null), diagramApi.getState().setLastClickedEdge(null);
8638
+ const { focusedNodeId, fitDiagram, onCanvasClick } = diagramApi.getState();
8639
+ if (onCanvasClick) {
8640
+ onCanvasClick(event);
8641
+ return;
8642
+ }
8643
+ focusedNodeId && (fitDiagram(), event.stopPropagation());
9095
8644
  },
9096
8645
  onNodeContextMenu: (event, xynode) => {
9097
8646
  var _a, _b;
@@ -9114,12 +8663,21 @@ function useXYFlowEvents() {
9114
8663
  });
9115
8664
  },
9116
8665
  onNodeClick: (event, xynode) => {
9117
- var _a, _b;
9118
- diagramApi.getState().setLastClickedNode(xynode.id), (_b = (_a = diagramApi.getState()).onNodeClick) == null || _b.call(_a, {
9119
- element: xynode.data.element,
9120
- xynode,
9121
- event
9122
- });
8666
+ diagramApi.getState().setLastClickedNode(xynode.id);
8667
+ const { focusedNodeId, fitDiagram, onNodeClick } = diagramApi.getState();
8668
+ if (onNodeClick) {
8669
+ onNodeClick({
8670
+ element: xynode.data.element,
8671
+ xynode,
8672
+ event
8673
+ });
8674
+ return;
8675
+ }
8676
+ focusedNodeId && focusedNodeId !== xynode.id && (fitDiagram(xynode), event.stopPropagation());
8677
+ },
8678
+ onNodeDoubleClick: (event, xynode) => {
8679
+ const { zoomable, fitDiagram, onNodeClick } = diagramApi.getState();
8680
+ onNodeClick || zoomable && (fitDiagram(xynode), event.stopPropagation());
9123
8681
  },
9124
8682
  onEdgeClick: (event, xyedge) => {
9125
8683
  var _a, _b;
@@ -9132,6 +8690,18 @@ function useXYFlowEvents() {
9132
8690
  onMoveEnd: (event, _viewport) => {
9133
8691
  const viewportChanged = !!event;
9134
8692
  viewportChanged !== diagramApi.getState().viewportChanged && diagramApi.setState({ viewportChanged }, !1, `viewport-changed: ${viewportChanged}`);
8693
+ },
8694
+ onNodeMouseEnter: (event, xynode) => {
8695
+ diagramApi.getState().setHoveredNode(xynode.id);
8696
+ },
8697
+ onNodeMouseLeave: (event, xynode) => {
8698
+ diagramApi.getState().setHoveredNode(null);
8699
+ },
8700
+ onEdgeMouseEnter: (event, xyedge) => {
8701
+ diagramApi.getState().setHoveredEdge(xyedge.id);
8702
+ },
8703
+ onEdgeMouseLeave: (event, xyedge) => {
8704
+ diagramApi.getState().setHoveredEdge(null);
9135
8705
  }
9136
8706
  }), [diagramApi, xyflowApi]);
9137
8707
  }
@@ -9151,15 +8721,14 @@ const nodeTypes = {
9151
8721
  hasOnCanvasContextMenu: !!s.onCanvasContextMenu,
9152
8722
  hasOnEdgeContextMenu: !!s.onEdgeContextMenu,
9153
8723
  hasOnEdgeClick: !!s.onEdgeClick,
9154
- hasOnCanvasClick: !!s.onCanvasClick || !!s.onCanvasDblClick
8724
+ zoomable: s.zoomable,
8725
+ pannable: s.pannable
9155
8726
  });
9156
8727
  function XYFlowWrapper({
9157
8728
  className,
9158
8729
  children: children2,
9159
8730
  defaultNodes,
9160
8731
  defaultEdges,
9161
- pannable,
9162
- zoomable,
9163
8732
  controls,
9164
8733
  background,
9165
8734
  style: style2
@@ -9169,6 +8738,8 @@ function XYFlowWrapper({
9169
8738
  nodesDraggable,
9170
8739
  fitView: fitView2,
9171
8740
  fitViewPadding,
8741
+ pannable,
8742
+ zoomable,
9172
8743
  ...editor
9173
8744
  } = useDiagramState(selector), layoutConstraints = useLayoutConstraints(), handlers = useXYFlowEvents(), isBgWithPattern = background !== "transparent" && background !== "solid", { colorScheme } = useMantineColorScheme(), colorMode = colorScheme !== "auto" ? colorScheme : void 0;
9174
8745
  return /* @__PURE__ */ jsxs(
@@ -9208,33 +8779,27 @@ function XYFlowWrapper({
9208
8779
  selectionKeyCode: null
9209
8780
  },
9210
8781
  nodesDraggable,
9211
- ...nodesDraggable && layoutConstraints,
8782
+ ...nodesDraggable && {
8783
+ onNodeDragStart: layoutConstraints.onNodeDragStart,
8784
+ onNodeDrag: layoutConstraints.onNodeDrag,
8785
+ onNodeDragStop: layoutConstraints.onNodeDragStop
8786
+ },
9212
8787
  zoomOnDoubleClick: !1,
9213
8788
  elevateNodesOnSelect: !1,
9214
8789
  selectNodesOnDrag: !1,
8790
+ onDoubleClick: handlers.onDoubleClick,
9215
8791
  onPaneClick: handlers.onPaneClick,
9216
- ...editor.hasOnNodeClick && {
9217
- onNodeClick: handlers.onNodeClick
9218
- },
9219
- ...editor.hasOnEdgeClick && {
9220
- onEdgeClick: handlers.onEdgeClick
9221
- },
9222
8792
  onMoveEnd: handlers.onMoveEnd,
8793
+ onNodeMouseEnter: handlers.onNodeMouseEnter,
8794
+ onNodeMouseLeave: handlers.onNodeMouseLeave,
8795
+ onEdgeMouseEnter: handlers.onEdgeMouseEnter,
8796
+ onEdgeMouseLeave: handlers.onEdgeMouseLeave,
8797
+ onNodeClick: handlers.onNodeClick,
8798
+ onNodeDoubleClick: handlers.onNodeDoubleClick,
8799
+ onEdgeClick: handlers.onEdgeClick,
9223
8800
  onInit: () => {
9224
8801
  diagramApi.setState({ initialized: !0 }, !1, "initialized");
9225
8802
  },
9226
- onNodeMouseEnter: (_event, node) => {
9227
- diagramApi.getState().setHoveredNode(node.id);
9228
- },
9229
- onNodeMouseLeave: () => {
9230
- diagramApi.getState().setHoveredNode(null);
9231
- },
9232
- onEdgeMouseEnter: (_event, edge) => {
9233
- diagramApi.getState().setHoveredEdge(edge.id);
9234
- },
9235
- onEdgeMouseLeave: () => {
9236
- diagramApi.getState().setHoveredEdge(null);
9237
- },
9238
8803
  ...editor.hasOnNodeContextMenu && {
9239
8804
  onNodeContextMenu: handlers.onNodeContextMenu
9240
8805
  },
@@ -9302,6 +8867,8 @@ function LikeC4Diagram({
9302
8867
  {
9303
8868
  view,
9304
8869
  readonly,
8870
+ pannable,
8871
+ zoomable,
9305
8872
  fitViewEnabled: fitView2,
9306
8873
  fitViewPadding,
9307
8874
  showElementLinks,
@@ -9318,7 +8885,7 @@ function LikeC4Diagram({
9318
8885
  onCanvasDblClick,
9319
8886
  children: [
9320
8887
  /* @__PURE__ */ jsx(
9321
- KeepAspectRatio,
8888
+ KeepAspectRatioContainer,
9322
8889
  {
9323
8890
  className: clsx(rootClassName, className),
9324
8891
  enabled: keepAspectRatio,
@@ -9338,8 +8905,6 @@ function LikeC4Diagram({
9338
8905
  controls,
9339
8906
  defaultNodes: initialRef.current.defaultNodes,
9340
8907
  defaultEdges: initialRef.current.defaultEdges,
9341
- pannable,
9342
- zoomable,
9343
8908
  children: readonly !== !0 && /* @__PURE__ */ jsx(OptionsPanel2, {})
9344
8909
  }
9345
8910
  )