@likec4/diagram 1.4.0 → 1.6.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 (87) hide show
  1. package/LICENSE +1 -1
  2. package/dist/LikeC4Diagram.css.d.ts +0 -1
  3. package/dist/LikeC4Diagram.d.ts +1 -1
  4. package/dist/LikeC4Diagram.props.d.ts +19 -4
  5. package/dist/StaticLikeC4Diagram.d.ts +1 -1
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.mjs +3937 -3646
  8. package/dist/state/DiagramContext.d.ts +95 -4159
  9. package/dist/state/diagramStore.d.ts +100 -4164
  10. package/dist/state/hooks.d.ts +4 -0
  11. package/dist/state/index.d.ts +1 -2
  12. package/dist/style.css +281 -191
  13. package/dist/ui/options/EdgeOptions.d.ts +19 -0
  14. package/dist/ui/options/NodeOptions.d.ts +2 -2
  15. package/dist/xyflow/EdgeMarkers.d.ts +11 -0
  16. package/dist/xyflow/XYFlowEvents.d.ts +8 -5
  17. package/dist/xyflow/const.d.ts +3 -3
  18. package/dist/xyflow/diagram-to-xyflow.d.ts +1 -1
  19. package/dist/xyflow/edges/RelationshipEdge.d.ts +3 -2
  20. package/dist/xyflow/edges/edges.css.d.ts +1 -0
  21. package/dist/xyflow/edges/utils.d.ts +1 -0
  22. package/dist/xyflow/hooks/index.d.ts +3 -2
  23. package/dist/xyflow/hooks/useXYFlow.d.ts +13 -12
  24. package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +1 -0
  25. package/dist/xyflow/nodes/element/ElementShapeSvg.d.ts +5 -0
  26. package/dist/xyflow/nodes/element/element.css.d.ts +5 -2
  27. package/dist/xyflow/types.d.ts +2 -32
  28. package/package.json +19 -19
  29. package/src/LikeC4Diagram.css.ts +0 -8
  30. package/src/LikeC4Diagram.props.ts +23 -5
  31. package/src/LikeC4Diagram.tsx +18 -21
  32. package/src/StaticLikeC4Diagram.tsx +1 -0
  33. package/src/globals.css.ts +10 -3
  34. package/src/index.ts +1 -1
  35. package/src/mantine.css.ts +2 -2
  36. package/src/state/DiagramContext.tsx +44 -13
  37. package/src/state/diagramStore.ts +72 -53
  38. package/src/state/hooks.ts +5 -0
  39. package/src/state/index.ts +1 -2
  40. package/src/ui/BackwardForwardPanel.css.ts +9 -9
  41. package/src/ui/DiagramTitlePanel.css.ts +7 -2
  42. package/src/ui/DiagramTitlePanel.tsx +5 -3
  43. package/src/ui/DynamicViewWalkthrough.tsx +6 -4
  44. package/src/ui/OptionsPanel.tsx +37 -27
  45. package/src/ui/options/EdgeOptions.tsx +157 -0
  46. package/src/ui/options/NodeOptions.tsx +37 -29
  47. package/src/xyflow/EdgeMarkers.tsx +148 -0
  48. package/src/xyflow/FitviewOnDiagramChange.tsx +9 -5
  49. package/src/xyflow/SelectEdgesOnNodeFocus.tsx +59 -55
  50. package/src/xyflow/SyncWithDiagram.tsx +13 -20
  51. package/src/xyflow/XYFlow.tsx +3 -4
  52. package/src/xyflow/XYFlowEvents.tsx +48 -33
  53. package/src/xyflow/const.ts +3 -3
  54. package/src/xyflow/diagram-to-xyflow.ts +17 -41
  55. package/src/xyflow/edges/RelationshipEdge.tsx +208 -119
  56. package/src/xyflow/edges/edges.css.ts +40 -26
  57. package/src/xyflow/edges/utils.ts +10 -0
  58. package/src/xyflow/hooks/index.ts +4 -2
  59. package/src/xyflow/hooks/useLayoutConstraints.ts +3 -4
  60. package/src/xyflow/hooks/useXYFlow.ts +28 -1
  61. package/src/xyflow/nodes/compound/CompoundNode.css.ts +34 -24
  62. package/src/xyflow/nodes/compound/CompoundNode.tsx +52 -53
  63. package/src/xyflow/nodes/element/ElementLink.tsx +12 -16
  64. package/src/xyflow/nodes/element/ElementNode.tsx +118 -114
  65. package/src/xyflow/nodes/element/ElementShapeSvg.tsx +2 -2
  66. package/src/xyflow/nodes/element/element.css.ts +147 -55
  67. package/src/xyflow/nodes/shared/NavigateToBtn.tsx +1 -1
  68. package/src/xyflow/types.ts +2 -4
  69. package/src/xyflow/utils.ts +3 -6
  70. package/dist/KeepAspectRatioContainer.d.ts +0 -9
  71. package/dist/icons/Clipboard.d.ts +0 -3
  72. package/dist/icons/Link.d.ts +0 -3
  73. package/dist/icons/ZoomIn.d.ts +0 -3
  74. package/dist/icons/index.d.ts +0 -3
  75. package/dist/mantine/theme.d.ts +0 -3
  76. package/dist/state/WhenInitialized.d.ts +0 -3
  77. package/dist/ui/Camera.d.ts +0 -3
  78. package/dist/xyflow/nodes/element/ElementIcon.d.ts +0 -10
  79. package/src/KeepAspectRatioContainer.tsx +0 -36
  80. package/src/icons/Clipboard.tsx +0 -24
  81. package/src/icons/Link.tsx +0 -23
  82. package/src/icons/ZoomIn.tsx +0 -25
  83. package/src/icons/index.ts +0 -3
  84. package/src/mantine/theme.ts +0 -20
  85. package/src/state/WhenInitialized.tsx +0 -24
  86. package/src/ui/Camera.tsx +0 -174
  87. package/src/xyflow/nodes/element/ElementIcon.tsx +0 -44
