@likec4/diagram 1.36.1 → 1.37.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 (173) hide show
  1. package/bundle/{chunk-DHvr-RGh.js → chunk-DSORWspW.js} +1008 -988
  2. package/bundle/custom.js +64 -56
  3. package/bundle/index.js +3539 -3315
  4. package/dist/LikeC4Diagram.props.d.ts +5 -5
  5. package/dist/LikeC4Styles.js +17 -15
  6. package/dist/StaticLikeC4Diagram.d.ts +1 -1
  7. package/dist/StaticLikeC4Diagram.js +3 -0
  8. package/dist/base/BaseXYFlow.d.ts +1 -1
  9. package/dist/base/BaseXYFlow.js +25 -27
  10. package/dist/base/const.d.ts +4 -4
  11. package/dist/base/const.js +5 -4
  12. package/dist/base/primitives/MarkdownBlock.js +4 -1
  13. package/dist/base/primitives/compound/CompoundActionButton.js +27 -42
  14. package/dist/base/primitives/compound/CompoundDetailsButton.js +23 -48
  15. package/dist/base/primitives/compound/CompoundNodeContainer.js +16 -48
  16. package/dist/base/primitives/compound/CompoundTitle.js +5 -80
  17. package/dist/base/primitives/compound/actionbtns.css.js +1 -13
  18. package/dist/base/primitives/customEdge.d.ts +1 -1
  19. package/dist/base/primitives/customNode.d.ts +4 -4
  20. package/dist/base/primitives/customNode.js +7 -7
  21. package/dist/base/primitives/edge/EdgeLabel.d.ts +5 -4
  22. package/dist/base/primitives/edge/EdgeLabel.js +39 -21
  23. package/dist/base/primitives/edge/EdgeLabelContainer.js +11 -23
  24. package/dist/base/primitives/edge/edge.css.js +19 -11
  25. package/dist/base/primitives/element/ElementShape.js +38 -18
  26. package/dist/base/primitives/element/ElementTags.js +7 -4
  27. package/dist/base/primitives/element/ElementTitle.js +10 -2
  28. package/dist/base/types.d.ts +17 -21
  29. package/dist/bundle/LikeC4View.d.ts +2 -2
  30. package/dist/bundle/LikeC4View.js +4 -1
  31. package/dist/bundle/LikeC4View.props.d.ts +2 -2
  32. package/dist/bundle/ReactLikeC4.d.ts +3 -3
  33. package/dist/bundle/custom.js +2 -1
  34. package/dist/bundle/index.js +2 -1
  35. package/dist/components/Link.js +3 -2
  36. package/dist/context/ReduceGraphics.js +2 -5
  37. package/dist/context/RootContainer.js +1 -5
  38. package/dist/custom/customNodes.d.ts +32 -26
  39. package/dist/custom/customNodes.js +12 -8
  40. package/dist/custom/hooks.d.ts +2 -1
  41. package/dist/custom/index.js +2 -1
  42. package/dist/globals.css.js +1 -1
  43. package/dist/hooks/index.d.ts +1 -1
  44. package/dist/hooks/useDiagram.d.ts +18 -1
  45. package/dist/hooks/useDiagram.js +18 -2
  46. package/dist/hooks/useXYFlow.d.ts +40 -21
  47. package/dist/index.d.ts +1 -1
  48. package/dist/index.js +2 -1
  49. package/dist/likec4diagram/DiagramUI.js +5 -2
  50. package/dist/likec4diagram/DiagramXYFlow.js +9 -9
  51. package/dist/likec4diagram/custom/edges/RelationshipEdge.d.ts +3 -3
  52. package/dist/likec4diagram/custom/edges/RelationshipEdge.js +27 -44
  53. package/dist/likec4diagram/custom/index.js +3 -3
  54. package/dist/likec4diagram/custom/nodes/nodes.d.ts +8 -6
  55. package/dist/likec4diagram/custom/nodes/nodes.js +13 -14
  56. package/dist/likec4diagram/custom/nodes/toolbar/CompoundToolbar.js +3 -2
  57. package/dist/likec4diagram/custom/nodes/toolbar/_shared.d.ts +2 -2
  58. package/dist/likec4diagram/relationship-popover/RelationshipPopover.d.ts +2 -0
  59. package/dist/likec4diagram/relationship-popover/RelationshipPopover.js +441 -0
  60. package/dist/likec4diagram/relationship-popover/actor.d.ts +177 -0
  61. package/dist/likec4diagram/relationship-popover/actor.js +155 -0
  62. package/dist/likec4diagram/relationship-popover/styles.css.d.ts +2 -0
  63. package/dist/likec4diagram/{custom/edges/RelationshipsDropdownMenu.css.js → relationship-popover/styles.css.js} +4 -17
  64. package/dist/likec4diagram/useLayoutConstraints.js +0 -1
  65. package/dist/likec4model/useLikeC4ElementsTree.js +1 -1
  66. package/dist/likec4model/useLikeC4Project.js +15 -1
  67. package/dist/navigationpanel/NavigationPanelDropdown.js +1 -2
  68. package/dist/navigationpanel/actor.js +1 -2
  69. package/dist/navigationpanel/controls/NavigationButtons.js +1 -5
  70. package/dist/navigationpanel/controls/ViewDetailsCard.js +2 -0
  71. package/dist/overlays/element-details/actor.d.ts +564 -8
  72. package/dist/overlays/overlay/Overlay.css.d.ts +1 -1
  73. package/dist/overlays/relationship-details/actor.d.ts +3 -1
  74. package/dist/overlays/relationship-details/hooks.d.ts +19 -1
  75. package/dist/overlays/relationship-details/layout-to-xyflow.js +0 -1
  76. package/dist/overlays/relationship-details/layout.js +1 -2
  77. package/dist/overlays/relationships-browser/actor.d.ts +26 -2
  78. package/dist/overlays/relationships-browser/custom/nodeTypes.d.ts +16 -0
  79. package/dist/overlays/relationships-browser/custom/nodeTypes.js +18 -8
  80. package/dist/overlays/relationships-browser/useViewToNodesEdges.js +0 -1
  81. package/dist/search/components/_shared.css.d.ts +1 -1
  82. package/dist/state/DiagramActorProvider.js +2 -19
  83. package/dist/state/assign.js +24 -10
  84. package/dist/state/diagram-machine.d.ts +149 -474
  85. package/dist/state/diagram-machine.js +94 -54
  86. package/dist/state/types.d.ts +1 -1
  87. package/dist/styles-min.css +1 -1
  88. package/dist/styles-xyflow.css +1 -1
  89. package/dist/styles.css +1 -1
  90. package/dist/styles.css2.js +1 -1
  91. package/dist/utils/index.d.ts +2 -1
  92. package/dist/utils/roundDpr.d.ts +1 -0
  93. package/dist/utils/roundDpr.js +20 -0
  94. package/dist/utils/xyflow.d.ts +0 -1
  95. package/dist/utils/xyflow.js +1 -7
  96. package/package.json +11 -10
  97. package/panda.buildinfo.json +90 -155
  98. package/src/LikeC4Diagram.props.ts +5 -5
  99. package/src/LikeC4Styles.tsx +22 -14
  100. package/src/StaticLikeC4Diagram.tsx +3 -0
  101. package/src/base/BaseXYFlow.tsx +26 -29
  102. package/src/base/const.ts +5 -4
  103. package/src/base/primitives/MarkdownBlock.tsx +6 -1
  104. package/src/base/primitives/compound/CompoundActionButton.tsx +31 -43
  105. package/src/base/primitives/compound/CompoundDetailsButton.tsx +26 -48
  106. package/src/base/primitives/compound/CompoundNodeContainer.tsx +15 -43
  107. package/src/base/primitives/compound/CompoundTitle.tsx +4 -76
  108. package/src/base/primitives/compound/actionbtns.css.ts +0 -12
  109. package/src/base/primitives/customEdge.ts +1 -1
  110. package/src/base/primitives/customNode.tsx +20 -24
  111. package/src/base/primitives/edge/EdgeLabel.tsx +23 -8
  112. package/src/base/primitives/edge/EdgeLabelContainer.tsx +9 -21
  113. package/src/base/primitives/edge/edge.css.ts +19 -11
  114. package/src/base/primitives/element/ElementShape.tsx +40 -18
  115. package/src/base/primitives/element/ElementTags.tsx +7 -4
  116. package/src/base/primitives/element/ElementTitle.tsx +23 -11
  117. package/src/base/types.ts +21 -25
  118. package/src/bundle/LikeC4View.props.ts +2 -2
  119. package/src/bundle/LikeC4View.tsx +8 -5
  120. package/src/bundle/ReactLikeC4.tsx +3 -3
  121. package/src/components/Link.tsx +3 -2
  122. package/src/context/RootContainer.tsx +1 -5
  123. package/src/context/TagStylesContext.tsx +2 -0
  124. package/src/custom/{customNodes.tsx → customNodes.ts} +58 -52
  125. package/src/custom/hooks.ts +7 -0
  126. package/src/globals.css +58 -5
  127. package/src/hooks/index.ts +1 -1
  128. package/src/hooks/useDiagram.ts +39 -5
  129. package/src/hooks/useXYFlow.ts +3 -1
  130. package/src/index.ts +1 -0
  131. package/src/likec4diagram/DiagramUI.tsx +3 -0
  132. package/src/likec4diagram/DiagramXYFlow.tsx +9 -11
  133. package/src/likec4diagram/custom/edges/RelationshipEdge.tsx +25 -49
  134. package/src/likec4diagram/custom/index.ts +5 -4
  135. package/src/likec4diagram/custom/nodes/nodes.tsx +13 -11
  136. package/src/likec4diagram/custom/nodes/toolbar/CompoundToolbar.tsx +3 -2
  137. package/src/likec4diagram/relationship-popover/RelationshipPopover.tsx +535 -0
  138. package/src/likec4diagram/relationship-popover/actor.ts +192 -0
  139. package/src/likec4diagram/{custom/edges/RelationshipsDropdownMenu.css.ts → relationship-popover/styles.css.ts} +3 -19
  140. package/src/likec4diagram/useLayoutConstraints.ts +0 -1
  141. package/src/likec4model/useLikeC4ElementsTree.ts +1 -1
  142. package/src/navigationpanel/NavigationPanelDropdown.tsx +1 -2
  143. package/src/navigationpanel/actor.ts +2 -2
  144. package/src/navigationpanel/controls/NavigationButtons.tsx +1 -5
  145. package/src/navigationpanel/controls/ViewDetailsCard.tsx +2 -0
  146. package/src/overlays/relationship-details/layout-to-xyflow.ts +0 -1
  147. package/src/overlays/relationship-details/layout.ts +4 -3
  148. package/src/overlays/relationships-browser/custom/nodeTypes.tsx +22 -8
  149. package/src/overlays/relationships-browser/useViewToNodesEdges.ts +0 -1
  150. package/src/state/DiagramActorProvider.tsx +2 -20
  151. package/src/state/assign.ts +24 -10
  152. package/src/state/diagram-machine.ts +101 -53
  153. package/src/state/types.ts +4 -1
  154. package/src/utils/index.ts +2 -1
  155. package/src/utils/roundDpr.ts +27 -0
  156. package/src/utils/xyflow.ts +0 -7
  157. package/dist/base/primitives/compound/CompoundNodeContainer.css.d.ts +0 -35
  158. package/dist/base/primitives/compound/CompoundNodeContainer.css.js +0 -132
  159. package/dist/base/primitives/edge/EdgeLabel.css.d.ts +0 -7
  160. package/dist/base/primitives/edge/EdgeLabel.css.js +0 -57
  161. package/dist/base/primitives/element/ElementShape.css.d.ts +0 -6
  162. package/dist/base/primitives/element/ElementShape.css.js +0 -107
  163. package/dist/likec4diagram/custom/edges/NotePopover.css.js +0 -21
  164. package/dist/likec4diagram/custom/edges/NotePopover.js +0 -91
  165. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.css.d.ts +0 -5
  166. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.d.ts +0 -13
  167. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.js +0 -215
  168. package/dist/likec4diagram/custom/index.d.ts +0 -62
  169. package/dist/overlays/relationship-details/custom/nodeTypes.d.ts +0 -10
  170. package/src/base/primitives/compound/CompoundNodeContainer.css.ts +0 -138
  171. package/src/base/primitives/edge/EdgeLabel.css.ts +0 -64
  172. package/src/base/primitives/element/ElementShape.css.ts +0 -112
  173. package/src/likec4diagram/custom/edges/RelationshipsDropdownMenu.tsx +0 -281
