@likec4/diagram 1.20.1 → 1.20.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.
Files changed (129) hide show
  1. package/dist/LikeC4Diagram.css.d.ts +1 -0
  2. package/dist/LikeC4Diagram.css.js +3 -1
  3. package/dist/base/BaseXYFlow.js +15 -14
  4. package/dist/base/Link.css.d.ts +3 -0
  5. package/dist/base/Link.css.js +9 -0
  6. package/dist/base/Link.d.ts +5 -0
  7. package/dist/base/Link.js +58 -0
  8. package/dist/base/const.d.ts +1 -0
  9. package/dist/base/const.js +2 -1
  10. package/dist/base/example/custom.d.ts +1 -1
  11. package/dist/base/index.d.ts +1 -0
  12. package/dist/base/primitives/compound/CompoundActionButton.js +2 -1
  13. package/dist/base/primitives/compound/CompoundDetailsButton.js +2 -1
  14. package/dist/base/primitives/compound/CompoundNodeContainer.css.d.ts +0 -1
  15. package/dist/base/primitives/compound/CompoundNodeContainer.css.js +4 -6
  16. package/dist/base/primitives/compound/CompoundNodeContainer.js +2 -2
  17. package/dist/base/primitives/customEdge.d.ts +1 -1
  18. package/dist/base/primitives/customEdge.js +1 -1
  19. package/dist/base/primitives/customNode.js +1 -1
  20. package/dist/base/primitives/edge/EdgeLabel.js +3 -1
  21. package/dist/base/primitives/edge/EdgePath.d.ts +2 -1
  22. package/dist/base/primitives/edge/EdgePath.js +2 -0
  23. package/dist/base/primitives/element/ElementActionButtons.js +2 -1
  24. package/dist/base/primitives/element/ElementDetailsButton.js +2 -1
  25. package/dist/base/primitives/element/ElementNodeContainer.css.d.ts +0 -1
  26. package/dist/base/primitives/element/ElementNodeContainer.css.js +1 -3
  27. package/dist/base/primitives/element/ElementNodeContainer.js +2 -3
  28. package/dist/base/primitives/element/ElementShape.js +4 -2
  29. package/dist/base/primitives/element/ElementTitle.js +2 -1
  30. package/dist/base/updateEdges.js +3 -3
  31. package/dist/base/updateNodes.js +2 -2
  32. package/dist/context/FramerMotionConfig.js +1 -1
  33. package/dist/hooks/useDiagram.d.ts +313 -90
  34. package/dist/hooks/useDiagramActor.d.ts +2 -2
  35. package/dist/hooks/useDiagramContext.d.ts +1 -1
  36. package/dist/hooks/useXYFlow.d.ts +2 -1
  37. package/dist/hooks/useXYFlow.js +5 -0
  38. package/dist/likec4diagram/XYFlow.js +12 -10
  39. package/dist/likec4diagram/custom/edges/RelationshipEdge.d.ts +1 -1
  40. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.js +2 -2
  41. package/dist/likec4diagram/custom/index.d.ts +1 -1
  42. package/dist/likec4diagram/custom/nodes/nodeTypes.js +2 -2
  43. package/dist/likec4diagram/state/actorContext.d.ts +1438 -364
  44. package/dist/likec4diagram/state/assign.js +2 -2
  45. package/dist/likec4diagram/state/machine.d.ts +321 -93
  46. package/dist/likec4diagram/state/syncManualLayoutActor.d.ts +1 -1
  47. package/dist/likec4diagram/types.d.ts +1 -0
  48. package/dist/likec4diagram/ui/diagram-title/DiagramTitlePanel.js +4 -3
  49. package/dist/likec4diagram/useViewToNodesEdges.js +3 -1
  50. package/dist/overlays/element-details/ElementDetailsCard.css.d.ts +0 -1
  51. package/dist/overlays/element-details/ElementDetailsCard.css.js +1 -3
  52. package/dist/overlays/element-details/ElementDetailsCard.js +5 -30
  53. package/dist/overlays/relationship-details/RelationshipDetails.js +4 -4
  54. package/dist/overlays/relationship-details/custom/ElementActions.js +1 -3
  55. package/dist/overlays/relationship-details/custom/edgeTypes.d.ts +1 -1
  56. package/dist/overlays/relationship-details/hooks.d.ts +2 -2
  57. package/dist/overlays/relationship-details/hooks.js +7 -7
  58. package/dist/overlays/relationship-details/useLayoutedDetails.js +7 -10
  59. package/dist/overlays/relationships-browser/-useRelationshipsView.d.ts +4 -1
  60. package/dist/overlays/relationships-browser/-useRelationshipsView.js +12 -11
  61. package/dist/overlays/relationships-browser/RelationshipsBrowser.js +81 -66
  62. package/dist/overlays/relationships-browser/_types.d.ts +2 -1
  63. package/dist/overlays/relationships-browser/actor.d.ts +15 -2
  64. package/dist/overlays/relationships-browser/actor.js +262 -65
  65. package/dist/overlays/relationships-browser/const.d.ts +1 -0
  66. package/dist/overlays/relationships-browser/const.js +4 -0
  67. package/dist/overlays/relationships-browser/custom/ElementActions.js +1 -1
  68. package/dist/overlays/relationships-browser/custom/edgeTypes.d.ts +3 -2
  69. package/dist/overlays/relationships-browser/custom/edgeTypes.js +24 -6
  70. package/dist/overlays/relationships-browser/custom/nodeTypes.js +3 -2
  71. package/dist/overlays/relationships-browser/hooks.d.ts +6 -3
  72. package/dist/overlays/relationships-browser/hooks.js +4 -2
  73. package/dist/overlays/relationships-browser/useViewToNodesEdges.js +7 -2
  74. package/dist/style.css +1 -1
  75. package/dist/utils/xyflow.js +9 -1
  76. package/package.json +8 -8
  77. package/src/LikeC4Diagram.css.ts +8 -0
  78. package/src/base/BaseXYFlow.tsx +23 -14
  79. package/src/base/Link.css.ts +49 -0
  80. package/src/base/Link.tsx +66 -0
  81. package/src/base/const.ts +1 -0
  82. package/src/base/index.ts +2 -0
  83. package/src/base/primitives/compound/CompoundActionButton.tsx +2 -1
  84. package/src/base/primitives/compound/CompoundDetailsButton.tsx +2 -1
  85. package/src/base/primitives/compound/CompoundNodeContainer.css.ts +16 -10
  86. package/src/base/primitives/compound/CompoundNodeContainer.tsx +1 -1
  87. package/src/base/primitives/customEdge.ts +2 -0
  88. package/src/base/primitives/customNode.ts +3 -0
  89. package/src/base/primitives/edge/EdgeLabel.tsx +3 -1
  90. package/src/base/primitives/edge/EdgePath.tsx +3 -0
  91. package/src/base/primitives/element/ElementActionButtons.tsx +2 -1
  92. package/src/base/primitives/element/ElementDetailsButton.tsx +2 -1
  93. package/src/base/primitives/element/ElementNodeContainer.css.ts +9 -4
  94. package/src/base/primitives/element/ElementNodeContainer.tsx +1 -2
  95. package/src/base/primitives/element/ElementShape.tsx +4 -3
  96. package/src/base/primitives/element/ElementTitle.tsx +2 -1
  97. package/src/base/updateEdges.ts +3 -2
  98. package/src/base/updateNodes.ts +3 -2
  99. package/src/context/DiagramFeatures.tsx +1 -0
  100. package/src/context/FramerMotionConfig.tsx +1 -1
  101. package/src/hooks/useDiagramActor.ts +7 -5
  102. package/src/hooks/useDiagramContext.ts +4 -1
  103. package/src/hooks/useXYFlow.ts +6 -1
  104. package/src/likec4diagram/XYFlow.tsx +20 -9
  105. package/src/likec4diagram/custom/edges/RelationshipsDropdownMenu.tsx +2 -2
  106. package/src/likec4diagram/custom/nodes/nodeTypes.tsx +2 -2
  107. package/src/likec4diagram/types.ts +1 -0
  108. package/src/likec4diagram/ui/diagram-title/DiagramTitlePanel.tsx +4 -3
  109. package/src/likec4diagram/useViewToNodesEdges.ts +1 -0
  110. package/src/overlays/element-details/ElementDetailsCard.css.ts +0 -28
  111. package/src/overlays/element-details/ElementDetailsCard.tsx +2 -50
  112. package/src/overlays/relationship-details/RelationshipDetails.tsx +4 -4
  113. package/src/overlays/relationship-details/custom/ElementActions.tsx +1 -2
  114. package/src/overlays/relationship-details/custom/edgeTypes.tsx +0 -5
  115. package/src/overlays/relationship-details/hooks.ts +6 -6
  116. package/src/overlays/relationship-details/useLayoutedDetails.ts +7 -10
  117. package/src/overlays/relationships-browser/-useRelationshipsView.ts +16 -12
  118. package/src/overlays/relationships-browser/RelationshipsBrowser.tsx +105 -68
  119. package/src/overlays/relationships-browser/_types.ts +2 -1
  120. package/src/overlays/relationships-browser/actor.ts +321 -62
  121. package/src/overlays/relationships-browser/const.ts +1 -0
  122. package/src/overlays/relationships-browser/custom/ElementActions.tsx +1 -1
  123. package/src/overlays/relationships-browser/custom/edgeTypes.tsx +25 -6
  124. package/src/overlays/relationships-browser/custom/nodeTypes.tsx +3 -2
  125. package/src/overlays/relationships-browser/hooks.ts +3 -1
  126. package/src/overlays/relationships-browser/useViewToNodesEdges.ts +8 -2
  127. package/dist/likec4diagram/ui/diagram-title/Link.js +0 -36
  128. package/dist/ui/Link.d.ts +0 -4
  129. package/src/ui/Link.tsx +0 -40