@@ -0,0 +1,19 @@
1
+ export declare const themedColors: ({
2
+ key: "primary";
3
+ value: "#3b82f6";
4
+ } | {
5
+ key: "secondary";
6
+ value: "#0284c7";
7
+ } | {
8
+ key: "muted";
9
+ value: "#64748b";
10
+ })[];
11
+ export declare const colors: {
12
+ key: "amber" | "blue" | "gray" | "slate" | "green" | "indigo" | "red" | "sky";
13
+ value: "#3b82f6" | "#0284c7" | "#64748b" | "#737373" | "#AC4D39" | "#428a4f" | "#A35829" | "#6366f1";
14
+ }[];
15
+ export type ThemeColorKey = typeof themedColors[0]['key'];
16
+ export type ColorKey = typeof colors[0]['key'];
17
+ export declare const EdgeOptions: import('react').NamedExoticComponent<{
18
+ selectedEdgeIds: string[];
19
+ }>;
@@ -14,6 +14,6 @@ export declare const colors: {
14
14
  }[];
15
15
  export type ThemeColorKey = typeof themedColors[0]['key'];
16
16
  export type ColorKey = typeof colors[0]['key'];
17
- export declare function NodeOptions({ selectedNodeIds }: {
17
+ export declare const NodeOptions: import('react').NamedExoticComponent<{
18
18
  selectedNodeIds: string[];
19
- }): import("react/jsx-runtime").JSX.Element | null;
19
+ }>;
@@ -0,0 +1,11 @@
1
+ import { SVGProps } from 'react';
2
+
3
+ export declare const EdgeMarkers: {
4
+ Arrow: (props: SVGProps<SVGMarkerElement>) => import("react/jsx-runtime").JSX.Element;
5
+ OArrow: (props: SVGProps<SVGMarkerElement>) => import("react/jsx-runtime").JSX.Element;
6
+ Open: (props: SVGProps<SVGMarkerElement>) => import("react/jsx-runtime").JSX.Element;
7
+ Diamond: (props: SVGProps<SVGMarkerElement>) => import("react/jsx-runtime").JSX.Element;
8
+ ODiamond: (props: SVGProps<SVGMarkerElement>) => import("react/jsx-runtime").JSX.Element;
9
+ Dot: (props: SVGProps<SVGMarkerElement>) => import("react/jsx-runtime").JSX.Element;
10
+ ODot: (props: SVGProps<SVGMarkerElement>) => import("react/jsx-runtime").JSX.Element;
11
+ };
@@ -1,5 +1,8 @@
1
- import { XYFlowNode } from './types';
1
+ import { ReactFlowProps } from '@xyflow/react';
2
+ import { Simplify } from 'type-fest';
3
+ import { XYFlowEdge, XYFlowNode } from './types';
2
4
 