@@ -24,6 +24,7 @@ import {
24
24
  useStoreApi,
25
25
  } from '@xyflow/react'
26
26
  import { type EdgeChange, type NodeChange, type Rect, type Viewport, nodeToRect } from '@xyflow/system'
27
+ import type { MouseEvent } from 'react'
27
28
  import { clamp, first, hasAtLeast, prop } from 'remeda'
28
29
  import type { PartialDeep } from 'type-fest'
29
30
  import {
@@ -149,8 +150,9 @@ export type Events =
149
150
  | { type: 'xyflow.resized' }
150
151
  | { type: 'xyflow.nodeMouseEnter'; node: Types.Node }
151
152
  | { type: 'xyflow.nodeMouseLeave'; node: Types.Node }
152
- | { type: 'xyflow.edgeMouseEnter'; edge: Types.Edge }
153
- | { type: 'xyflow.edgeMouseLeave'; edge: Types.Edge }
153
+ | { type: 'xyflow.edgeMouseEnter'; edge: Types.Edge; event: MouseEvent }
154
+ | { type: 'xyflow.edgeMouseLeave'; edge: Types.Edge; event: MouseEvent }
155
+ | { type: 'xyflow.edgeEditingStarted'; edge: Types.EdgeData }
154
156
  | { type: 'update.nodeData'; nodeId: NodeId; data: PartialDeep<Types.NodeData> }
155
157
  | { type: 'update.edgeData'; edgeId: EdgeId; data: PartialDeep<Types.EdgeData> }
156
158
  | { type: 'update.view'; view: DiagramView; xynodes: Types.Node[]; xyedges: Types.Edge[] }
@@ -184,6 +186,12 @@ export type EmittedEvents =
184
186
  | { type: 'navigateTo'; viewId: ViewId }
185
187
  | { type: 'viewChange'; change: ViewChange }
186
188
  | { type: 'openSource'; params: OpenSourceParams }
189
+ | { type: 'edgeMouseEnter'; edge: Types.Edge; event: MouseEvent }
190
+ | { type: 'edgeMouseLeave'; edge: Types.Edge; event: MouseEvent }
191
+ | { type: 'edgeEditingStarted'; edge: Types.Edge }
192
+ | { type: 'walkthroughStarted'; edge: Types.Edge }
193
+ | { type: 'walkthroughStep'; edge: Types.Edge }
194
+ | { type: 'walkthroughStopped' }
187
195
 
188
196
  export type ActionArg = { context: Context; event: Events }
189
197
 
@@ -417,6 +425,10 @@ const _diagramMachine = setup({
417
425
  features: { ...event.features },
418
426
  }
419
427
  }),