@@ -2,3 +2,4 @@ export declare const cssReactFlow: string;
2
2
  export declare const notInitialized: string;
3
3
  export declare const cssDisablePan: string;
4
4
  export declare const cssTransparentBg: string;
5
+ export declare const hiddenIfZoomTooSmall: string;
@@ -2,8 +2,10 @@
2
2
  var cssReactFlow = "_2h8g8h0";
3
3
  var cssDisablePan = "_2h8g8h2";
4
4
  var cssTransparentBg = "_2h8g8h3";
5
+ var hiddenIfZoomTooSmall = "_2h8g8h4";
5
6
  export {
6
7
  cssDisablePan,
7
8
  cssReactFlow,
8
- cssTransparentBg
9
+ cssTransparentBg,
10
+ hiddenIfZoomTooSmall
9
11
  };
@@ -1,13 +1,15 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { useCallbackRef } from "@mantine/hooks";
3
- import { ReactFlow, useStoreApi, useOnViewportChange } from "@xyflow/react";
3
+ import { ReactFlow, useStoreApi, useOnViewportChange, useStore } from "@xyflow/react";
4
4
  import clsx from "clsx";
5
- import { useMemo, useEffect } from "react";
5
+ import { useMemo } from "react";
6
+ import { useIsZoomTooSmall } from "../hooks/useXYFlow.js";
6
7
  import { cssReactFlow, cssDisablePan, cssTransparentBg } from "../LikeC4Diagram.css.js";