5
+ export type XYFlowEventHandlers = Simplify<Required<Pick<ReactFlowProps<XYFlowNode, XYFlowEdge>, 'onDoubleClick' | 'onPaneClick' | 'onNodeClick' | 'onNodeDoubleClick' | 'onEdgeClick' | 'onMoveEnd' | 'onNodeContextMenu' | 'onEdgeContextMenu' | 'onPaneContextMenu' | 'onNodeMouseEnter' | 'onNodeMouseLeave' | 'onEdgeMouseEnter' | 'onEdgeMouseLeave'>>>;
3
6
  export declare function useXYFlowEvents(): {
4
7
  onDoubleClick: (event: import('react').MouseEvent<HTMLDivElement, MouseEvent>) => void;
5
8
  onPaneClick: (event: import('react').MouseEvent<Element, MouseEvent>) => void;
@@ -20,7 +23,7 @@ export declare function useXYFlowEvents(): {
20
23
  zIndex?: number;
21
24
  ariaLabel?: string;
22
25
  interactionWidth?: number;
23
- label?: import('react').ReactNode;
26
+ label?: string | import('react').ReactNode;
24
27
  labelStyle?: import('react').CSSProperties;
25
28
  labelShowBg?: boolean;
26
29
  labelBgStyle?: import('react').CSSProperties;
@@ -51,7 +54,7 @@ export declare function useXYFlowEvents(): {
51
54
  zIndex?: number;
52
55
  ariaLabel?: string;
53
56
  interactionWidth?: number;
54
- label?: import('react').ReactNode;
57
+ label?: string | import('react').ReactNode;
55
58
  labelStyle?: import('react').CSSProperties;
56
59
  labelShowBg?: boolean;
57
60
  labelBgStyle?: import('react').CSSProperties;
@@ -83,7 +86,7 @@ export declare function useXYFlowEvents(): {
83
86
  zIndex?: number;
84
87
  ariaLabel?: string;
85
88
  interactionWidth?: number;
86
- label?: import('react').ReactNode;
89
+ label?: string | import('react').ReactNode;
87
90
  labelStyle?: import('react').CSSProperties;
88
91
  labelShowBg?: boolean;
89
92
  labelBgStyle?: import('react').CSSProperties;
@@ -112,7 +115,7 @@ export declare function useXYFlowEvents(): {
112
115
  zIndex?: number;
113
116
  ariaLabel?: string;
114
117
  interactionWidth?: number;
115
- label?: import('react').ReactNode;
118
+ label?: string | import('react').ReactNode;
116
119
  labelStyle?: import('react').CSSProperties;
117
120
  labelShowBg?: boolean;
118
121
  labelBgStyle?: import('react').CSSProperties;
@@ -1,6 +1,6 @@
1
1
  export declare const ZIndexes: {
2
- readonly Compound: 1;
3
- readonly Edge: 2;
4
- readonly Element: 3;
2
+ readonly Compound: 2;
3
+ readonly Edge: 4;
4
+ readonly Element: 6;
5
5
  };
6
6
  export declare const MinZoom = 0.1;
@@ -1,4 +1,4 @@
1
- import { DiagramView } from '@likec4/core';
1
+ import { DiagramView } from '@likec4/core/types';
2
2
  import { XYFlowData } from '../xyflow/types';
3
3
 
4
4
  export declare function diagramViewToXYFlowData(view: Pick<DiagramView, 'id' | 'nodes' | 'edges' | '__' | 'manualLayout'>, opts: {
@@ -1,4 +1,5 @@
1
1
  import { EdgeProps } from '@xyflow/react';
2
+ import { RelationshipData } from '../types';
2
3
 
3
4
  export declare const RelationshipEdge: import('react').NamedExoticComponent<EdgeProps<{
4
5
  source: string;
@@ -15,7 +16,7 @@ export declare const RelationshipEdge: import('react').NamedExoticComponent<Edge
15
16
  zIndex?: number;
16
17
  ariaLabel?: string;
17
18
  interactionWidth?: number;
18
- label?: import('react').ReactNode;
19
+ label?: string | import('react').ReactNode;
19
20
  labelStyle?: import('react').CSSProperties;
20
21
  labelShowBg?: boolean;
21
22
  labelBgStyle?: import('react').CSSProperties;
@@ -25,7 +26,7 @@ export declare const RelationshipEdge: import('react').NamedExoticComponent<Edge
25
26
  className?: string;
26
27
  reconnectable?: boolean | import('@xyflow/react').HandleType;
27
28
  focusable?: boolean;
28
- data: import('../types').RelationshipData;
29
+ data: RelationshipData;
29
30
  readonly id: string;
30
31
  readonly type: "relationship";
31
32
  }>>;
@@ -3,6 +3,7 @@ export declare const dimmed: string;
3
3
  export declare const edgePathBg: string;
4
4
  export declare const markerContext: string;
5
5
  export declare const controlPoint: string;
6
+ export declare const controlDragging: string;
6
7
  export declare const cssEdgePath: string;
7
8
  export declare const varLabelX: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
8
9
  export declare const varLabelY: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
@@ -1,6 +1,7 @@
1
1
  import { Position, XYPosition } from '@xyflow/react';
2
2
  import { InternalXYFlowNode } from '../types';
3
3
 
4
+ export declare function getNodeCenter(node: InternalXYFlowNode): XYPosition;
4
5
  export declare function getNodeIntersectionFromCenterToPoint(intersectionNode: InternalXYFlowNode, { x: x1, y: y1 }: XYPosition): {
5
6
  x: number;
6
7
  y: number;
@@ -1,2 +1,3 @@
1
- export * from './useLayoutConstraints';
2
- export * from './useXYFlow';
1
+ export { useLayoutConstraints } from './useLayoutConstraints';
2
+ export { useXYFlow, useXYNodesData, useXYStore, useXYStoreApi } from './useXYFlow';
3
+ export type * from './useXYFlow';
@@ -1,4 +1,4 @@
1
- import { XYFlowNode, XYFlowState } from '../types';
1
+ import { XYFlowEdge, XYFlowNode, XYFlowState } from '../types';
2
2
 
3
3
  export declare const useXYFlow: () => import('@xyflow/react').ReactFlowInstance<XYFlowNode, {
4
4
  source: string;
@@ -15,7 +15,7 @@ export declare const useXYFlow: () => import('@xyflow/react').ReactFlowInstance<
15
15
  zIndex?: number;
16
16
  ariaLabel?: string;
17
17
  interactionWidth?: number;
18
- label?: import('react').ReactNode;
18
+ label?: string | import('react').ReactNode;
19
19
  labelStyle?: import('react').CSSProperties;
20
20
  labelShowBg?: boolean;
21
21
  labelBgStyle?: import('react').CSSProperties;
@@ -30,8 +30,8 @@ export declare const useXYFlow: () => import('@xyflow/react').ReactFlowInstance<
30
30
  readonly type: "relationship";
31
31
  }>;
32
32
  export declare const useXYNodesData: {
33
- (nodeId: string): Pick<XYFlowNode, "id" | "data" | "type"> | null;
34
- (nodeIds: string[]): Pick<XYFlowNode, "id" | "data" | "type">[];
33
+ (nodeId: string): Pick<XYFlowNode, "id" | "type" | "data"> | null;
34
+ (nodeIds: string[]): Pick<XYFlowNode, "id" | "type" | "data">[];
35
35
  };
36
36
  export declare function useXYStore<StateSlice = unknown>(selector: (state: XYFlowState) => StateSlice, equalityFn?: (a: StateSlice, b: StateSlice) => boolean): StateSlice;
37
37
  export declare const useXYStoreApi: () => {
@@ -50,7 +50,7 @@ export declare const useXYStoreApi: () => {
50
50
  zIndex?: number;
51
51
  ariaLabel?: string;
52
52
  interactionWidth?: number;
53
- label?: import('react').ReactNode;
53
+ label?: string | import('react').ReactNode;
54
54
  labelStyle?: import('react').CSSProperties;
55
55
  labelShowBg?: boolean;
56
56
  labelBgStyle?: import('react').CSSProperties;
@@ -79,7 +79,7 @@ export declare const useXYStoreApi: () => {
79
79
  zIndex?: number;
80
80
  ariaLabel?: string;
81
81
  interactionWidth?: number;
82
- label?: import('react').ReactNode;
82
+ label?: string | import('react').ReactNode;
83
83
  labelStyle?: import('react').CSSProperties;
84
84
  labelShowBg?: boolean;
85
85
  labelBgStyle?: import('react').CSSProperties;
@@ -107,7 +107,7 @@ export declare const useXYStoreApi: () => {
107
107
  zIndex?: number;
108
108
  ariaLabel?: string;
109
109
  interactionWidth?: number;
110
- label?: import('react').ReactNode;
110
+ label?: string | import('react').ReactNode;
111
111
  labelStyle?: import('react').CSSProperties;
112
112
  labelShowBg?: boolean;
113
113
  labelBgStyle?: import('react').CSSProperties;
@@ -135,7 +135,7 @@ export declare const useXYStoreApi: () => {
135
135
  zIndex?: number;
136
136
  ariaLabel?: string;
137
137
  interactionWidth?: number;
138
- label?: import('react').ReactNode;
138
+ label?: string | import('react').ReactNode;
139
139
  labelStyle?: import('react').CSSProperties;
140
140
  labelShowBg?: boolean;
141
141
  labelBgStyle?: import('react').CSSProperties;
@@ -163,7 +163,7 @@ export declare const useXYStoreApi: () => {
163
163
  zIndex?: number;
164
164
  ariaLabel?: string;
165
165
  interactionWidth?: number;
166
- label?: import('react').ReactNode;
166
+ label?: string | import('react').ReactNode;
167
167
  labelStyle?: import('react').CSSProperties;
168
168
  labelShowBg?: boolean;
169
169
  labelBgStyle?: import('react').CSSProperties;
@@ -191,7 +191,7 @@ export declare const useXYStoreApi: () => {
191
191
  zIndex?: number;
192
192
  ariaLabel?: string;
193
193
  interactionWidth?: number;
194
- label?: import('react').ReactNode;
194
+ label?: string | import('react').ReactNode;
195
195
  labelStyle?: import('react').CSSProperties;
196
196
  labelShowBg?: boolean;
197
197
  labelBgStyle?: import('react').CSSProperties;
@@ -220,7 +220,7 @@ export declare const useXYStoreApi: () => {
220
220
  zIndex?: number;
221
221
  ariaLabel?: string;
222
222
  interactionWidth?: number;
223
- label?: import('react').ReactNode;
223
+ label?: string | import('react').ReactNode;
224
224
  labelStyle?: import('react').CSSProperties;
225
225
  labelShowBg?: boolean;
226
226
  labelBgStyle?: import('react').CSSProperties;
@@ -248,7 +248,7 @@ export declare const useXYStoreApi: () => {
248
248
  zIndex?: number;
249
249
  ariaLabel?: string;
250
250
  interactionWidth?: number;
251
- label?: import('react').ReactNode;
251
+ label?: string | import('react').ReactNode;
252
252
  labelStyle?: import('react').CSSProperties;
253
253
  labelShowBg?: boolean;
254
254
  labelBgStyle?: import('react').CSSProperties;
@@ -264,3 +264,4 @@ export declare const useXYStoreApi: () => {
264
264
  }>) => void) => () => void;
265
265
  };
266
266
  export type XYStoreApi = ReturnType<typeof useXYStoreApi>;
267
+ export declare function useXYEdgesData(edgeIds: string[]): Pick<XYFlowEdge, 'id' | 'data'>[];
@@ -1,4 +1,5 @@
1
1
  export declare const container: string;
2
+ export declare const nodeHandlerInCenter: string;
2
3
  export declare const dimmed: string;
3
4
  export declare const varOpacity: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
4
5
  export declare const varBorderTransparency: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
@@ -1,5 +1,10 @@
1
1
  import { ElementShape } from '@likec4/core';
2
2
 
3
+ export declare function cylinderSVGPath(diameter: number, height: number, tilt?: number): {
4
+ path: string;
5
+ ry: number;
6
+ rx: number;
7
+ };
3
8
  type ElementShapeSvgProps = {
4
9
  shape: ElementShape;
5
10
  w: number;
@@ -1,16 +1,19 @@
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 handleCenter: string;
3
4
  export declare const containerAnimated: string;
4
5
  export declare const dimmed: string;
5
6
  export declare const indicator: string;
6
7
  export declare const fillElementFill: string;
7
8
  export declare const fillElementStroke: string;
8
9
  export declare const fillMixStroke: string;
10
+ export declare const hasIcon: string;
9
11
  export declare const title: string;
10
12
  export declare const description: string;
11
13
  export declare const technology: string;
12
- export declare const element: string;
13
- export declare const iconMaxH: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
14
+ export declare const elementDataContainer: string;
15
+ export declare const elementTextData: string;
14
16
  export declare const elementIcon: string;
17
+ export declare const cssShapeSvgMultiple: string;
15
18
  export declare const cssShapeSvg: string;
16
19
  export declare const cssNavigateBtn: string;
@@ -1,4 +1,4 @@
1
- import { BBox, DiagramEdge, DiagramNode, Fqn, Point, XYPosition } from '@likec4/core';
1
+ import { BBox, DiagramEdge, DiagramNode, Fqn, XYPosition } from '@likec4/core';
2
2
  import { Edge, EdgeMouseHandler, InternalNode, Node, NodeMouseHandler, OnMoveEnd, OnMoveStart, ReactFlowInstance, ReactFlowState } from '@xyflow/react';
3
3
  import { MouseEvent as ReactMouseEvent } from 'react';
4
4
  import { SetReadonly, SetRequired } from 'type-fest';
@@ -26,8 +26,6 @@ export declare namespace XYFlowNode {
26
26
  export type RelationshipData = {
27
27
  edge: DiagramEdge;
28
28
  controlPoints: XYPosition[] | null;
29
- headPoint: Point | null;
30
- tailPoint: Point | null;
31
29
  type: 'bezier' | 'poly';
32
30
  stepNum: number | null;
33
31
  label: null | {
@@ -39,35 +37,7 @@ export type RelationshipEdge = TypedXYFlowEdge<RelationshipData, 'relationship'>
39
37
  export type XYFlowEdge = RelationshipEdge;
40
38
  export declare namespace XYFlowEdge {
41
39
  type Data = RelationshipData;
42
- const isRelationship: (e: Edge) => e is {
43
- source: string;
44
- target: string;
45
- sourceHandle?: string | null;
46
- targetHandle?: string | null;
47
- animated?: boolean;
48
- hidden?: boolean;
49
- deletable?: boolean;
50
- selectable?: boolean;
51
- selected?: boolean;
52
- markerStart?: import("@xyflow/react").EdgeMarkerType;
53
- markerEnd?: import("@xyflow/react").EdgeMarkerType;
54
- zIndex?: number;
55
- ariaLabel?: string;
56
- interactionWidth?: number;
57
- label?: import("react").ReactNode;
58
- labelStyle?: import("react").CSSProperties;
59
- labelShowBg?: boolean;
60
- labelBgStyle?: import("react").CSSProperties;
61
- labelBgPadding?: [number, number];
62
- labelBgBorderRadius?: number;
63
- style?: import("react").CSSProperties;
64
- className?: string;
65
- reconnectable?: boolean | import("@xyflow/react").HandleType;
66
- focusable?: boolean;
67
- data: RelationshipData;
68
- readonly id: string;
69
- readonly type: "relationship";
70
- };
40
+ const isRelationship: (e: Edge) => e is RelationshipEdge;
71
41
  }
72
42
  export type XYFlowInstance = ReactFlowInstance<XYFlowNode, XYFlowEdge>;
73
43
  export type XYFlowState = ReactFlowState<XYFlowNode, XYFlowEdge>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@likec4/diagram",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "license": "MIT",
5
5
  "bugs": "https://github.com/likec4/likec4/issues",
6
6
  "homepage": "https://likec4.dev",
@@ -40,7 +40,7 @@
40
40
  "./style.css": "./dist/style.css"
41
41
  }
42
42
  },
43
- "packageManager": "yarn@4.3.0",
43
+ "packageManager": "yarn@4.3.1",
44
44
  "scripts": {
45
45
  "typecheck": "tsc --noEmit",
46
46
  "prepack": "vite build --mode production",
@@ -48,50 +48,50 @@
48
48
  "clean": "run -T rimraf -v -g 'dist/*' .tsbuildinfo"
49
49
  },
50
50
  "dependencies": {
51
- "@likec4/core": "1.4.0",
51
+ "@likec4/core": "1.6.0",
52
52
  "@react-hookz/web": "^24.0.4",
53
- "@tabler/icons-react": "^3.7.0",
53
+ "@tabler/icons-react": "^3.11.0",
54
54
  "@vanilla-extract/css": "^1.15.3",
55
55
  "@vanilla-extract/css-utils": "^0.1.4",
56
56
  "@vanilla-extract/dynamic": "^2.1.1",
57
57
  "d3-shape": "^3.2.0",
58
58
  "esm-env": "^1.0.0",
59
59
  "fast-equals": "^5.0.1",
60
- "framer-motion": "^11.2.12",
61
- "remeda": "^1.61.0",
60
+ "framer-motion": "^11.3.8",
61
+ "remeda": "^2.3.0",
62
62
  "zustand": "^4.5.4"
63
63
  },
64
64
  "peerDependencies": {
65
- "@mantine/core": "7.10.2",
66
- "@mantine/hooks": "7.10.2",
65
+ "@mantine/core": "^7.11.2",
66
+ "@mantine/hooks": "^7.11.2",
67
67
  "react": "^18.3.1",
68
68
  "react-dom": "^18.3.1"
69
69
  },
70
70
  "devDependencies": {
71
- "@likec4/tsconfig": "1.4.0",
71
+ "@likec4/tsconfig": "1.6.0",
72
72
  "@lume/kiwi": "^0.4.3",
73
- "@mantine/core": "7.10.2",
74
- "@mantine/hooks": "7.10.2",
75
- "@mantine/vanilla-extract": "7.10.2",
73
+ "@mantine/core": "7.11.2",
74
+ "@mantine/hooks": "7.11.2",
75
+ "@mantine/vanilla-extract": "7.11.2",
76
76
  "@total-typescript/ts-reset": "^0.5.1",
77
77
  "@types/bezier-js": "^4.1.3",
78
- "@types/d3-shape": "^3",
78
+ "@types/d3-shape": "^3.1.6",
79
79
  "@types/react": "^18.3.3",
80
80
  "@types/react-dom": "^18.3.0",
81
81
  "@vanilla-extract/esbuild-plugin": "^2.3.8",
82
82
  "@vitejs/plugin-react": "^4.3.1",
83
- "@xyflow/react": "12.0.0-next.24",
84
- "@xyflow/system": "0.0.30",
83
+ "@xyflow/react": "12.0.3",
84
+ "@xyflow/system": "0.0.37",
85
85
  "bezier-js": "^6.1.4",
86
86
  "clsx": "^2.1.1",
87
- "execa": "^9.1.0",
87
+ "execa": "^9.3.0",
88
88
  "khroma": "^2.1.0",
89
89
  "react": "^18.3.1",
90
90
  "react-dom": "^18.3.1",
91
91
  "tilg": "^0.1.1",
92
- "type-fest": "^4.18.2",
93
- "typescript": "^5.4.5",
94
- "vite": "5.3.2",
92
+ "type-fest": "^4.21.0",
93
+ "typescript": "^5.5.3",
94
+ "vite": "5.3.4",
95
95
  "vite-plugin-dts": "^3.9.1"
96
96
  }
97
97
  }
@@ -1,14 +1,6 @@
1
1
  import { globalStyle, style } from '@vanilla-extract/css'
2
2
  import { vars, xyvars } from './theme.css'
3
3
 
4
- export const keepAspectRatioContainer = style({
5
- overflow: 'hidden',
6
- position: 'relative',
7
- width: '100%',
8
- height: '100%',
9
- padding: 0
10
- })
11
-
12
4
  export const cssReactFlow = style({
13
5
  '@supports': {
14
6
  // https://wojtek.im/journal/targeting-safari-with-css-media-query
@@ -6,17 +6,29 @@ import type {
6
6
  EdgeId,
7
7
  ElementShape,
8
8
  Fqn,
9
+ IconUrl,
9
10
  NonEmptyArray,
10
11
  ThemeColor,
11
12
  ViewID
12
13
  } from '@likec4/core'
13
14
  import type { XYPosition } from '@xyflow/system'
14
- import type { MouseEvent as ReactMouseEvent } from 'react'
15
- import type { SetRequired, Simplify } from 'type-fest'
15
+ import type { MouseEvent as ReactMouseEvent, ReactNode } from 'react'
16
16
  import type { XYFlowEdge, XYFlowNode } from './xyflow/types'
17
- import type { XYBackground, XYBackgroundProps } from './xyflow/XYFlowBackground'
17
+ import type { XYBackground } from './xyflow/XYFlowBackground'
18
18
 
19
- export type DiagramNodeWithNavigate = Simplify<SetRequired<DiagramNode, 'navigateTo'>>
19
+ export type DiagramNodeWithNavigate = Omit<DiagramNode, 'navigateTo'> & {
20
+ navigateTo: ViewID
21
+ }
22
+
23
+ type ElementIconNodeProps = {
24
+ id: string
25
+ title: string
26
+ icon?: string | undefined
27
+ }
28
+
29
+ export type ElementIconRenderer = (props: {
30
+ node: ElementIconNodeProps
31
+ }) => ReactNode
20
32
 
21
33
  export type OnNavigateTo = {
22
34
  (
@@ -36,7 +48,7 @@ export type OnNodeClick = (
36
48
  ) => void
37
49
  export type OnEdgeClick = (
38
50
  event: {
39
- relation: DiagramEdge
51
+ edge: DiagramEdge
40
52
  xyedge: XYFlowEdge
41
53
  event: ReactMouseEvent
42
54
  }
@@ -177,6 +189,12 @@ export interface LikeC4DiagramProperties {
177
189
  * @default false
178
190
  */
179
191
  experimentalEdgeEditing?: boolean | undefined
192
+
193
+ /**
194
+ * Render custom icon for a node
195
+ * By default, if icon is http:// or https://, it will be rendered as an image
196
+ */
197
+ renderIcon?: ElementIconRenderer | undefined
180
198
  }
181
199
 
182
200
  export interface LikeC4DiagramEventHandlers {
@@ -7,7 +7,6 @@ import { domAnimation, LazyMotion } from 'framer-motion'
7
7
  import { memo, useEffect, useRef, useState } from 'react'
8
8
  import useTilg from 'tilg'
9
9
  import { rootClassName } from './globals.css'
10
- import { KeepAspectRatioContainer } from './KeepAspectRatioContainer'
11
10
  import { cssDisablePan, cssNoControls, cssReactFlow, cssTransparentBg } from './LikeC4Diagram.css'
12
11
  import { type LikeC4DiagramEventHandlers, type LikeC4DiagramProperties } from './LikeC4Diagram.props'
13
12
  import { EnsureMantine } from './mantine/EnsureMantine'
@@ -50,7 +49,8 @@ export function LikeC4Diagram({
50
49
  onEdgeContextMenu,
51
50
  onNavigateTo,
52
51
  onNodeClick,
53
- onNodeContextMenu
52
+ onNodeContextMenu,
53
+ renderIcon
54
54
  }: LikeC4DiagramProps) {
55
55
  DEV && useTilg()
56
56
  const initialRef = useRef<{
@@ -71,6 +71,7 @@ export function LikeC4Diagram({
71
71
  initialHeight: initialHeight ?? view.height
72
72
  }
73
73
  }
74
+
74
75
  return (
75
76
  <EnsureMantine>
76
77
  <XYFlowProvider
@@ -79,6 +80,8 @@ export function LikeC4Diagram({
79
80
  >
80
81
  <DiagramContextProvider
81
82
  view={view}
83
+ keepAspectRatio={keepAspectRatio}
84
+ className={clsx(rootClassName, className)}
82
85
  readonly={readonly}
83
86
  pannable={pannable}
84
87
  zoomable={zoomable}
@@ -88,6 +91,7 @@ export function LikeC4Diagram({
88
91
  nodesDraggable={nodesDraggable}
89
92
  nodesSelectable={nodesSelectable}
90
93
  experimentalEdgeEditing={experimentalEdgeEditing}
94
+ renderIcon={renderIcon ?? null}
91
95
  onCanvasClick={onCanvasClick}
92
96
  onCanvasContextMenu={onCanvasContextMenu}
93
97
  onEdgeClick={onEdgeClick}
@@ -99,25 +103,18 @@ export function LikeC4Diagram({
99
103
  onCanvasDblClick={onCanvasDblClick}
100
104
  >
101
105
  <LazyMotion features={domAnimation} strict>
102
- <KeepAspectRatioContainer
103
- className={clsx(rootClassName, className)}
104
- enabled={keepAspectRatio}
105
- width={view.width}
106
- height={view.height}
107
- >
108
- <LikeC4DiagramInnerMemo
109
- defaultNodes={initialRef.current.defaultNodes}
110
- defaultEdges={initialRef.current.defaultEdges}
111
- fitView={fitView}
112
- zoomable={zoomable}
113
- background={background}
114
- controls={controls}
115
- pannable={pannable}
116
- showDiagramTitle={showDiagramTitle}
117
- showNavigationButtons={showNavigationButtons}
118
- enableDynamicViewWalkthrough={enableDynamicViewWalkthrough}
119
- />
120
- </KeepAspectRatioContainer>
106
+ <LikeC4DiagramInnerMemo
107
+ defaultNodes={initialRef.current.defaultNodes}
108
+ defaultEdges={initialRef.current.defaultEdges}
109
+ fitView={fitView}
110
+ zoomable={zoomable}
111
+ background={background}
112
+ controls={controls}
113
+ pannable={pannable}
114
+ showDiagramTitle={showDiagramTitle}
115
+ showNavigationButtons={showNavigationButtons}
116
+ enableDynamicViewWalkthrough={enableDynamicViewWalkthrough}
117
+ />
121
118
  </LazyMotion>
122
119
  </DiagramContextProvider>
123
120
  </XYFlowProvider>
@@ -11,6 +11,7 @@ export type StaticLikeC4DiagramProps = Pick<
11
11
  | 'background'
12
12
  | 'initialWidth'
13
13
  | 'initialHeight'
14
+ | 'renderIcon'
14
15
  >
15
16
 
16
17
  export function StaticLikeC4Diagram({
@@ -8,6 +8,13 @@ import { vars } from './theme.css'
8
8
  export const rootClassName = 'likec4-diagram-root'
9
9
 
10
10
  globalStyle(`.${rootClassName}`, {
11
+ overflow: 'hidden',
12
+ position: 'relative',
13
+ width: '100%',
14
+ height: '100%',
15
+ padding: 0,
16
+ margin: 0,
17
+ boxSizing: 'border-box',
11
18
  WebkitFontSmoothing: mantine.webkitFontSmoothing,
12
19
  MozOsxFontSmoothing: mantine.mozFontSmoothing
13
20
  })
@@ -21,7 +28,7 @@ createGlobalTheme(`.${rootClassName}`, {
21
28
  background: {
22
29
  color: mantine.colors.body,
23
30
  pattern: {
24
- color: mantine.colors.dimmed
31
+ color: mantine.colors.dark[3]
25
32
  }
26
33
  }
27
34
  },
@@ -74,13 +81,13 @@ createGlobalTheme(`:where([data-mantine-color-scheme='light']) .${rootClassName}
74
81
  likec4: {
75
82
  background: {
76
83
  pattern: {
77
- color: mantine.colors.dark[3]
84
+ color: mantine.colors.gray[6]
78
85
  }
79
86
  }
80
87
  }
81
88
  })
82
89
 
83
- for (const color of keys.strict(defaultTheme.elements)) {
90
+ for (const color of keys(defaultTheme.elements)) {
84
91
  createGlobalTheme(`:where([data-likec4-color='${color}'])`, {
85
92
  element: {
86
93
  fill: vars.element.fill,
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { LikeC4Diagram } from './LikeC4Diagram'
2
2
  export { StaticLikeC4Diagram } from './StaticLikeC4Diagram'
3
3
 
4
- export * from './hooks'
4
+ export { useSetState, useUpdateEffect } from './hooks'
5
5
  export type * from './LikeC4Diagram'
6
6
  export type * from './LikeC4Diagram.props'
7
7
  export type * from './StaticLikeC4Diagram'
@@ -1,4 +1,4 @@
1
1
  import { themeToVars } from '@mantine/vanilla-extract'
2
- import { theme } from './mantine/theme'
3
2
 
4
- export const mantine = themeToVars(theme)
3
+ // we need only variables names
4
+ export const mantine = themeToVars({})