@likec4/diagram 1.39.5 → 1.41.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 (140) hide show
  1. package/bundle/{chunk-CW_KClZe.js → chunk-FGcODVxo.js} +1059 -1023
  2. package/bundle/custom.js +61 -60
  3. package/bundle/index.js +2932 -764
  4. package/dist/LikeC4Diagram.d.ts +1 -1
  5. package/dist/LikeC4Diagram.js +7 -4
  6. package/dist/LikeC4Diagram.props.d.ts +6 -1
  7. package/dist/base/const.d.ts +9 -0
  8. package/dist/base/const.js +10 -1
  9. package/dist/base/index.d.ts +1 -0
  10. package/dist/base/primitives/MarkdownBlock.js +2 -0
  11. package/dist/base/primitives/edge/EdgeLabel.js +2 -1
  12. package/dist/base/primitives/edge/EdgeLabelContainer.js +10 -4
  13. package/dist/base/primitives/edge/EdgePath.js +17 -8
  14. package/dist/base/primitives/edge/edge.css.d.ts +0 -1
  15. package/dist/base/primitives/edge/edge.css.js +6 -14
  16. package/dist/base/primitives/element/ElementActionButtons.js +1 -3
  17. package/dist/base/primitives/element/ElementNodeContainer.d.ts +0 -6
  18. package/dist/base/primitives/element/ElementNodeContainer.js +3 -26
  19. package/dist/base/primitives/element/ElementTitle.js +2 -2
  20. package/dist/base/types.d.ts +3 -3
  21. package/dist/bundle/LikeC4View.js +4 -12
  22. package/dist/bundle/LikeC4View.props.d.ts +12 -3
  23. package/dist/bundle/custom.js +1 -1
  24. package/dist/components/Link.js +28 -20
  25. package/dist/custom/customNodes.d.ts +6 -0
  26. package/dist/custom/customNodes.js +2 -1
  27. package/dist/custom/index.js +1 -1
  28. package/dist/hooks/useDiagram.d.ts +5 -1
  29. package/dist/hooks/useDiagram.js +3 -0
  30. package/dist/hooks/useXYFlow.d.ts +4 -439
  31. package/dist/likec4diagram/DiagramUI.js +1 -1
  32. package/dist/likec4diagram/DiagramXYFlow.js +8 -4
  33. package/dist/likec4diagram/convert-to-xyflow.d.ts +14 -0
  34. package/dist/likec4diagram/convert-to-xyflow.js +29 -0
  35. package/dist/likec4diagram/custom/edges/RelationshipEdge.d.ts +4 -4
  36. package/dist/likec4diagram/custom/edges/RelationshipEdge.js +0 -1
  37. package/dist/likec4diagram/custom/edges/SequenceStepEdge.d.ts +3 -0
  38. package/dist/likec4diagram/custom/edges/SequenceStepEdge.js +71 -0
  39. package/dist/likec4diagram/custom/index.js +7 -2
  40. package/dist/likec4diagram/custom/nodes/ElementActions.d.ts +2 -1
  41. package/dist/likec4diagram/custom/nodes/SequenceActorNode.d.ts +4 -0
  42. package/dist/likec4diagram/custom/nodes/SequenceActorNode.js +157 -0
  43. package/dist/likec4diagram/custom/nodes/index.d.ts +1 -0
  44. package/dist/likec4diagram/custom/nodes/nodes.d.ts +1 -2
  45. package/dist/likec4diagram/relationship-popover/RelationshipPopover.js +31 -27
  46. package/dist/likec4diagram/types.d.ts +41 -7
  47. package/dist/likec4diagram/xyflow-diagram/diagram-view.d.ts +11 -0
  48. package/dist/likec4diagram/{useViewToNodesEdges.js → xyflow-diagram/diagram-view.js} +4 -13
  49. package/dist/likec4diagram/xyflow-sequence/_types.d.ts +41 -0
  50. package/dist/likec4diagram/xyflow-sequence/const.d.ts +17 -0
  51. package/dist/likec4diagram/xyflow-sequence/const.js +16 -0
  52. package/dist/likec4diagram/xyflow-sequence/layouter.d.ts +46 -0
  53. package/dist/likec4diagram/xyflow-sequence/layouter.js +408 -0
  54. package/dist/likec4diagram/xyflow-sequence/sequence-view.d.ts +7 -0
  55. package/dist/likec4diagram/xyflow-sequence/sequence-view.js +273 -0
  56. package/dist/likec4diagram/xyflow-sequence/utils.d.ts +14 -0
  57. package/dist/likec4diagram/xyflow-sequence/utils.js +92 -0
  58. package/dist/navigationpanel/NavigationPanelControls.js +2 -2
  59. package/dist/navigationpanel/controls/ViewDetailsCard.js +27 -12
  60. package/dist/navigationpanel/dropdown/ProjectsMenu.js +53 -44
  61. package/dist/navigationpanel/walkthrough/ActiveWalkthroughControls.d.ts +1 -2
  62. package/dist/navigationpanel/walkthrough/ActiveWalkthroughControls.js +10 -41
  63. package/dist/navigationpanel/walkthrough/DynamicViewControls.d.ts +292 -0
  64. package/dist/navigationpanel/walkthrough/DynamicViewControls.js +119 -0
  65. package/dist/navigationpanel/walkthrough/index.d.ts +2 -1
  66. package/dist/overlays/element-details/ElementDetailsCard.css.js +7 -1
  67. package/dist/overlays/element-details/ElementDetailsCard.js +17 -19
  68. package/dist/overlays/relationship-details/RelationshipDetails.js +4 -1
  69. package/dist/overlays/relationship-details/layout.d.ts +3 -2
  70. package/dist/overlays/relationship-details/layout.js +1 -2
  71. package/dist/overlays/relationships-browser/RelationshipsBrowser.js +2 -1
  72. package/dist/overlays/relationships-browser/layout.js +1 -1
  73. package/dist/search/components/ElementsColumn.js +1 -1
  74. package/dist/state/DiagramActorProvider.d.ts +3 -2
  75. package/dist/state/DiagramActorProvider.js +40 -41
  76. package/dist/state/assign.js +11 -4
  77. package/dist/state/diagram-machine.d.ts +224 -194
  78. package/dist/state/diagram-machine.js +170 -63
  79. package/dist/state/utils.d.ts +7 -1
  80. package/dist/state/utils.js +67 -7
  81. package/dist/styles-min.css +1 -1
  82. package/dist/styles.css +1 -1
  83. package/dist/styles.css2.js +1 -1
  84. package/package.json +8 -7
  85. package/panda.buildinfo.json +45 -24
  86. package/src/LikeC4Diagram.props.ts +14 -1
  87. package/src/LikeC4Diagram.tsx +7 -4
  88. package/src/base/const.ts +12 -0
  89. package/src/base/index.ts +2 -0
  90. package/src/base/primitives/MarkdownBlock.tsx +2 -0
  91. package/src/base/primitives/edge/EdgeLabel.tsx +23 -19
  92. package/src/base/primitives/edge/EdgeLabelContainer.tsx +12 -7
  93. package/src/base/primitives/edge/EdgePath.tsx +25 -14
  94. package/src/base/primitives/edge/edge.css.ts +5 -14
  95. package/src/base/primitives/element/ElementActionButtons.tsx +1 -3
  96. package/src/base/primitives/element/ElementNodeContainer.tsx +3 -30
  97. package/src/base/primitives/element/ElementTitle.tsx +2 -3
  98. package/src/base/types.ts +7 -5
  99. package/src/bundle/LikeC4View.props.ts +14 -3
  100. package/src/bundle/LikeC4View.tsx +4 -14
  101. package/src/bundle/ReactLikeC4.tsx +1 -2
  102. package/src/components/Link.tsx +21 -18
  103. package/src/custom/customNodes.ts +7 -0
  104. package/src/hooks/useDiagram.ts +10 -0
  105. package/src/likec4diagram/DiagramUI.tsx +1 -1
  106. package/src/likec4diagram/DiagramXYFlow.tsx +10 -5
  107. package/src/likec4diagram/convert-to-xyflow.ts +45 -0
  108. package/src/likec4diagram/custom/edges/RelationshipEdge.tsx +0 -1
  109. package/src/likec4diagram/custom/edges/SequenceStepEdge.tsx +65 -0
  110. package/src/likec4diagram/custom/index.ts +7 -1
  111. package/src/likec4diagram/custom/nodes/ElementActions.tsx +4 -2
  112. package/src/likec4diagram/custom/nodes/SequenceActorNode.tsx +175 -0
  113. package/src/likec4diagram/custom/nodes/index.ts +1 -0
  114. package/src/likec4diagram/custom/nodes/nodes.tsx +1 -1
  115. package/src/likec4diagram/relationship-popover/RelationshipPopover.tsx +36 -30
  116. package/src/likec4diagram/types.ts +96 -13
  117. package/src/likec4diagram/{useViewToNodesEdges.ts → xyflow-diagram/diagram-view.ts} +7 -28
  118. package/src/likec4diagram/xyflow-sequence/_types.ts +45 -0
  119. package/src/likec4diagram/xyflow-sequence/const.ts +37 -0
  120. package/src/likec4diagram/xyflow-sequence/layouter.ts +567 -0
  121. package/src/likec4diagram/xyflow-sequence/sequence-view.ts +337 -0
  122. package/src/likec4diagram/xyflow-sequence/utils.ts +112 -0
  123. package/src/navigationpanel/NavigationPanelControls.tsx +2 -2
  124. package/src/navigationpanel/controls/ViewDetailsCard.tsx +29 -12
  125. package/src/navigationpanel/dropdown/ProjectsMenu.tsx +5 -1
  126. package/src/navigationpanel/walkthrough/ActiveWalkthroughControls.tsx +5 -40
  127. package/src/navigationpanel/walkthrough/DynamicViewControls.tsx +125 -0
  128. package/src/navigationpanel/walkthrough/index.tsx +2 -1
  129. package/src/overlays/element-details/ElementDetailsCard.css.ts +7 -1
  130. package/src/overlays/element-details/ElementDetailsCard.tsx +24 -25
  131. package/src/overlays/relationship-details/RelationshipDetails.tsx +5 -2
  132. package/src/overlays/relationship-details/layout.ts +4 -3
  133. package/src/overlays/relationships-browser/RelationshipsBrowser.tsx +2 -1
  134. package/src/overlays/relationships-browser/layout.ts +1 -1
  135. package/src/search/components/ElementsColumn.tsx +1 -1
  136. package/src/state/DiagramActorProvider.tsx +46 -51
  137. package/src/state/assign.ts +18 -5
  138. package/src/state/diagram-machine.ts +207 -75
  139. package/src/state/utils.ts +81 -7
  140. package/dist/likec4diagram/useViewToNodesEdges.d.ts +0 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@likec4/diagram",