428
+ 'updateInputs': assign(({ event }) => {
429
+ assertEvent(event, 'update.inputs')
430
+ return { ...event.inputs }
431
+ }),
420
432
  'closeSearch': sendTo(
421
433
  ({ system }) => typedSystem(system).searchActorRef!,
422
434
  {
@@ -464,25 +476,41 @@ const _diagramMachine = setup({
464
476
  }),
465
477
  }
466
478
  }),
467
- 'onEdgeMouseEnter': assign(({ context }, params: { edge: Types.Edge }) => {
468
- return {
479
+ 'onEdgeMouseEnter': enqueueActions(({ enqueue, context, event }) => {
480
+ assertEvent(event, 'xyflow.edgeMouseEnter')
481
+ let edge = event.edge
482
+ enqueue.assign({
469
483
  xyedges: context.xyedges.map(e => {
470
- if (e.id === params.edge.id) {
471
- return Base.setHovered(e, true)
484
+ if (e.id === event.edge.id) {
485
+ edge = Base.setHovered(e, true)
486
+ return edge
472
487
  }
473
488
  return e
474
489
  }),
475
- }
490
+ })
491
+ enqueue.emit({
492
+ type: 'edgeMouseEnter',
493
+ edge,
494
+ event: event.event,
495
+ })
476
496
  }),
477
- 'onEdgeMouseLeave': assign(({ context }, params: { edge: Types.Edge }) => {
478
- return {
497
+ 'onEdgeMouseLeave': enqueueActions(({ enqueue, context, event }) => {
498
+ assertEvent(event, 'xyflow.edgeMouseLeave')
499
+ let edge = event.edge
500
+ enqueue.assign({
479
501
  xyedges: context.xyedges.map(e => {
480
- if (e.id === params.edge.id) {
481
- return Base.setHovered(e, false)
502
+ if (e.id === event.edge.id) {
503
+ edge = Base.setHovered(e, false)
504
+ return edge
482
505
  }
483
506
  return e
484
507
  }),
485
- }
508
+ })
509
+ enqueue.emit({
510
+ type: 'edgeMouseLeave',
511
+ edge,
512
+ event: event.event,
513
+ })
486
514
  }),
487
515
  'focus on nodes and edges': assign(focusNodesEdges),
488
516
  'notations.highlight': assign(({ context }, params: { notation: ElementNotation; kind?: string }) => {
@@ -524,6 +552,33 @@ const _diagramMachine = setup({
524
552
  })),
525
553
  })),
526
554
  'update active walkthrough': assign(updateActiveWalkthrough),
555
+ 'emit: walkthroughStarted': emit(({ context }) => {
556
+ const edge = context.xyedges.find(x => x.id === context.activeWalkthrough?.stepId)
557
+ invariant(edge, 'Invalid walkthrough state')
558
+ return {
559
+ type: 'walkthroughStarted',
560
+ edge,
561
+ }
562
+ }),
563
+ 'emit: walkthroughStep': emit(({ context }) => {
564
+ const edge = context.xyedges.find(x => x.id === context.activeWalkthrough?.stepId)
565
+ invariant(edge, 'Invalid walkthrough state')
566
+ return {
567
+ type: 'walkthroughStep',
568
+ edge,
569
+ }
570
+ }),
571
+ 'emit: walkthroughStopped': emit(() => ({
572
+ type: 'walkthroughStopped',
573
+ })),
574
+ 'emit: edgeEditingStarted': emit(({ context, event }) => {
575
+ assertEvent(event, 'xyflow.edgeEditingStarted')
576
+ const edge = nonNullable(context.xyedges.find(x => x.id === event.edge.id), `Edge ${event.edge.id} not found`)
577
+ return ({
578
+ type: 'edgeEditingStarted',
579
+ edge,
580
+ })
581
+ }),
527
582
  },
528
583
  }).createMachine({
529
584
  initial: 'initializing',
@@ -739,16 +794,10 @@ const _diagramMachine = setup({
739
794
  },
740
795
  },
741
796
  'xyflow.edgeMouseEnter': {
742
- actions: {
743
- type: 'onEdgeMouseEnter',
744
- params: prop('event'),
745
- },
797
+ actions: 'onEdgeMouseEnter',
746
798
  },
747
799
  'xyflow.edgeMouseLeave': {
748
- actions: {
749
- type: 'onEdgeMouseLeave',
750
- params: prop('event'),
751
- },
800
+ actions: 'onEdgeMouseLeave',
752
801
  },
753
802
  'notations.highlight': {
754
803
  actions: {
@@ -838,7 +887,7 @@ const _diagramMachine = setup({
838
887
  }),
839
888
  target: 'focused',
840
889
  },
841
- 'xyflow.edgeClick': [{
890
+ 'xyflow.edgeClick': {
842
891
  guard: and([
843
892
  'is dynamic view',
844
893
  'click: selected edge',
@@ -847,17 +896,7 @@ const _diagramMachine = setup({
847
896
  type: 'walkthrough.start',
848
897
  stepId: event.edge.id as StepEdgeId,
849
898
  })),
850
- }, {
851
- guard: and([
852
- 'enabled: RelationshipDetails',
853
- 'click: selected edge',
854
- ]) as any,
855
- actions: sendTo(({ system }) => typedSystem(system).overlaysActorRef!, ({ context, event }) => ({
856
- type: 'open.relationshipDetails',
857
- viewId: context.view.id,
858
- edgeId: event.edge.id as EdgeId,
859
- })),
860
- }],
899
+ },
861
900
  },
862
901
  },
863
902
  focused: {
@@ -944,6 +983,7 @@ const _diagramMachine = setup({
944
983
  }),
945
984
  'update active walkthrough',
946
985
  'xyflow:fitFocusedBounds',
986
+ 'emit: walkthroughStarted',
947
987
  ],
948
988
  on: {
949
989
  'key.esc': {
@@ -956,26 +996,29 @@ const _diagramMachine = setup({
956
996
  actions: raise({ type: 'walkthrough.step', direction: 'next' }),
957
997
  },
958
998
  'walkthrough.step': {
959
- actions: enqueueActions(({ enqueue, context, event }) => {
960
- const { stepId } = context.activeWalkthrough!
961
- const stepIndex = context.xyedges.findIndex(e => e.id === stepId)
962
- const nextStepIndex = clamp(event.direction === 'next' ? stepIndex + 1 : stepIndex - 1, {
963
- min: 0,
964
- max: context.xyedges.length - 1,
965
- })
966
- if (nextStepIndex === stepIndex) {
967
- return
968
- }
969
- const nextStepId = context.xyedges[nextStepIndex]!.id as StepEdgeId
970
- enqueue.assign({
971
- activeWalkthrough: {
972
- stepId: nextStepId,
973
- parallelPrefix: getParallelStepsPrefix(nextStepId),
974
- },
975
- })
976
- enqueue('update active walkthrough')
977
- enqueue('xyflow:fitFocusedBounds')
978
- }),
999
+ actions: [
1000
+ assign(({ context, event }) => {
1001
+ const { stepId } = context.activeWalkthrough!
1002
+ const stepIndex = context.xyedges.findIndex(e => e.id === stepId)
1003
+ const nextStepIndex = clamp(event.direction === 'next' ? stepIndex + 1 : stepIndex - 1, {
1004
+ min: 0,
1005
+ max: context.xyedges.length - 1,
1006
+ })
1007
+ if (nextStepIndex === stepIndex) {
1008
+ return {}
1009
+ }
1010
+ const nextStepId = context.xyedges[nextStepIndex]!.id as StepEdgeId
1011
+ return {
1012
+ activeWalkthrough: {
1013
+ stepId: nextStepId,
1014
+ parallelPrefix: getParallelStepsPrefix(nextStepId),
1015
+ },
1016
+ }
1017
+ }),
1018
+ 'update active walkthrough',
1019
+ 'xyflow:fitFocusedBounds',
1020
+ 'emit: walkthroughStep',
1021
+ ],
979
1022
  },
980
1023
  'xyflow.edgeClick': {
981
1024
  actions: [
@@ -992,6 +1035,7 @@ const _diagramMachine = setup({
992
1035
  }),
993
1036
  'update active walkthrough',
994
1037
  'xyflow:fitFocusedBounds',
1038
+ 'emit: walkthroughStep',
995
1039
  ],
996
1040
  },
997
1041
  'notations.unhighlight': {
@@ -1025,6 +1069,7 @@ const _diagramMachine = setup({
1025
1069
  activeWalkthrough: null,
1026
1070
  viewportBeforeFocus: null,
1027
1071
  })
1072
+ enqueue('emit: walkthroughStopped')
1028
1073
  }),
1029
1074
  },
1030
1075
  },
@@ -1089,6 +1134,9 @@ const _diagramMachine = setup({
1089
1134
  viewport: (({ event }) => event.viewport),
1090
1135
  }),
1091
1136
  },
1137
+ 'xyflow.edgeEditingStarted': {
1138
+ actions: 'emit: edgeEditingStarted',
1139
+ },
1092
1140
  'fitDiagram': {
1093
1141
  guard: 'enabled: FitView',
1094
1142
  actions: {
@@ -1151,7 +1199,7 @@ const _diagramMachine = setup({
1151
1199
  ],
1152
1200
  },
1153
1201
  'update.inputs': {
1154
- actions: assign(({ event }) => ({ ...event.inputs })),
1202
+ actions: 'updateInputs',
1155
1203
  },
1156
1204
  'update.features': {
1157
1205
  actions: [
@@ -23,7 +23,10 @@ export type DiagramActorSnapshot = SnapshotFrom<DiagramMachineLogic>
23
23
 
24
24
  export type DiagramActorEvent = EventFromLogic<DiagramMachineLogic>
25
25
 
26
- export type { Context as DiagramContext } from './diagram-machine'
26
+ export type {
27
+ Context as DiagramContext,
28
+ EmittedEvents as DiagramEmittedEvents,
29
+ } from './diagram-machine'
27
30
 
28
31
  export type SyncLayoutActorRef = Omit<ActorRefFromLogic<SyncLayoutActorLogic>, 'system'> & {
29
32
  system: System
@@ -10,5 +10,6 @@ export {
10
10
  isSamePoint,
11
11
  nodeToRect,
12
12
  stopPropagation,
13
- toDomPrecision,
14
13
  } from './xyflow'
14
+
15
+ export { roundDpr } from './roundDpr'
@@ -0,0 +1,27 @@
1
+ import { clamp } from 'remeda'
2
+
3
+ /**
4
+ * Returns the current device pixel ratio (DPR) given the passed options
5
+ *
6
+ * @param options
7
+ * @returns current device pixel ratio
8
+ */
9
+ function getDevicePixelRatio(): number {
10
+ const hasDprProp = typeof window !== 'undefined' && typeof window.devicePixelRatio === 'number'
11
+ const dpr = hasDprProp ? window.devicePixelRatio : 1
12
+ return clamp(Math.floor(dpr), {
13
+ min: 1,
14
+ max: 4,
15
+ })
16
+ }
17
+
18
+ let knownDpr: number | undefined
19
+
20
+ export function roundDpr(v: number) {
21
+ knownDpr ??= getDevicePixelRatio()
22
+ if (knownDpr < 2) {
23
+ return Math.round(v)
24
+ }
25
+ // https://floating-ui.com/docs/misc#subpixel-and-accelerated-positioning
26
+ return Math.round(v * knownDpr) / knownDpr
27
+ }
@@ -5,13 +5,6 @@ import { getNodeDimensions } from '@xyflow/system'
5
5
  import { Bezier } from 'bezier-js'
6
6
  import { isArray } from 'remeda'
7
7
 
8
- export function toDomPrecision(v: number | null) {
9
- if (v === null) {
10
- return 0.01
11
- }
12
- return Math.round(v * 100) / 100
13
- }
14
-
15
8
  export function distance(a: XYPosition, b: XYPosition) {
16
9
  return Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2))
17
10
  }
@@ -1,35 +0,0 @@
1
- import { SlotRecipeRuntimeFn } from '@likec4/styles/types';
2
- export declare const borderWidth: {
3
- readonly var: "--_border-width";
4
- readonly ref: "var(--_border-width, 2px)";
5
- };
6
- export declare const borderRadius: {
7
- readonly var: "--_border-radius";
8
- readonly ref: "var(--_border-radius, 4px)";
9
- };
10
- export declare const compoundOpacity: {
11
- readonly var: "--_compound-opacity";
12
- readonly ref: "var(--_compound-opacity, 1)";
13
- };
14
- export declare const borderOpacityPercent: {
15
- readonly var: "--_border-opacity-percent";
16
- readonly ref: "var(--_border-opacity-percent, 100%)";
17
- };
18
- export declare const compound: SlotRecipeRuntimeFn<"root" | "compoundBorder" | "indicatorSvg" | "indicatorRect", {
19
- isTransparent: {
20
- false: {
21
- root: {
22
- _before: {
23
- boxShadow: {
24
- _noReduceGraphics: "0 4px 10px 0.5px rgba(0,0,0,0.1) , 0 2px 2px -1px rgba(0,0,0,0.4)";
25
- _whenSelected: "none";
26
- _whenPanning: "none !important";
27
- };
28
- };
29
- };
30
- };
31
- true: {
32
- root: {};
33
- };
34
- };
35
- }>;
@@ -1,132 +0,0 @@
1
- import { sva, css } from '@likec4/styles/css';
2
-
3
- const borderWidth = {
4
- var: "--_border-width",
5
- ref: "var(--_border-width, 2px)"
6
- };
7
- const borderRadius = {
8
- var: "--_border-radius",
9
- ref: "var(--_border-radius, 4px)"
10
- };
11
- const compoundOpacity = {
12
- var: "--_compound-opacity",
13
- ref: "var(--_compound-opacity, 1)"
14
- };
15
- const borderOpacityPercent = {
16
- var: "--_border-opacity-percent",
17
- ref: "var(--_border-opacity-percent, 100%)"
18
- };
19
- const root = css.raw({
20
- position: "relative",
21
- width: "100%",
22
- height: "100%",
23
- padding: "0",
24
- margin: "0",
25
- border: "transparent",
26
- pointerEvents: "none",
27
- _before: {
28
- borderRadius: borderRadius.ref,
29
- content: '" "',
30
- position: "absolute",
31
- top: "0",
32
- left: "0",
33
- width: "100%",
34
- height: "100%",
35
- border: "transparent",
36
- background: "var(--likec4-palette-fill)",
37
- backgroundClip: "padding-box",
38
- transitionDelay: ".075ms"
39
- },
40
- _noReduceGraphics: {
41
- _before: {
42
- transition: `all {durations.slow} {easings.inOut}`
43
- },
44
- "&[data-likec4-hovered='true']": {
45
- _before: {
46
- transitionDelay: ".2s",
47
- transitionTimingFunction: "in"
48
- }
49
- }
50
- },
51
- "&:is([data-compound-transparent])": {
52
- _before: {
53
- opacity: compoundOpacity.ref,
54
- borderWidth: `calc(${borderWidth.ref} - 1px)`
55
- }
56
- }
57
- });
58
- const compoundBorder = css.raw({
59
- borderRadius: borderRadius.ref,
60
- padding: "0",
61
- margin: "0",
62
- transition: `all 250ms {easings.inOut}`,
63
- cursor: "default",
64
- position: "absolute",
65
- top: "0",
66
- left: "0",
67
- width: "100%",
68
- height: "100%",
69
- pointerEvents: "none",
70
- background: "transparent",
71
- borderStyle: "dashed",
72
- borderWidth: `[${borderWidth.ref}]`,
73
- borderColor: `[color-mix(in srgb, var(--likec4-palette-stroke) ${borderOpacityPercent.ref}, transparent)]`
74
- });
75
- const indicatorSvg = css.raw({
76
- position: "absolute",
77
- top: "0",
78
- left: "0",
79
- width: "100%",
80
- height: "100%",
81
- pointerEvents: "none",
82
- overflow: "visible",
83
- visibility: "hidden",
84
- _whenFocused: {
85
- visibility: "visible"
86
- },
87
- _whenSelected: {
88
- visibility: "visible"
89
- },
90
- _whenPanning: {
91
- display: "none"
92
- }
93
- });
94
- const indicatorRect = css.raw({
95
- stroke: `[color-mix(in srgb, var(--likec4-palette-stroke) 60%, var(--likec4-palette-hiContrast))]`,
96
- strokeWidth: "4",
97
- fill: "[none]",
98
- animationStyle: "indicator",
99
- _light: {
100
- stroke: `[color-mix(in srgb, var(--likec4-palette-stroke) 80%, var(--likec4-palette-hiContrast))]`
101
- }
102
- });
103
- const compound = sva({
104
- slots: ["root", "compoundBorder", "indicatorSvg", "indicatorRect"],
105
- className: "compound-container",
106
- base: {
107
- root,
108
- compoundBorder,
109
- indicatorSvg,
110
- indicatorRect
111
- },
112
- variants: {
113
- isTransparent: {
114
- false: {
115
- root: {
116
- _before: {
117
- boxShadow: {
118
- _noReduceGraphics: "0 4px 10px 0.5px rgba(0,0,0,0.1) , 0 2px 2px -1px rgba(0,0,0,0.4)",
119
- _whenSelected: "none",
120
- _whenPanning: "none !important"
121
- }
122
- }
123
- }
124
- },
125
- true: {
126
- root: {}
127
- }
128
- }
129
- }
130
- });
131
-
132
- export { borderOpacityPercent, borderRadius, borderWidth, compound, compoundOpacity };
@@ -1,7 +0,0 @@
1
- export declare const edgeNoteCloseButton: string;
2
- export declare const edgeNoteText: string;
3
- export declare const translate: {
4
- readonly var: "--edge-translate";
5
- readonly ref: "var(--edge-translate)";
6
- };
7
- export declare const edgeLabelContainer: string;
@@ -1,57 +0,0 @@
1
- import { css } from '@likec4/styles/css';
2
-
3
- const labelBorderRadius = "4px";
4
- css({
5
- position: "absolute",
6
- top: "1",
7
- right: "1"
8
- });
9
- css({
10
- userSelect: "all",
11
- textAlign: "left",
12
- whiteSpaceCollapse: "preserve-breaks",
13
- textWrap: "pretty",
14
- lineHeight: "1.25",
15
- "--text-fz": "{fontSizes.sm}",
16
- md: {
17
- "--text-fz": "{fontSizes.md}"
18
- }
19
- });
20
- const translate = {
21
- var: "--edge-translate",
22
- ref: `var(--edge-translate)`
23
- };
24
- const edgeLabelContainer = css({
25
- top: "0",
26
- left: "0",
27
- position: "absolute",
28
- pointerEvents: "all",
29
- cursor: "pointer",
30
- width: "auto",
31
- height: "auto",
32
- background: "[var(--xy-edge-label-background-color)]",
33
- color: "[var(--xy-edge-label-color)]",
34
- border: "0px solid transparent",
35
- borderRadius: labelBorderRadius,
36
- transform: `${translate.ref}`,
37
- transition: "fast",
38
- "&:is([data-likec4-hovered='true'])": {
39
- transition: `all 190ms {easings.inOut}`,
40
- transform: `var(--edge-translate, translate(0px, 0px)) scale(1.12)`,
41
- transitionDelay: "100ms"
42
- },
43
- _noReduceGraphics: {
44
- mixBlendMode: {
45
- _dark: "plus-lighter",
46
- _light: "screen"
47
- }
48
- },
49
- _smallZoom: {
50
- display: "none"
51
- },
52
- _reduceGraphicsOnPan: {
53
- display: "none"
54
- }
55
- });
56
-
57
- export { edgeLabelContainer, translate };
@@ -1,6 +0,0 @@
1
- export declare const indicator: string;
2
- export declare const fillElementFill: string;
3
- export declare const fillElementStroke: string;
4
- export declare const fillMixStroke: string;
5
- export declare const shapeSvgMultiple: string;
6
- export declare const shapeSvg: string;
@@ -1,107 +0,0 @@
1
- import { cx, css } from '@likec4/styles/css';
2
-
3
- const indicator = css({
4
- _smallZoom: {
5
- visibility: "hidden"
6
- },
7
- stroke: "var(--likec4-palette-loContrast)",
8
- fill: "[none]",
9
- strokeWidth: 8,
10
- strokeOpacity: 0.8,
11
- visibility: "hidden",
12
- pointerEvents: "none",
13
- _light: {
14
- stroke: `[color-mix(in srgb, var(--likec4-palette-fill) 50%,rgb(121, 121, 121))]`
15
- },
16
- _whenFocused: {
17
- visibility: "visible"
18
- },
19
- _groupFocusVisible: {
20
- visibility: "visible"
21
- },
22
- _whenSelected: {
23
- animationStyle: "indicator",
24
- visibility: "visible"
25
- }
26
- });
27
- const fillElementFill = css({
28
- fill: "var(--likec4-palette-fill)"
29
- });
30
- css({
31
- fill: "var(--likec4-palette-stroke)"
32
- });
33
- const fillMixStroke = css({
34
- fill: "[color-mix(in srgb, var(--likec4-palette-stroke) 90%, var(--likec4-palette-fill))]",
35
- ".shape-svg-multiple &": {
36
- fill: "var(--likec4-palette-fill)"
37
- }
38
- });
39
- const shapeBase = css.raw({
40
- top: "0",
41
- left: "0",
42
- position: "absolute",
43
- width: "100%",
44
- height: "100%",
45
- pointerEvents: "none",
46
- fill: "var(--likec4-palette-fill)",
47
- stroke: "var(--likec4-palette-stroke)",
48
- overflow: "visible"
49
- // zIndex is removed to improve rendering performance
50
- // this forces to keep shape in the same layer as the node
51
- // zIndex: -1,
52
- });
53
- const shapeSvgMultiple = cx(
54
- "shape-svg-multiple",
55
- css(shapeBase, {
56
- transformOrigin: {
57
- base: "50% 50%",
58
- _shapeQueue: "75% 25%",
59
- _shapeCylinder: "50% 100%",
60
- _shapeStorage: "50% 100%"
61
- },
62
- transform: "translate(14px, 14px) perspective(300px) translateZ(-8px)",
63
- filter: "brightness(0.65) saturate(0.8)",
64
- stroke: "[none]",
65
- display: {
66
- _smallZoom: "none",
67
- _reduceGraphicsOnPan: "none",
68
- _whenSelected: "none",
69
- _whenFocused: "none"
70
- }
71
- })
72
- );
73
- const shapeSvg = css(shapeBase, {
74
- transition: `fill 120ms linear, filter 130ms {easings.inOut}`,
75
- transitionDelay: "0ms",
76
- filter: `
77
- drop-shadow(0 2px 1px rgba(0, 0, 0, 0.21))
78
- drop-shadow(0 1px 1px color-mix(in srgb, var(--likec4-palette-stroke) 40%, transparent))
79
- drop-shadow(0 5px 3px rgba(0, 0, 0, 0.1))
80
- `,
81
- _whenHovered: {
82
- filter: `
83
- drop-shadow(0 2px 1px rgba(0, 0, 0, 0.25))
84
- drop-shadow(0 8px 3px rgba(0, 0, 0, 0.1))
85
- drop-shadow(0 10px 10px rgba(0, 0, 0, 0.05))
86
- `
87
- },
88
- [`:where([data-likec4-level='true']) &`]: {
89
- filter: `
90
- drop-shadow(0 2px 1px rgba(0, 0, 0, 0.25))
91
- drop-shadow(0 8px 3px rgba(0, 0, 0, 0.1))
92
- drop-shadow(0 10px 10px rgba(0, 0, 0, 0.05))
93
- `
94
- },
95
- _whenSelected: {
96
- filter: "none"
97
- },
98
- _smallZoom: {
99
- filter: "none"
100
- },
101
- _whenPanning: {
102
- transition: "none",
103
- filter: "none"
104
- }
105
- });
106
-
107
- export { fillElementFill, fillMixStroke, indicator, shapeSvg, shapeSvgMultiple };