7
8
  import { stopPropagation } from "../utils/xyflow.js";
8
9
  import { Background } from "./Background.js";
9
10
  import { MaxZoom, MinZoom } from "./const.js";
10
11
  import { Base } from "./types.js";
12
+ import { useUpdateEffect } from "../hooks/useUpdateEffect.js";
11
13
  const BaseXYFlow = ({
12
14
  nodes,
13
15
  edges,
@@ -28,6 +30,7 @@ const BaseXYFlow = ({
28
30
  ...props
29
31
  }) => {
30
32
  const isBgWithPattern = background !== "transparent" && background !== "solid";
33
+ const isZoomTooSmall = useIsZoomTooSmall();
31
34
  return /* @__PURE__ */ jsxs(
32
35
  ReactFlow,
33
36
  {
@@ -41,6 +44,7 @@ const BaseXYFlow = ({
41
44
  background === "transparent" && cssTransparentBg,
42
45
  className
43
46
  ),
47
+ "data-likec4-zoom-small": isZoomTooSmall,
44
48
  zoomOnPinch: zoomable,
45
49
  zoomOnScroll: !pannable && zoomable,
46
50
  ...!zoomable && {
@@ -65,6 +69,7 @@ const BaseXYFlow = ({
65
69
  ...!pannable && {
66
70
  selectionKeyCode: null
67
71
  },
72
+ onlyRenderVisibleElements: nodes.length > 75,
68
73
  elementsSelectable: nodesSelectable,
69
74
  nodesFocusable: nodesDraggable || nodesSelectable,
70
75
  edgesFocusable: false,
@@ -127,18 +132,14 @@ const BaseXYFlowInner = ({
127
132
  }
128
133
  }
129
134
  });
130
- const listenToViewportResize = !!onViewportResize;
131
- const onViewportResizeCb = useCallbackRef(onViewportResize);
132
- useEffect(() => {
133
- if (!listenToViewportResize) {
134
- return;
135
- }
136
- return xyflowApi.subscribe((state, prevState) => {
137
- if (state.width !== prevState.width || state.height !== prevState.height) {
138
- onViewportResizeCb();
139
- }
140
- });
141
- }, [listenToViewportResize]);
135
+ return /* @__PURE__ */ jsx(Fragment, { children: onViewportResize && /* @__PURE__ */ jsx(ViewportResizeHanlder, { onViewportResize }) });
136
+ };
137
+ const selectDimensions = ({ width, height }) => ({ width, height });
138
+ const ViewportResizeHanlder = ({
139
+ onViewportResize
140
+ }) => {
141
+ const { width, height } = useStore(selectDimensions);
142
+ useUpdateEffect(onViewportResize, [width, height]);
142
143
  return /* @__PURE__ */ jsx(Fragment, {});
143
144
  };
144
145
  export {
@@ -0,0 +1,3 @@
1
+ export declare const elementLink: string;
2
+ export declare const linkIcon: string;
3
+ export declare const linkTitleBox: string;
@@ -0,0 +1,9 @@
1
+ /* empty css */
2
+ var elementLink = "_180738q0";
3
+ var linkIcon = "_180738q1";
4
+ var linkTitleBox = "_180738q2";
5
+ export {
6
+ elementLink,
7
+ linkIcon,
8
+ linkTitleBox
9
+ };
@@ -0,0 +1,5 @@
1
+ import { Link as LinkData } from '@likec4/core';
2
+ export declare function Link({ value, size, }: {
3
+ size?: 'sm' | 'md';
4
+ value: LinkData;
5
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,58 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { CopyButton, Anchor, ActionIcon, Box, Text } from "@mantine/core";
3
+ import { IconCheck, IconCopy } from "@tabler/icons-react";
4
+ import { elementLink, linkIcon, linkTitleBox } from "./Link.css.js";
5
+ import { stopPropagation } from "../utils/xyflow.js";
6
+ function Link({
7
+ value,
8
+ size = "md"
9
+ }) {
10
+ const isNormalSize = size === "md";
11
+ const url = new URL(value.url, window.location.href).toString();
12
+ return /* @__PURE__ */ jsx(CopyButton, { value: url, children: ({ copied, copy }) => /* @__PURE__ */ jsxs(
13
+ Anchor,
14
+ {
15
+ href: url,
16
+ target: "_blank",
17
+ underline: "never",
18
+ className: elementLink,
19
+ "data-size": size,
20
+ onClick: stopPropagation,
21
+ children: [
22
+ /* @__PURE__ */ jsx(
23
+ ActionIcon,
24
+ {
25
+ className: linkIcon,
26
+ tabIndex: -1,
27
+ size: isNormalSize ? 24 : 20,
28
+ variant: copied ? "light" : "subtle",
29
+ color: copied ? "teal" : "gray",
30
+ onClick: (e) => {
31
+ e.stopPropagation();
32
+ e.preventDefault();
33
+ copy();
34
+ },
35
+ children: copied ? /* @__PURE__ */ jsx(IconCheck, {}) : /* @__PURE__ */ jsx(IconCopy, { style: { width: "65%", opacity: 0.65 } })
36
+ }
37
+ ),
38
+ /* @__PURE__ */ jsxs(Box, { className: linkTitleBox, children: [
39
+ /* @__PURE__ */ jsx(
40
+ Text,
41
+ {
42
+ component: "div",
43
+ fz: isNormalSize ? "xs" : 11,
44
+ truncate: true,
45
+ lh: isNormalSize ? 1.3 : 1.2,
46
+ fw: value.title ? 500 : 400,
47
+ children: value.title || url
48
+ }
49
+ ),
50
+ value.title && /* @__PURE__ */ jsx(Text, { component: "div", fz: isNormalSize ? 10 : 9, c: "dimmed", lh: isNormalSize ? 1.2 : 1.1, truncate: true, children: url })
51
+ ] })
52
+ ]
53
+ }
54
+ ) });
55
+ }
56
+ export {
57
+ Link
58
+ };
@@ -2,6 +2,7 @@ export declare const ZIndexes: {
2
2
  readonly Compound: 2;
3
3
  readonly Edge: 4;
4
4
  readonly Element: 6;
5
+ readonly Max: 8;
5
6
  };
6
7
  export declare const MinZoom = 0.1;
7
8
  export declare const MaxZoom = 2;
@@ -1,7 +1,8 @@
1
1
  const ZIndexes = {
2
2
  Compound: 2,
3
3
  Edge: 4,
4
- Element: 6
4
+ Element: 6,
5
+ Max: 8
5
6
  };
6
7
  const MinZoom = 0.1;
7
8
  const MaxZoom = 2;
@@ -35,9 +35,9 @@ export declare const edgeTypes: {
35
35
  target: string;
36
36
  style?: CSSProperties;
37
37
  id: string;
38
- selected?: boolean;
39
38
  selectable?: boolean;
40
39
  deletable?: boolean;
40
+ selected?: boolean;
41
41
  animated?: boolean;
42
42
  sourceX: number;
43
43
  sourceY: number;
@@ -1,2 +1,3 @@
1
1
  export { BaseXYFlow, type BaseXYFlowProps } from './BaseXYFlow';
2
2
  export { Base, type EdgeProps, type NodeProps, type NonOptional, type ReactFlowEdge, type ReactFlowNode, } from './types';
3
+ export { Link } from './Link';
@@ -3,6 +3,7 @@ import { Box, ActionIcon } from "@mantine/core";
3
3
  import { IconZoomScan } from "@tabler/icons-react";
4
4
  import clsx from "clsx";
5
5
  import { m } from "framer-motion";
6
+ import { hiddenIfZoomTooSmall } from "../../../LikeC4Diagram.css.js";
6
7
  import { stopPropagation } from "../../../utils/xyflow.js";
7
8
  import { container, actionButton, actionIcon } from "./CompoundActionButton.css.js";
8
9
  function CompoundActionButton({
@@ -12,7 +13,7 @@ function CompoundActionButton({
12
13
  icon,
13
14
  onClick
14
15
  }) {
15
- return /* @__PURE__ */ jsx(Box, { className: clsx(container, "compound-action"), children: /* @__PURE__ */ jsx(
16
+ return /* @__PURE__ */ jsx(Box, { className: clsx(container, hiddenIfZoomTooSmall, "compound-action"), children: /* @__PURE__ */ jsx(
16
17
  Box,
17
18
  {
18
19
  className: clsx("nodrag nopan", actionButton),
@@ -3,6 +3,7 @@ import { Box, ActionIcon } from "@mantine/core";
3
3
  import { IconId } from "@tabler/icons-react";
4
4
  import clsx from "clsx";
5
5
  import { m } from "framer-motion";
6
+ import { hiddenIfZoomTooSmall } from "../../../LikeC4Diagram.css.js";
6
7
  import { stopPropagation } from "../../../utils/xyflow.js";
7
8
  import { container, actionIconWrapper, actionIcon } from "./CompoundDetailsButton.css.js";
8
9
  function CompoundDetailsButton({
@@ -12,7 +13,7 @@ function CompoundDetailsButton({
12
13
  icon,
13
14
  onClick
14
15
  }) {
15
- return /* @__PURE__ */ jsx(Box, { className: clsx(container, "details-button"), onClick: stopPropagation, children: /* @__PURE__ */ jsx(
16
+ return /* @__PURE__ */ jsx(Box, { className: clsx(container, hiddenIfZoomTooSmall, "details-button"), onClick: stopPropagation, children: /* @__PURE__ */ jsx(
16
17
  Box,
17
18
  {
18
19
  component: m.div,
@@ -2,7 +2,6 @@ export declare const varCompoundOpacity: `var(--${string})` | `var(--${string},
2
2
  export declare const varBorderRadius: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
3
3
  export declare const varBorderTransparency: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
4
4
  export declare const varBorderColor: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
5
- export declare const dimmed: string;
6
5
  export declare const container: string;
7
6
  export declare const compoundBg: string;
8
7
  export declare const compoundBorder: string;
@@ -1,16 +1,14 @@
1
1
  /* empty css */
2
2
  var varCompoundOpacity = "var(--_7cmew10)";
3
3
  var varBorderTransparency = "var(--_7cmew12)";
4
- var dimmed = "_7cmew15";
5
- var container = "_7cmew16";
6
- var compoundBg = "_7cmew17";
7
- var compoundBorder = "_7cmew18";
8
- var indicator = "_7cmew1c";
4
+ var container = "_7cmew15";
5
+ var compoundBg = "_7cmew16";
6
+ var compoundBorder = "_7cmew17";
7
+ var indicator = "_7cmew1b";
9
8
  export {
10
9
  compoundBg,
11
10
  compoundBorder,
12
11
  container,
13
- dimmed,
14
12
  indicator,
15
13
  varBorderTransparency,
16
14
  varCompoundOpacity
@@ -5,7 +5,7 @@ import clsx from "clsx";
5
5
  import { m } from "framer-motion";
6
6
  import { forwardRef } from "react";
7
7
  import { isNumber, clamp } from "remeda";
8
- import { container, dimmed, varCompoundOpacity, varBorderTransparency, indicator, compoundBg, compoundBorder } from "./CompoundNodeContainer.css.js";
8
+ import { container, varCompoundOpacity, varBorderTransparency, indicator, compoundBg, compoundBorder } from "./CompoundNodeContainer.css.js";
9
9
  const CompoundNodeContainer = createPolymorphicComponent(
10
10
  forwardRef(({
11
11
  nodeProps: {
@@ -39,7 +39,6 @@ const CompoundNodeContainer = createPolymorphicComponent(
39
39
  component: m.div,
40
40
  className: clsx([
41
41
  container,
42
- isDimmed && dimmed,
43
42
  "likec4-compound-node"
44
43
  ]),
45
44
  initial: false,
@@ -47,6 +46,7 @@ const CompoundNodeContainer = createPolymorphicComponent(
47
46
  "data-likec4-color": data.color,
48
47
  "data-compound-depth": data.depth ?? 1,
49
48
  "data-compound-transparent": isTransparent,
49
+ "data-likec4-dimmed": isDimmed,
50
50
  "data-likec4-shape": data.shape,
51
51
  style: assignInlineVars({
52
52
  [varCompoundOpacity]: opacity.toFixed(2),
@@ -11,9 +11,9 @@ export declare function customEdge<P extends Record<string, unknown> = Base.Node
11
11
  target: string;
12
12
  style?: CSSProperties;
13
13
  id: string;
14
- selected?: boolean;
15
14
  selectable?: boolean;
16
15
  deletable?: boolean;
16
+ selected?: boolean;
17
17
  animated?: boolean;
18
18
  sourceX: number;
19
19
  sourceY: number;
@@ -3,7 +3,7 @@ import { memo } from "react";
3
3
  const isSame = (a, b) => {
4
4
  return Math.abs(a - b) < 2.5;
5
5
  };
6
- const edgePropsEqual = (prev, next) => prev.id === next.id && deepEqual(prev.source, next.source) && deepEqual(prev.sourceHandleId ?? null, next.sourceHandleId ?? null) && deepEqual(prev.target, next.target) && deepEqual(prev.targetHandleId ?? null, next.targetHandleId ?? null) && deepEqual(prev.selected ?? false, next.selected ?? false) && isSame(prev.sourceX, next.sourceX) && isSame(prev.sourceY, next.sourceY) && isSame(prev.targetX, next.targetX) && isSame(prev.targetY, next.targetY) && deepEqual(prev.data, next.data) && deepEqual(prev.style, next.style);
6
+ const edgePropsEqual = (prev, next) => prev.id === next.id && deepEqual(prev.source, next.source) && deepEqual(prev.sourceHandleId ?? null, next.sourceHandleId ?? null) && deepEqual(prev.target, next.target) && deepEqual(prev.targetHandleId ?? null, next.targetHandleId ?? null) && deepEqual(prev.selected ?? false, next.selected ?? false) && deepEqual(prev.sourcePosition, next.sourcePosition) && deepEqual(prev.targetPosition, next.targetPosition) && isSame(prev.sourceX, next.sourceX) && isSame(prev.sourceY, next.sourceY) && isSame(prev.targetX, next.targetX) && isSame(prev.targetY, next.targetY) && deepEqual(prev.data, next.data) && deepEqual(prev.style, next.style);
7
7
  function customEdge(Edge) {
8
8
  return memo(Edge, edgePropsEqual);
9
9
  }
@@ -1,6 +1,6 @@
1
1
  import { deepEqual } from "fast-equals";
2
2
  import { memo } from "react";
3
- const nodePropsEqual = (prev, next) => prev.id === next.id && deepEqual(prev.selected ?? false, next.selected ?? false) && deepEqual(prev.dragging ?? false, next.dragging ?? false) && deepEqual(prev.width ?? 0, next.width ?? 0) && deepEqual(prev.height ?? 0, next.height ?? 0) && deepEqual(prev.data, next.data);
3
+ const nodePropsEqual = (prev, next) => prev.id === next.id && deepEqual(prev.selected ?? false, next.selected ?? false) && deepEqual(prev.dragging ?? false, next.dragging ?? false) && deepEqual(prev.width ?? 0, next.width ?? 0) && deepEqual(prev.height ?? 0, next.height ?? 0) && deepEqual(prev.zIndex, next.zIndex) && deepEqual(prev.positionAbsoluteX, next.positionAbsoluteX) && deepEqual(prev.positionAbsoluteY, next.positionAbsoluteY) && deepEqual(prev.data, next.data);
4
4
  function customNode(Node) {
5
5
  return memo(Node, nodePropsEqual);
6
6
  }
@@ -6,6 +6,7 @@ import { EdgeLabelRenderer } from "@xyflow/react";
6
6
  import clsx from "clsx";
7
7
  import { forwardRef } from "react";
8
8
  import { isTruthy, isNumber } from "remeda";
9
+ import { useIsZoomTooSmall } from "../../../hooks/useXYFlow.js";
9
10
  import { ZIndexes } from "../../const.js";
10
11
  import { edgeVars, edgeLabelContainer, dimmed, edgeLabel, stepEdgeNumber, secondColumn, edgeLabelText, edgeLabelTechnology, varTranslate } from "./EdgeLabel.css.js";
11
12
  const toCssVarValue = (value) => {
@@ -31,13 +32,14 @@ const EdgeLabel = createPolymorphicComponent(
31
32
  children,
32
33
  ...rest
33
34
  }, ref) => {
35
+ const isZoomTooSmall = useIsZoomTooSmall();
34
36
  const stepNum = isStepEdgeId(id) ? extractStep(id) : null;
35
37
  let zIndex = ZIndexes.Edge;
36
38
  if (isHovered || isActive) {
37
39
  zIndex = ZIndexes.Element + 1;
38
40
  }
39
41
  let labelX = (labelXY == null ? void 0 : labelXY.x) ?? (labelBBox == null ? void 0 : labelBBox.x), labelY = (labelXY == null ? void 0 : labelXY.y) ?? (labelBBox == null ? void 0 : labelBBox.y);
40
- if (labelX === void 0 || labelY === void 0) {
42
+ if (labelX === void 0 || labelY === void 0 || isZoomTooSmall) {
41
43
  return null;
42
44
  }
43
45
  const translate = labelXY == null ? void 0 : labelXY.translate;
@@ -6,9 +6,9 @@ export declare const EdgePath: ForwardRefExoticComponent<{
6
6
  target: string;
7
7
  style?: CSSProperties;
8
8
  id: string;
9
- selected?: boolean;
10
9
  selectable?: boolean;
11
10
  deletable?: boolean;
11
+ selected?: boolean;
12
12
  animated?: boolean;
13
13
  sourceX: number;
14
14
  sourceY: number;
@@ -40,5 +40,6 @@ export declare const EdgePath: ForwardRefExoticComponent<{
40
40
  };
41
41
  } & {
42
42
  svgPath: string;
43
+ strokeWidth?: number;
43
44
  onEdgePointerDown?: PointerEventHandler<SVGGElement> | undefined;
44
45
  } & RefAttributes<SVGPathElement>>;
@@ -11,6 +11,7 @@ const EdgePath = forwardRef(({
11
11
  tail,
12
12
  head
13
13
  },
14
+ strokeWidth,
14
15
  svgPath,
15
16
  style,
16
17
  interactionWidth,
@@ -63,6 +64,7 @@ const EdgePath = forwardRef(({
63
64
  className: clsx("react-flow__edge-path", cssEdgePath),
64
65
  d: svgPath,
65
66
  style,
67
+ strokeWidth,
66
68
  strokeLinecap: "round",
67
69
  strokeDasharray,
68
70
  markerStart: MarkerStart ? `url(#start${id})` : void 0,
@@ -2,6 +2,7 @@ import { jsx } from "react/jsx-runtime";
2
2
  import { Box, ActionIcon } from "@mantine/core";
3
3
  import clsx from "clsx";
4
4
  import { m } from "framer-motion";
5
+ import { hiddenIfZoomTooSmall } from "../../../LikeC4Diagram.css.js";
5
6
  import { stopPropagation } from "../../../utils/xyflow.js";
6
7
  import { container, actionButtons, actionIcon } from "./ElementActionButtons.css.js";
7
8
  function ElementActionButtons({
@@ -15,7 +16,7 @@ function ElementActionButtons({
15
16
  if (!buttons.length) {
16
17
  return null;
17
18
  }
18
- return /* @__PURE__ */ jsx(Box, { className: container, children: /* @__PURE__ */ jsx(
19
+ return /* @__PURE__ */ jsx(Box, { className: clsx(container, hiddenIfZoomTooSmall), children: /* @__PURE__ */ jsx(
19
20
  Box,
20
21
  {
21
22
  component: m.div,
@@ -3,6 +3,7 @@ import { Box, ActionIcon } from "@mantine/core";
3
3
  import { IconId } from "@tabler/icons-react";
4
4
  import clsx from "clsx";
5
5
  import { m } from "framer-motion";
6
+ import { hiddenIfZoomTooSmall } from "../../../LikeC4Diagram.css.js";
6
7
  import { stopPropagation } from "../../../utils/xyflow.js";
7
8
  import { container, actionIconWrapper, actionIcon } from "./ElementDetailsButton.css.js";
8
9
  function ElementDetailsButton({
@@ -13,7 +14,7 @@ function ElementDetailsButton({
13
14
  icon,
14
15
  onClick
15
16
  }) {
16
- return /* @__PURE__ */ jsx(Box, { className: clsx(container, "details-button"), children: /* @__PURE__ */ jsx(
17
+ return /* @__PURE__ */ jsx(Box, { className: clsx(container, hiddenIfZoomTooSmall, "details-button"), children: /* @__PURE__ */ jsx(
17
18
  Box,
18
19
  {
19
20
  className: clsx("nodrag nopan", actionIconWrapper),
@@ -1,3 +1,2 @@
1
1
  export declare const stokeFillMix: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
2
2
  export declare const container: string;
3
- export declare const dimmed: string;
@@ -1,7 +1,5 @@
1
1
  /* empty css */
2
2
  var container = "_1smoows1";
3
- var dimmed = "_1smoows2";
4
3
  export {
5
- container,
6
- dimmed
4
+ container
7
5
  };
@@ -3,7 +3,7 @@ import { createPolymorphicComponent, Box } from "@mantine/core";
3
3
  import clsx from "clsx";
4
4
  import { m } from "framer-motion";
5
5
  import { forwardRef } from "react";
6
- import { container, dimmed } from "./ElementNodeContainer.css.js";
6
+ import { container } from "./ElementNodeContainer.css.js";
7
7
  const ElementNodeContainer = createPolymorphicComponent(
8
8
  forwardRef(({
9
9
  nodeProps: {
@@ -34,11 +34,9 @@ const ElementNodeContainer = createPolymorphicComponent(
34
34
  ref,
35
35
  className: clsx([
36
36
  container,
37
- isDimmed && dimmed,
38
37
  "likec4-element-node"
39
38
  ]),
40
39
  initial: false,
41
- layoutRoot: true,
42
40
  ...selectable && {
43
41
  animate: {
44
42
  scale
@@ -48,6 +46,7 @@ const ElementNodeContainer = createPolymorphicComponent(
48
46
  "data-hovered": isHovered,
49
47
  "data-likec4-color": data.color,
50
48
  "data-likec4-shape": data.shape,
49
+ "data-likec4-dimmed": isDimmed,
51
50
  ...rest,
52
51
  children
53
52
  }
@@ -1,5 +1,7 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import { nonexhaustive } from "@likec4/core";
3
+ import clsx from "clsx";
4
+ import { hiddenIfZoomTooSmall } from "../../../LikeC4Diagram.css.js";
3
5
  import { toDomPrecision } from "../../../utils/xyflow.js";
4
6
  import { shapeSvgMultiple, shapeSvg, indicator, fillMixStroke, fillElementFill } from "./ElementShape.css.js";
5
7
  function cylinderSVGPath(diameter, height, tilt = 0.065) {
@@ -150,7 +152,7 @@ function ElementShape({ data, width, height, isMultiple = false, withSelectedInd
150
152
  let w = !!width && width > 10 ? width : data.width;
151
153
  let h = !!height && height > 10 ? height : data.height;
152
154
  return /* @__PURE__ */ jsxs(Fragment, { children: [
153
- isMultiple && /* @__PURE__ */ jsx("svg", { className: shapeSvgMultiple, viewBox: `0 0 ${w} ${h}`, children: /* @__PURE__ */ jsx(ElementShapeSvg, { shape: data.shape, w, h }) }),
155
+ isMultiple && /* @__PURE__ */ jsx("svg", { className: clsx(shapeSvgMultiple, hiddenIfZoomTooSmall), viewBox: `0 0 ${w} ${h}`, children: /* @__PURE__ */ jsx(ElementShapeSvg, { shape: data.shape, w, h }) }),
154
156
  /* @__PURE__ */ jsxs("svg", { className: shapeSvg, viewBox: `0 0 ${w} ${h}`, children: [
155
157
  withSelectedIndicator && /* @__PURE__ */ jsx(SelectedIndicator, { shape: data.shape, w, h }),
156
158
  /* @__PURE__ */ jsx(ElementShapeSvg, { shape: data.shape, w, h })
@@ -182,7 +184,7 @@ function SelectedIndicator({ shape, w, h }) {
182
184
  break;
183
185
  }
184
186
  }
185
- return /* @__PURE__ */ jsx("g", { className: indicator, children: svg });
187
+ return /* @__PURE__ */ jsx("g", { className: clsx(indicator, hiddenIfZoomTooSmall), children: svg });
186
188
  }
187
189
  export {
188
190
  ElementShape,
@@ -4,6 +4,7 @@ import { assignInlineVars } from "../../../node_modules/@vanilla-extract/dynamic
4
4
  import clsx from "clsx";
5
5
  import { isTruthy, isNumber } from "remeda";
6
6
  import { IconRenderer } from "../../../context/IconRenderer.js";
7
+ import { hiddenIfZoomTooSmall } from "../../../LikeC4Diagram.css.js";
7
8
  import { elementIcon, elementDataContainer, hasIcon, elementTextData, title, technology, description, iconSize } from "./ElementTitle.css.js";
8
9
  function ElementTitle({ id, data, iconSize: iconSize$1 }) {
9
10
  const elementIcon$1 = IconRenderer({
@@ -43,7 +44,7 @@ function ElementTitle({ id, data, iconSize: iconSize$1 }) {
43
44
  Text,
44
45
  {
45
46
  component: "div",
46
- className: clsx(technology, "likec4-element-technology"),
47
+ className: clsx(technology, hiddenIfZoomTooSmall, "likec4-element-technology"),
47
48
  children: data.technology
48
49
  }
49
50
  ),
@@ -1,14 +1,14 @@
1
1
  import { deepEqual } from "fast-equals";
2
- import { isDefined } from "remeda";
2
+ import { isDefined, omit } from "remeda";
3
3
  function _update(current, update) {
4
4
  return update.map((next) => {
5
5
  const existing = current.find((n) => n.id === next.id);
6
6
  if (existing && existing.type === next.type) {
7
- if (deepEqual(existing.hidden ?? false, next.hidden ?? false) && deepEqual(existing.source, next.source) && deepEqual(existing.sourceHandle ?? null, next.sourceHandle ?? null) && deepEqual(existing.target, next.target) && deepEqual(existing.targetHandle ?? null, next.targetHandle ?? null) && deepEqual(existing.data, next.data)) {
7
+ if (deepEqual(existing.hidden ?? false, next.hidden ?? false) && deepEqual(existing.source, next.source) && deepEqual(existing.sourceHandle ?? null, next.sourceHandle ?? null) && deepEqual(existing.target, next.target) && deepEqual(existing.targetHandle ?? null, next.targetHandle ?? null) && deepEqual(existing.zIndex ?? 0, next.zIndex ?? 0) && deepEqual(existing.data, next.data)) {
8
8
  return existing;
9
9
  }
10
10
  return {
11
- ...existing,
11
+ ...omit(existing, ["hidden", "zIndex"]),
12
12
  ...next,
13
13
  data: {
14
14
  ...existing.data,
@@ -6,11 +6,11 @@ function _update(current, updated) {
6
6
  const existing = current.find((n) => n.id === update.id);
7
7
  if (existing) {
8
8
  const { width: existingWidth, height: existingHeight } = getNodeDimensions(existing);
9
- if (deepEqual(existing.type, update.type) && deepEqual(existingWidth, update.initialWidth) && deepEqual(existingHeight, update.initialHeight) && deepEqual(existing.hidden ?? false, update.hidden ?? false) && deepEqual(existing.position, update.position) && deepEqual(existing.data, update.data) && deepEqual(existing.parentId ?? null, update.parentId ?? null)) {
9
+ if (deepEqual(existing.type, update.type) && deepEqual(existingWidth, update.initialWidth) && deepEqual(existingHeight, update.initialHeight) && deepEqual(existing.parentId ?? null, update.parentId ?? null) && deepEqual(existing.hidden ?? false, update.hidden ?? false) && deepEqual(existing.zIndex ?? 0, update.zIndex ?? 0) && deepEqual(existing.position, update.position) && deepEqual(existing.data, update.data)) {
10
10
  return existing;
11
11
  }
12
12
  return {
13
- ...omit(existing, ["measured", "parentId"]),
13
+ ...omit(existing, ["measured", "parentId", "hidden", "zIndex"]),
14
14
  ...update,
15
15
  // Force dimensions from update
16
16
  width: update.initialWidth,
@@ -5,7 +5,7 @@ import "react";
5
5
  const FramerMotionConfig = ({ children }) => {
6
6
  var _a;
7
7
  const nonce = (_a = useMantineStyleNonce()) == null ? void 0 : _a();
8
- return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsx(MotionConfig, { reducedMotion: "user", ...nonce && { nonce }, children }) });
8
+ return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsx(MotionConfig, { ...nonce && { nonce }, children }) });
9
9
  };
10
10
  export {
11
11
  FramerMotionConfig