3
- "version": "1.39.5",
3
+ "version": "1.41.0",
4
4
  "license": "MIT",
5
5
  "bugs": "https://github.com/likec4/likec4/issues",
6
6
  "homepage": "https://likec4.dev",
@@ -69,6 +69,7 @@
69
69
  "dependencies": {
70
70
  "@dagrejs/dagre": "1.1.5",
71
71
  "@floating-ui/dom": "^1.7.4",
72
+ "@lume/kiwi": "^0.4.4",
72
73
  "@mantine/core": "8.2.8",
73
74
  "@mantine/hooks": "8.2.8",
74
75
  "@nanostores/react": "1.0.0",
@@ -88,11 +89,11 @@
88
89
  "remeda": "^2.30.0",
89
90
  "type-fest": "^4.41.0",
90
91
  "xstate": "^5.20.2",
91
- "@likec4/core": "1.39.5",
92
- "@likec4/styles": "1.39.5"
92
+ "@likec4/core": "1.41.0",
93
+ "@likec4/styles": "1.41.0"
93
94
  },
94
95
  "peerDependencies": {
95
- "@pandacss/dev": "^1.1.0",
96
+ "@pandacss/dev": "^1.3.0",
96
97
  "react": "^18.x || ^19.x",
97
98
  "react-dom": "^18.x || ^19.x"
98
99
  },
@@ -102,7 +103,7 @@
102
103
  }
103
104
  },
104
105
  "devDependencies": {
105
- "@pandacss/dev": "^1.1.0",
106
+ "@pandacss/dev": "^1.3.0",
106
107
  "@statelyai/inspect": "^0.4.0",
107
108
  "@tabler/icons-react": "3.34.1",
108
109
  "@types/bezier-js": "^4.1.3",
@@ -115,11 +116,11 @@
115
116
  "react": "19.1.1",
116
117
  "react-dom": "19.1.1",
117
118
  "typescript": "5.9.2",
118
- "vite": "^6.3.5",
119
+ "vite": "^6.3.6",
119
120
  "vite-plugin-dts": "^4.5.4",
120
121
  "vitest": "3.2.4",
121
122
  "wireit": "0.14.12",
122
- "@likec4/tsconfig": "1.39.5"
123
+ "@likec4/tsconfig": "1.41.0"
123
124
  },
124
125
  "scripts": {
125
126
  "typecheck": "tsc --build --verbose",
@@ -1,5 +1,5 @@
1
1
  {
2
- "schemaVersion": "1.1.0",
2
+ "schemaVersion": "1.3.0",
3
3
  "styles": {
4
4
  "atomic": [
5
5
  "background]___[value:dots",
@@ -37,16 +37,12 @@
37
37
  "color]___[value:mantine.colors.dimmed]___[cond:&:is([data-position=\"left\"])",
38
38
  "userSelect]___[value:none]___[cond:&:is([data-position=\"left\"])",
39
39
  "pointerEvents]___[value:none]___[cond:&:is([data-position=\"left\"])",
40
- "color]___[value:[inherit]]___[cond:&:is([data-position=\"left\"])<___>_groupHover",
40
+ "color]___[value:[var(--badge-color)]]___[cond:&:is([data-position=\"left\"])<___>_groupHover",
41
41
  "opacity]___[value:0.7]___[cond:&:is([data-position=\"left\"])<___>_groupHover",
42
- "color]___[value:[inherit]]___[cond:& > a",
43
- "cursor]___[value:pointer]___[cond:& > a",
44
- "transition]___[value:fast]___[cond:& > a",
45
- "opacity]___[value:0.7]___[cond:& > a",
46
- "opacity]___[value:1]___[cond:& > a<___>_hover",
47
- "textDecoration]___[value:none]___[cond:& > a",
48
- "textDecoration]___[value:underline]___[cond:& > a<___>_hover",
49
42
  "stroke]___[value:2.5",
43
+ "opacity]___[value:0.7",
44
+ "textDecoration]___[value:none",
45
+ "textDecoration]___[value:underline]___[cond:_hover",
50
46
  "height]___[value:12",
51
47
  "width]___[value:12",
52
48
  "height]___[value:30px",
@@ -240,6 +236,7 @@
240
236
  "position]___[value:bottom-end",
241
237
  "boxShadow]___[value:xl",
242
238
  "display]___[value:flex]___[cond:@/xs",
239
+ "paddingBlock]___[value:1",
243
240
  "alignItems]___[value:baseline",
244
241
  "stroke]___[value:1.8",
245
242
  "marginTop]___[value:1",
@@ -248,16 +245,17 @@
248
245
  "gap]___[value:md",
249
246
  "margin]___[value:xs",
250
247
  "padding]___[value:md",
251
- "maxWidth]___[value:calc(100cqw - 32px)",
252
- "minWidth]___[value:calc(100cqw - 50px)",
248
+ "paddingBottom]___[value:lg",
249
+ "maxWidth]___[value:calc(100cqw - 52px)",
250
+ "minWidth]___[value:200px",
253
251
  "maxHeight]___[value:calc(100cqh - 100px)",
254
252
  "overflow]___[value:auto",
255
253
  "overscrollBehavior]___[value:contain",
256
254
  "minWidth]___[value:400]___[cond:@/sm",
257
255
  "maxWidth]___[value:550]___[cond:@/sm",
258
256
  "maxWidth]___[value:700]___[cond:@/lg",
259
- "marginBlock]___[value:md",
260
257
  "overflow]___[value:visible",
258
+ "color]___[value:mantine.colors.gray[4]]___[cond:_dark",
261
259
  "color]___[value:mantine.colors.gray[8]]___[cond:_light",
262
260
  "opacity]___[value:0.5",
263
261
  "marginInlineEnd]___[value:0.5",
@@ -313,10 +311,14 @@
313
311
  "borderColor]___[value:mantine.colors.gray[5]",
314
312
  "borderRadius]___[value:3",
315
313
  "transform]___[value:translate(-50%, -50%)",
316
- "flexShrink]___[value:0",
317
- "marginRight]___[value:sm",
318
314
  "borderColor]___[value:mantine.colors.orange[6]",
319
315
  "borderWidth]___[value:4]___[cond:md",
316
+ "marginRight]___[value:sm",
317
+ "flexShrink]___[value:0",
318
+ "display]___[value:[inherit]]___[cond:@/md",
319
+ "marginInlineStart]___[value:0",
320
+ "marginInlineStart]___[value:2]___[cond:@/md",
321
+ "height]___[value:26",
320
322
  "top]___[value:[1px]",
321
323
  "right]___[value:[1px]",
322
324
  "zIndex]___[value:9",
@@ -326,6 +328,8 @@
326
328
  "--text-fz]___[value:{fontSizes.sm}",
327
329
  "--text-fz]___[value:{fontSizes.md}]___[cond:md",
328
330
  "paddingTop]___[value:xxs",
331
+ "maxWidth]___[value:calc(100cqw - 32px)",
332
+ "minWidth]___[value:calc(100cqw - 50px)",
329
333
  "boxSizing]___[value:border-box",
330
334
  "inset]___[value:0",
331
335
  "width]___[value:100vw",
@@ -336,6 +340,7 @@
336
340
  "backdropBlur]___[value:var(--_blur)]___[cond:_backdrop",
337
341
  "backgroundColor]___[value:[rgb(36 36 36 / var(--_opacity, 5%))]]___[cond:_backdrop",
338
342
  "gap]___[value:lg",
343
+ "color]___[value:mantine.colors.text",
339
344
  "backgroundColor]___[value:mantine.colors.body",
340
345
  "backgroundColor]___[value:mantine.colors.dark[6]]___[cond:_dark",
341
346
  "border]___[value:none",
@@ -419,13 +424,15 @@
419
424
  "cursor]___[value:se-resize",
420
425
  "borderWidth]___[value:4px]___[cond:_hover",
421
426
  "borderColor]___[value:mantine.colors.dark[1]]___[cond:_hover",
427
+ "alignItems]___[value:start",
428
+ "justifyContent]___[value:space-between",
422
429
  "marginBottom]___[value:sm",
423
- "gap]___[value:6",
424
430
  "lineClamp]___[value:1",
425
431
  "gap]___[value:4",
426
432
  "marginTop]___[value:6",
427
433
  "stroke]___[value:1.6",
428
434
  "paddingTop]___[value:xs",
435
+ "gap]___[value:6",
429
436
  "gap]___[value:[4px 4px]",
430
437
  "paddingRight]___[value:xxs",
431
438
  "transitionProperty]___[value:all",
@@ -436,7 +443,7 @@
436
443
  "color]___[value:mantine.colors.defaultColor]___[cond:_groupHover",
437
444
  "background]___[value:mantine.colors.defaultHover]___[cond:_groupHover",
438
445
  "whiteSpace]___[value:pre",
439
- "fontFamily]___[value:[var(--mantine-font-family-monospace)]",
446
+ "fontFamily]___[value:mono",
440
447
  "overscrollBehavior]___[value:none",
441
448
  "marginBottom]___[value:sm]___[cond:&[data-level='1']",
442
449
  "marginBottom]___[value:0",
@@ -660,7 +667,6 @@
660
667
  "top]___[value:[2rem]",
661
668
  "left]___[value:[50%]",
662
669
  "maxWidth]___[value:600px",
663
- "minWidth]___[value:200px",
664
670
  "transform]___[value:translateX(-50%)",
665
671
  "zIndex]___[value:903",
666
672
  "marginTop]___[value:[32px]]___[cond:& + &",
@@ -668,11 +674,8 @@
668
674
  "transitionDelay]___[value:0.2s",
669
675
  "transitionDelay]___[value:0s]___[cond:_hover",
670
676
  "lineClamp]___[value:5",
671
- "fill]___[value:[none]",
672
- "strokeOpacity]___[value:0",
677
+ "fill]___[value:none",
673
678
  "transition]___[value:none]___[cond:_reduceGraphics",
674
- "display]___[value:none]___[cond:_reduceGraphicsOnPan",
675
- "display]___[value:none]___[cond:_smallZoom",
676
679
  "strokeWidth]___[value:calc(var(--xy-edge-stroke-width) + 2)",
677
680
  "strokeOpacity]___[value:0.08",
678
681
  "transitionProperty]___[value:stroke-width, stroke-opacity]___[cond:_noReduceGraphics",
@@ -686,8 +689,7 @@
686
689
  "strokeOpacity]___[value:0.4]___[cond:_whenSelected<___>_whenHovered",
687
690
  "fill]___[value:[var(--xy-edge-stroke)]",
688
691
  "stroke]___[value:[var(--xy-edge-stroke)]",
689
- "fill]___[value:[none!]",
690
- "strokeDashoffset]___[value:10",
692
+ "strokeDashoffset]___[value:0",
691
693
  "animationStyle]___[value:xyedgeAnimated]___[cond:_noReduceGraphics",
692
694
  "animationPlayState]___[value:paused]___[cond:_noReduceGraphics",
693
695
  "transition]___[value:stroke 130ms ease-out,stroke-width 130ms ease-out]___[cond:_noReduceGraphics",
@@ -703,6 +705,7 @@
703
705
  "top]___[value:[calc(100% - 30px)]",
704
706
  "width]___[value:auto",
705
707
  "minHeight]___[value:30px",
708
+ "display]___[value:none]___[cond:_smallZoom",
706
709
  "top]___[value:0.5",
707
710
  "right]___[value:[5px]]___[cond:_shapeBrowser",
708
711
  "top]___[value:[14px]]___[cond:_shapeCylinder",
@@ -759,6 +762,25 @@
759
762
  "cursor]___[value:grabbing",
760
763
  "cursor]___[value:grabbing !important]___[cond:& *",
761
764
  "cursor]___[value:grabbing !important]___[cond:& .react-flow__edge-interaction",
765
+ "border]___[value:default",
766
+ "borderWidth]___[value:1",
767
+ "--_color]___[value:var(--likec4-palette-stroke)",
768
+ "--_color]___[value:[color-mix(in srgb, var(--likec4-palette-hiContrast) 40%, var(--likec4-palette-fill))]]___[cond:_dark",
769
+ "borderColor]___[value:[var(--_color)/30]",
770
+ "backgroundColor]___[value:var(--likec4-palette-fill)/15",
771
+ "paddingLeft]___[value:2",
772
+ "paddingTop]___[value:0.5",
773
+ "fontWeight]___[value:bold",
774
+ "letterSpacing]___[value:.75px",
775
+ "color]___[value:[var(--_color)/75]",
776
+ "backgroundColor]___[value:var(--likec4-palette-fill)",
777
+ "borderRadius]___[value:xs",
778
+ "width]___[value:5px",
779
+ "width]___[value:7px]___[cond:_whenHovered",
780
+ "width]___[value:7px]___[cond:_whenSelected",
781
+ "translateX]___[value:-1/2",
782
+ "translateY]___[value:-1/2",
783
+ "top]___[value:1",
762
784
  "position]___[value:top-end",
763
785
  "minWidth]___[value:200",
764
786
  "maxWidth]___[value:calc(100vw - 16px)",
@@ -774,7 +796,6 @@
774
796
  "marginBottom]___[value:xs",
775
797
  "height]___[value:sm",
776
798
  "paddingBlock]___[value:2",
777
- "opacity]___[value:0.7",
778
799
  "flex]___[value:0 0 auto",
779
800
  "maxHeight]___[value:60",
780
801
  "right]___[value:0",
@@ -1,5 +1,12 @@
1
1
  import type * as t from '@likec4/core/types'
2
- import type { DiagramEdge, DiagramNode, LayoutedView, ViewChange, WhereOperator } from '@likec4/core/types'
2
+ import type {
3
+ DiagramEdge,
4
+ DiagramNode,
5
+ DynamicViewDisplayVariant,
6
+ LayoutedView,
7
+ ViewChange,
8
+ WhereOperator,
9
+ } from '@likec4/core/types'
3
10
  import type { ReactFlowProps as XYFlowProps } from '@xyflow/react'
4
11
  import type { MouseEvent as ReactMouseEvent, ReactNode } from 'react'
5
12
  import type { SetRequired } from 'type-fest'
@@ -250,6 +257,12 @@ export interface LikeC4DiagramProperties<A extends Any = Any> {
250
257
  */
251
258
  enableDynamicViewWalkthrough?: boolean | undefined
252
259
 
260
+ /**
261
+ * Default dynamic view display variant
262
+ * @default 'diagram'
263
+ */
264
+ dynamicViewVariant?: DynamicViewDisplayVariant | undefined
265
+
253
266
  /**
254
267
  * Display element tags in the bottom left corner
255
268
  * @default false
@@ -1,6 +1,7 @@
1
1
  import type { Any } from '@likec4/core/types'
2
2
  import { ReactFlowProvider as XYFlowProvider } from '@xyflow/react'
3
3
  import { type PropsWithChildren, useRef } from 'react'
4
+ import { FitViewPaddings } from './base'
4
5
  import {
5
6
  DiagramEventHandlers,
6
7
  DiagramFeatures,
@@ -37,9 +38,10 @@ export function LikeC4Diagram<A extends Any = Any>({
37
38
  onBurgerMenuClick,
38
39
  view,
39
40
  className,
40
- fitView = true,
41
- fitViewPadding = '8px',
42
41
  readonly = true,
42
+ controls = !readonly,
43
+ fitView = true,
44
+ fitViewPadding = controls === 'next' ? FitViewPaddings.withControls : FitViewPaddings.default,
43
45
  pannable = true,
44
46
  zoomable = true,
45
47
  background = 'dots',
@@ -50,11 +52,11 @@ export function LikeC4Diagram<A extends Any = Any>({
50
52
  enableRelationshipBrowser = enableRelationshipDetails,
51
53
  nodesDraggable = !readonly,
52
54
  nodesSelectable = !readonly || enableFocusMode || !!onNavigateTo || !!onNodeClick,
53
- controls = !readonly,
54
55
  showDiagramTitle = true,
55
56
  showNotations = true,
56
57
  showNavigationButtons = !!onNavigateTo,
57
58
  enableDynamicViewWalkthrough = false,
59
+ dynamicViewVariant,
58
60
  enableSearch = true,
59
61
  initialWidth,
60
62
  initialHeight,
@@ -63,7 +65,7 @@ export function LikeC4Diagram<A extends Any = Any>({
63
65
  renderIcon,
64
66
  renderControls,
65
67
  where,
66
- reactFlowProps = {},
68
+ reactFlowProps,
67
69
  renderNodes,
68
70
  children,
69
71
  }: LikeC4DiagramProps<A>) {
@@ -144,6 +146,7 @@ export function LikeC4Diagram<A extends Any = Any>({
144
146
  fitViewPadding={fitViewPadding}
145
147
  nodesSelectable={nodesSelectable}
146
148
  where={where ?? null}
149
+ dynamicViewVariant={dynamicViewVariant}
147
150
  >
148
151
  <ControlsCustomLayoutProvider value={renderControls ?? null}>
149
152
  <LikeC4DiagramXYFlow
package/src/base/const.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { ViewPadding } from '../LikeC4Diagram.props'
2
+
1
3
  export const ZIndexes = {
2
4
  Compound: 1,
3
5
  // XYFlow increments zIndexes of compounds
@@ -8,3 +10,13 @@ export const ZIndexes = {
8
10
 
9
11
  export const MinZoom = 0.05
10
12
  export const MaxZoom = 3
13
+
14
+ export const FitViewPaddings = {
15
+ default: '16px',
16
+ withControls: {
17
+ top: '50px',
18
+ left: '16px',
19
+ right: '16px',
20
+ bottom: '16px',
21
+ },
22
+ } satisfies Record<string, ViewPadding>
package/src/base/index.ts CHANGED
@@ -8,3 +8,5 @@ export {
8
8
  type ReactFlowEdge,
9
9
  type ReactFlowNode,
10
10
  } from './types'
11
+
12
+ export * from './const'
@@ -45,6 +45,7 @@ export const MarkdownBlock = forwardRef<HTMLDivElement, MarkdownBlockProps>(({
45
45
  hideIfEmpty = false,
46
46
  emptyText = 'no content',
47
47
  className,
48
+ style,
48
49
  ...props
49
50
  }, ref) => {
50
51
  if (value.isEmpty && hideIfEmpty) {
@@ -67,6 +68,7 @@ export const MarkdownBlock = forwardRef<HTMLDivElement, MarkdownBlockProps>(({
67
68
  className,
68
69
  )}
69
70
  style={{
71
+ ...style,
70
72
  ...props.fontSize && {
71
73
  '--text-fz': `var(--font-sizes-${props.fontSize}, var(--font-sizes-md))`,
72
74
  },
@@ -50,6 +50,8 @@ export const EdgeLabel = forwardRef<HTMLDivElement, EdgeLabelProps>((
50
50
  cursor: selectable || stepNum !== null ? 'pointer' : 'default',
51
51
  })
52
52
 
53
+ const hasLabel = isTruthy(label) || isTruthy(technology)
54
+
53
55
  return (
54
56
  <m.div
55
57
  ref={ref}
@@ -65,25 +67,27 @@ export const EdgeLabel = forwardRef<HTMLDivElement, EdgeLabelProps>((
65
67
  {stepNum}
66
68
  </Box>
67
69
  )}
68
- <Box className={classes.labelContents}>
69
- {isTruthy(label) && (
70
- <Box
71
- className={cx(
72
- classes.labelText,
73
- css({
74
- lineClamp: 5,
75
- }),
76
- )}>
77
- {label}
78
- </Box>
79
- )}
80
- {isTruthy(technology) && (
81
- <Box className={classes.labelTechnology}>
82
- {'[ ' + technology + ' ]'}
83
- </Box>
84
- )}
85
- {children}
86
- </Box>
70
+ {hasLabel && (
71
+ <Box className={classes.labelContents}>
72
+ {isTruthy(label) && (
73
+ <Box
74
+ className={cx(
75
+ classes.labelText,
76
+ css({
77
+ lineClamp: 5,
78
+ }),
79
+ )}>
80
+ {label}
81
+ </Box>
82
+ )}
83
+ {isTruthy(technology) && (
84
+ <Box className={classes.labelTechnology}>
85
+ {'[ ' + technology + ' ]'}
86
+ </Box>
87
+ )}
88
+ {children}
89
+ </Box>
90
+ )}
87
91
  </m.div>
88
92
  )
89
93
  })
@@ -1,9 +1,10 @@
1
1
  import type { DiagramEdge } from '@likec4/core/types'
2
- import { css, cx } from '@likec4/styles/css'
2
+ import { cx } from '@likec4/styles/css'
3
3
  import { EdgeLabelRenderer } from '@xyflow/react'
4
- import { type HTMLAttributes } from 'react'
4
+ import { type HTMLAttributes, useCallback } from 'react'
5
5
  import { isNumber } from 'remeda'
6
6
  import type { UndefinedOnPartialDeep } from 'type-fest'
7
+ import { useXYStore } from '../../../hooks'
7
8
  import { ZIndexes } from '../../const'
8
9
  import type { EdgeProps } from '../../types'
9
10
 
@@ -50,10 +51,14 @@ export function EdgeLabelContainer({
50
51
  children,
51
52
  ...rest
52
53
  }: EdgeLabelContainerProps) {
53
- let zIndex = ZIndexes.Edge
54
+ let zIndex = useXYStore(
55
+ useCallback((state) => {
56
+ return state.edgeLookup.get(id)?.zIndex ?? ZIndexes.Edge
57
+ }, [id]),
58
+ )
59
+ // Move above the elements
54
60
  if (isHovered || isActive) {
55
- // Move above the elements
56
- zIndex = ZIndexes.Element + 1
61
+ zIndex += 100
57
62
  }
58
63
 
59
64
  let labelX = labelXY?.x ?? labelBBox?.x,
@@ -65,9 +70,10 @@ export function EdgeLabelContainer({
65
70
  const translate = labelXY?.translate
66
71
 
67
72
  return (
68
- <EdgeLabelRenderer key={id}>
73
+ <EdgeLabelRenderer>
69
74
  <div
70
75
  key={id}
76
+ {...rest}
71
77
  className={cx(
72
78
  'nodrag nopan',
73
79
  'likec4-edge-label-container',
@@ -88,7 +94,6 @@ export function EdgeLabelContainer({
88
94
  ...style,
89
95
  transform: `translate(${toCssVarValue(labelX)}, ${toCssVarValue(labelY)}) ${translate || ''}`,
90
96
  }}
91
- {...rest}
92
97
  >
93
98
  {children}
94
99
  </div>
@@ -3,7 +3,7 @@ import { css, cx } from '@likec4/styles/css'
3
3
  import { type PointerEventHandler, forwardRef } from 'react'
4
4
  import type { UndefinedOnPartialDeep } from 'type-fest'
5
5
  import type { EdgeProps } from '../../types'
6
- import { cssEdgePath, edgePathBg, hideOnReducedGraphics, markerContext } from './edge.css'
6
+ import { cssEdgePath, edgePathBg, markerContext } from './edge.css'
7
7
  import { arrowTypeToMarker, EdgeMarkers } from './EdgeMarkers'
8
8
 
9
9
  type Data = UndefinedOnPartialDeep<
@@ -32,6 +32,7 @@ export const EdgePath = forwardRef<SVGPathElement, EdgePathProps>(({
32
32
  tail,
33
33
  head,
34
34
  },
35
+ selectable = true,
35
36
  style,
36
37
  interactionWidth,
37
38
  },
@@ -71,25 +72,34 @@ export const EdgePath = forwardRef<SVGPathElement, EdgePathProps>(({
71
72
 
72
73
  return (
73
74
  <>
74
- <path
75
- className={cx(
76
- 'react-flow__edge-interaction',
77
- hideOnReducedGraphics,
78
- css({
79
- fill: '[none]',
75
+ {selectable && (
76
+ <path
77
+ className={cx(
78
+ 'react-flow__edge-interaction',
79
+ 'hide-on-reduced-graphics',
80
+ css({
81
+ fill: 'none',
82
+ }),
83
+ )}
84
+ d={svgPath}
85
+ style={{
86
+ strokeWidth: interactionWidth ?? 10,
87
+ stroke: 'currentcolor',
80
88
  strokeOpacity: 0,
81
- }),
82
- )}
83
- d={svgPath}
84
- strokeWidth={interactionWidth ?? 10}
85
- />
89
+ }}
90
+ />
91
+ )}
86
92
  <g className={markerContext} onPointerDown={onEdgePointerDown}>
87
93
  <defs>
88
94
  {MarkerStart && <MarkerStart id={'start' + id} />}
89
95
  {MarkerEnd && <MarkerEnd id={'end' + id} />}
90
96
  </defs>
91
97
  <path
92
- className={cx('react-flow__edge-path', edgePathBg)}
98
+ className={cx(
99
+ 'react-flow__edge-path',
100
+ 'hide-on-reduced-graphics',
101
+ edgePathBg,
102
+ )}
93
103
  d={svgPath}
94
104
  style={style}
95
105
  strokeLinecap={'round'}
@@ -98,7 +108,7 @@ export const EdgePath = forwardRef<SVGPathElement, EdgePathProps>(({
98
108
  ref={svgPathRef}
99
109
  className={cx(
100
110
  'react-flow__edge-path',
101
- 'react-flow__edge-interaction',
111
+ selectable && 'react-flow__edge-interaction',
102
112
  cssEdgePath,
103
113
  )}
104
114
  d={svgPath}
@@ -113,3 +123,4 @@ export const EdgePath = forwardRef<SVGPathElement, EdgePathProps>(({
113
123
  </>
114
124
  )
115
125
  })
126
+ EdgePath.displayName = 'EdgePath'
@@ -8,18 +8,9 @@ export const edgeContainer = css({
8
8
  },
9
9
  })
10
10
 
11
- const _hideOnReducedGraphics = css.raw({
12
- _reduceGraphicsOnPan: {
13
- display: 'none',
14
- },
15
- _smallZoom: {
16
- display: 'none',
17
- },
18
- })
19
- export const hideOnReducedGraphics = css(_hideOnReducedGraphics)
20
-
21
- export const edgePathBg = css(_hideOnReducedGraphics, {
22
- fill: '[none]',
11
+ export const edgePathBg = css({
12
+ pointerEvents: 'none',
13
+ fill: 'none',
23
14
  strokeWidth: 'calc(var(--xy-edge-stroke-width) + 2)',
24
15
  strokeOpacity: 0.08,
25
16
  _noReduceGraphics: {
@@ -48,8 +39,8 @@ export const markerContext = css({
48
39
  })
49
40
 
50
41
  export const cssEdgePath = css({
51
- fill: '[none!]',
52
- strokeDashoffset: 10,
42
+ fill: 'none',
43
+ strokeDashoffset: 0,
53
44
  _noReduceGraphics: {
54
45
  animationStyle: 'xyedgeAnimated',
55
46
  animationPlayState: 'paused',
@@ -4,7 +4,6 @@ import { actionBtn } from '@likec4/styles/recipes'
4
4
  import { ActionIcon } from '@mantine/core'
5
5
  import { useId } from '@mantine/hooks'
6
6
  import * as m from 'motion/react-m'
7
- import { useIsZoomTooSmall } from '../../../hooks/useXYFlow'
8
7
  import { stopPropagation } from '../../../utils/xyflow'
9
8
  import type { NodeProps } from '../../types'
10
9
 
@@ -43,8 +42,7 @@ export function ElementActionButtons({
43
42
  buttons,
44
43
  }: ElementActionButtonsProps) {
45
44
  const id = useId()
46
- const zoomTooSmall = useIsZoomTooSmall()
47
- if (!buttons.length || zoomTooSmall) {
45
+ if (!buttons.length) {
48
46
  return null
49
47
  }
50
48
  return (
@@ -2,11 +2,9 @@ import {
2
2
  type Color,
3
3
  type ElementShape,
4
4
  type ElementStyle,
5
- DefaultPaddingSize,
6
- DefaultShapeSize,
7
- DefaultTextSize,
5
+ ensureSizes,
8
6
  } from '@likec4/core/types'
9
- import { css, cx } from '@likec4/styles/css'
7
+ import { cx } from '@likec4/styles/css'
10
8
  import type { MotionNodeLayoutOptions } from 'motion/react'
11
9
  import * as m from 'motion/react-m'
12
10
  import { type CSSProperties, type ReactNode, forwardRef } from 'react'
@@ -28,31 +26,6 @@ export type ElementNodeContainerProps =
28
26
  [key: `data-${string}`]: string | undefined
29
27
  }
30
28
  & MotionNodeLayoutOptions
31
-
32
- export function nodeSizes({
33
- size,
34
- padding,
35
- textSize,
36
- }: ElementStyle) {
37
- if (!size && !!textSize) {
38
- size = textSize
39
- }
40
- if (!textSize && !!size) {
41
- textSize = size
42
- }
43
- if (!padding && !!size) {
44
- padding = size
45
- }
46
- size ??= DefaultShapeSize
47
- textSize ??= DefaultTextSize
48
- padding ??= DefaultPaddingSize
49
- return {
50
- size,
51
- padding,
52
- textSize,
53
- }
54
- }
55
-
56
29
  /**
57
30
  * Top-level primitive to compose leaf nodes renderers.
58
31
  * This container provides the state via data-* attributes
@@ -86,7 +59,7 @@ export const ElementNodeContainer = forwardRef<HTMLDivElement, ElementNodeContai
86
59
  size,
87
60
  padding,
88
61
  textSize,
89
- } = nodeSizes(data.style ?? {})
62
+ } = ensureSizes(data.style ?? {})
90
63
 
91
64
  return (
92
65
  <m.div
@@ -1,4 +1,4 @@
1
- import type { DiagramNode, RichTextOrEmpty } from '@likec4/core/types'
1
+ import { type DiagramNode, type RichTextOrEmpty, ensureSizes } from '@likec4/core/types'
2
2
  import { cx } from '@likec4/styles/css'
3
3
  import { Box } from '@likec4/styles/jsx'
4
4
  import { elementNodeData, elementNodeIcon as elementIconRecipe } from '@likec4/styles/recipes'
@@ -8,7 +8,6 @@ import type { Simplify } from 'type-fest'
8
8
  import { IconRenderer } from '../../../context/IconRenderer'
9
9
  import type { NodeProps, NonOptional } from '../../types'
10
10
  import { MarkdownBlock } from '../MarkdownBlock'
11
- import { nodeSizes } from './ElementNodeContainer'
12
11
 
13
12
  type Data = Simplify<
14
13
  & NonOptional<
@@ -44,7 +43,7 @@ export function ElementTitle({ id, data, iconSize }: ElementTitleProps) {
44
43
  hasDescription: !!data.description?.nonEmpty,
45
44
  hasTechnology: !isEmpty(data.technology ?? ''),
46
45
  })
47
- const size = nodeSizes(data.style).size
46
+ const { size } = ensureSizes(data.style)
48
47
  const isSm = size === 'sm'
49
48
  const isSmOrXs = isSm || size === 'xs'
50
49
  return (