@likec4/diagram 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/KeepAspectRatioContainer.d.ts +9 -0
- package/dist/LikeC4Diagram.css.d.ts +1 -0
- package/dist/index.mjs +248 -683
- package/dist/state/DiagramContext.d.ts +36 -9
- package/dist/state/diagramStore.d.ts +42 -12
- package/dist/state/useDiagramStore.d.ts +36 -9
- package/dist/style.css +600 -53
- package/dist/ui/index.d.ts +0 -1
- package/dist/xyflow/{XYFlowWrapper.d.ts → XYFlow.d.ts} +2 -2
- package/dist/xyflow/XYFlowEvents.d.ts +127 -13
- package/dist/xyflow/edges/RelationshipEdge.d.ts +2 -2
- package/dist/xyflow/hooks/useXYFlow.d.ts +20 -20
- package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +7 -5
- package/dist/xyflow/types.d.ts +2 -2
- package/package.json +3 -3
- package/src/{ui/KeepAspectRatio.tsx → KeepAspectRatioContainer.tsx} +7 -6
- package/src/LikeC4Diagram.css.ts +6 -0
- package/src/LikeC4Diagram.tsx +6 -6
- package/src/globals.css.ts +42 -37
- package/src/state/diagramStore.ts +26 -7
- package/src/ui/index.ts +0 -1
- package/src/xyflow/FitviewOnDiagramChange.tsx +24 -18
- package/src/xyflow/SyncWithDiagram.tsx +23 -20
- package/src/xyflow/{XYFlowWrapper.tsx → XYFlow.tsx} +17 -24
- package/src/xyflow/XYFlowEvents.tsx +96 -43
- package/src/xyflow/diagram-to-xyflow.ts +4 -4
- package/src/xyflow/nodes/compound/CompoundNode.css.ts +85 -39
- package/src/xyflow/nodes/compound/CompoundNode.tsx +29 -31
- package/src/xyflow/nodes/element/ElementNode.tsx +2 -2
- package/src/xyflow/nodes/shared/NavigateToBtn.tsx +2 -1
- package/dist/ui/KeepAspectRatio.css.d.ts +0 -1
- package/dist/ui/KeepAspectRatio.d.ts +0 -9
- package/src/ui/KeepAspectRatio.css.ts +0 -7
package/dist/ui/index.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ import { LikeC4DiagramProperties } from '../LikeC4Diagram.props';
|
|
|
3
3
|
import { SetNonNullable, Simplify } from 'type-fest';
|
|
4
4
|
import { CSSProperties, PropsWithChildren } from 'react';
|
|
5
5
|
|
|
6
|
-
type OnlyExpectedProps = Required<Pick<LikeC4DiagramProperties, 'className' | 'controls' | '
|
|
6
|
+
type OnlyExpectedProps = Required<Pick<LikeC4DiagramProperties, 'className' | 'controls' | 'background'>>;
|
|
7
7
|
type XYFlowWrapperProps = Simplify<PropsWithChildren<SetNonNullable<OnlyExpectedProps> & {
|
|
8
8
|
defaultNodes: XYFlowNode[];
|
|
9
9
|
defaultEdges: XYFlowEdge[];
|
|
10
10
|
style?: CSSProperties | undefined;
|
|
11
11
|
}>>;
|
|
12
|
-
declare function XYFlowWrapper({ className, children, defaultNodes, defaultEdges,
|
|
12
|
+
declare function XYFlowWrapper({ className, children, defaultNodes, defaultEdges, controls, background, style }: XYFlowWrapperProps): JSX.Element;
|
|
13
13
|
export declare const XYFlow: typeof XYFlowWrapper;
|
|
14
14
|
export {};
|
|
@@ -1,15 +1,129 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { MouseEvent as ReactMouseEvent } from 'react';
|
|
3
|
-
import { EdgeMouseHandler, NodeMouseHandler, OnMoveEnd } from '@xyflow/react';
|
|
1
|
+
import { XYFlowNode } from './types';
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
export declare function useXYFlowEvents(): {
|
|
4
|
+
onDoubleClick: import('react').MouseEventHandler<HTMLDivElement> | undefined;
|
|
5
|
+
onNodeClick: import('@xyflow/react').NodeMouseHandler<XYFlowNode>;
|
|
6
|
+
onNodeContextMenu: import('@xyflow/react').NodeMouseHandler<XYFlowNode>;
|
|
7
|
+
onEdgeClick: (event: import('react').MouseEvent<Element, MouseEvent>, edge: {
|
|
8
|
+
source: string;
|
|
9
|
+
target: string;
|
|
10
|
+
style?: import('react').CSSProperties;
|
|
11
|
+
id: string;
|
|
12
|
+
zIndex?: number;
|
|
13
|
+
markerEnd?: import('@xyflow/react').EdgeMarkerType;
|
|
14
|
+
markerStart?: import('@xyflow/react').EdgeMarkerType;
|
|
15
|
+
hidden?: boolean;
|
|
16
|
+
className?: string;
|
|
17
|
+
label?: import('react').ReactNode;
|
|
18
|
+
selected?: boolean;
|
|
19
|
+
selectable?: boolean;
|
|
20
|
+
deletable?: boolean;
|
|
21
|
+
ariaLabel?: string;
|
|
22
|
+
focusable?: boolean;
|
|
23
|
+
sourceHandle?: string | null;
|
|
24
|
+
targetHandle?: string | null;
|
|
25
|
+
animated?: boolean;
|
|
26
|
+
interactionWidth?: number;
|
|
27
|
+
labelStyle?: import('react').CSSProperties;
|
|
28
|
+
labelShowBg?: boolean;
|
|
29
|
+
labelBgStyle?: import('react').CSSProperties;
|
|
30
|
+
labelBgPadding?: [number, number];
|
|
31
|
+
labelBgBorderRadius?: number;
|
|
32
|
+
updatable?: import('@xyflow/react').EdgeUpdatable;
|
|
33
|
+
data: import('./types').RelationshipData;
|
|
34
|
+
type: "relationship";
|
|
35
|
+
}) => void;
|
|
36
|
+
onEdgeContextMenu: import('@xyflow/react').EdgeMouseHandler<{
|
|
37
|
+
source: string;
|
|
38
|
+
target: string;
|
|
39
|
+
style?: import("react").CSSProperties;
|
|
40
|
+
id: string;
|
|
41
|
+
zIndex?: number;
|
|
42
|
+
markerEnd?: import("@xyflow/react").EdgeMarkerType;
|
|
43
|
+
markerStart?: import("@xyflow/react").EdgeMarkerType;
|
|
44
|
+
hidden?: boolean;
|
|
45
|
+
className?: string;
|
|
46
|
+
label?: import("react").ReactNode;
|
|
47
|
+
selected?: boolean;
|
|
48
|
+
selectable?: boolean;
|
|
49
|
+
deletable?: boolean;
|
|
50
|
+
ariaLabel?: string;
|
|
51
|
+
focusable?: boolean;
|
|
52
|
+
sourceHandle?: string | null;
|
|
53
|
+
targetHandle?: string | null;
|
|
54
|
+
animated?: boolean;
|
|
55
|
+
interactionWidth?: number;
|
|
56
|
+
labelStyle?: import("react").CSSProperties;
|
|
57
|
+
labelShowBg?: boolean;
|
|
58
|
+
labelBgStyle?: import("react").CSSProperties;
|
|
59
|
+
labelBgPadding?: [number, number];
|
|
60
|
+
labelBgBorderRadius?: number;
|
|
61
|
+
updatable?: import("@xyflow/react").EdgeUpdatable;
|
|
62
|
+
data: import("./types").RelationshipData;
|
|
63
|
+
type: "relationship";
|
|
64
|
+
}>;
|
|
65
|
+
onMoveEnd: import('@xyflow/react').OnMove;
|
|
66
|
+
onNodeDoubleClick: import('@xyflow/react').NodeMouseHandler<XYFlowNode>;
|
|
67
|
+
onNodeMouseEnter: import('@xyflow/react').NodeMouseHandler<XYFlowNode>;
|
|
68
|
+
onNodeMouseLeave: import('@xyflow/react').NodeMouseHandler<XYFlowNode>;
|
|
69
|
+
onEdgeMouseEnter: import('@xyflow/react').EdgeMouseHandler<{
|
|
70
|
+
source: string;
|
|
71
|
+
target: string;
|
|
72
|
+
style?: import("react").CSSProperties;
|
|
73
|
+
id: string;
|
|
74
|
+
zIndex?: number;
|
|
75
|
+
markerEnd?: import("@xyflow/react").EdgeMarkerType;
|
|
76
|
+
markerStart?: import("@xyflow/react").EdgeMarkerType;
|
|
77
|
+
hidden?: boolean;
|
|
78
|
+
className?: string;
|
|
79
|
+
label?: import("react").ReactNode;
|
|
80
|
+
selected?: boolean;
|
|
81
|
+
selectable?: boolean;
|
|
82
|
+
deletable?: boolean;
|
|
83
|
+
ariaLabel?: string;
|
|
84
|
+
focusable?: boolean;
|
|
85
|
+
sourceHandle?: string | null;
|
|
86
|
+
targetHandle?: string | null;
|
|
87
|
+
animated?: boolean;
|
|
88
|
+
interactionWidth?: number;
|
|
89
|
+
labelStyle?: import("react").CSSProperties;
|
|
90
|
+
labelShowBg?: boolean;
|
|
91
|
+
labelBgStyle?: import("react").CSSProperties;
|
|
92
|
+
labelBgPadding?: [number, number];
|
|
93
|
+
labelBgBorderRadius?: number;
|
|
94
|
+
updatable?: import("@xyflow/react").EdgeUpdatable;
|
|
95
|
+
data: import("./types").RelationshipData;
|
|
96
|
+
type: "relationship";
|
|
97
|
+
}>;
|
|
98
|
+
onEdgeMouseLeave: import('@xyflow/react').EdgeMouseHandler<{
|
|
99
|
+
source: string;
|
|
100
|
+
target: string;
|
|
101
|
+
style?: import("react").CSSProperties;
|
|
102
|
+
id: string;
|
|
103
|
+
zIndex?: number;
|
|
104
|
+
markerEnd?: import("@xyflow/react").EdgeMarkerType;
|
|
105
|
+
markerStart?: import("@xyflow/react").EdgeMarkerType;
|
|
106
|
+
hidden?: boolean;
|
|
107
|
+
className?: string;
|
|
108
|
+
label?: import("react").ReactNode;
|
|
109
|
+
selected?: boolean;
|
|
110
|
+
selectable?: boolean;
|
|
111
|
+
deletable?: boolean;
|
|
112
|
+
ariaLabel?: string;
|
|
113
|
+
focusable?: boolean;
|
|
114
|
+
sourceHandle?: string | null;
|
|
115
|
+
targetHandle?: string | null;
|
|
116
|
+
animated?: boolean;
|
|
117
|
+
interactionWidth?: number;
|
|
118
|
+
labelStyle?: import("react").CSSProperties;
|
|
119
|
+
labelShowBg?: boolean;
|
|
120
|
+
labelBgStyle?: import("react").CSSProperties;
|
|
121
|
+
labelBgPadding?: [number, number];
|
|
122
|
+
labelBgBorderRadius?: number;
|
|
123
|
+
updatable?: import("@xyflow/react").EdgeUpdatable;
|
|
124
|
+
data: import("./types").RelationshipData;
|
|
125
|
+
type: "relationship";
|
|
126
|
+
}>;
|
|
127
|
+
onPaneClick: (event: import('react').MouseEvent<Element, MouseEvent>) => void;
|
|
128
|
+
onPaneContextMenu: (event: MouseEvent | import('react').MouseEvent<Element, MouseEvent>) => void;
|
|
13
129
|
};
|
|
14
|
-
export declare function useXYFlowEvents(): XYFlowEventHandlers;
|
|
15
|
-
export {};
|
|
@@ -10,13 +10,13 @@ export declare const RelationshipEdge: import('react').NamedExoticComponent<Edge
|
|
|
10
10
|
markerEnd?: import("@xyflow/react").EdgeMarkerType;
|
|
11
11
|
markerStart?: import("@xyflow/react").EdgeMarkerType;
|
|
12
12
|
hidden?: boolean;
|
|
13
|
+
className?: string;
|
|
14
|
+
label?: import("react").ReactNode;
|
|
13
15
|
selected?: boolean;
|
|
14
16
|
selectable?: boolean;
|
|
15
17
|
deletable?: boolean;
|
|
16
18
|
ariaLabel?: string;
|
|
17
|
-
className?: string;
|
|
18
19
|
focusable?: boolean;
|
|
19
|
-
label?: import("react").ReactNode;
|
|
20
20
|
sourceHandle?: string | null;
|
|
21
21
|
targetHandle?: string | null;
|
|
22
22
|
animated?: boolean;
|
|
@@ -9,13 +9,13 @@ export declare const useXYFlow: () => import('@xyflow/react').ReactFlowInstance<
|
|
|
9
9
|
markerEnd?: import("@xyflow/react").EdgeMarkerType;
|
|
10
10
|
markerStart?: import("@xyflow/react").EdgeMarkerType;
|
|
11
11
|
hidden?: boolean;
|
|
12
|
+
className?: string;
|
|
13
|
+
label?: import("react").ReactNode;
|
|
12
14
|
selected?: boolean;
|
|
13
15
|
selectable?: boolean;
|
|
14
16
|
deletable?: boolean;
|
|
15
17
|
ariaLabel?: string;
|
|
16
|
-
className?: string;
|
|
17
18
|
focusable?: boolean;
|
|
18
|
-
label?: import("react").ReactNode;
|
|
19
19
|
sourceHandle?: string | null;
|
|
20
20
|
targetHandle?: string | null;
|
|
21
21
|
animated?: boolean;
|
|
@@ -30,8 +30,8 @@ export declare const useXYFlow: () => import('@xyflow/react').ReactFlowInstance<
|
|
|
30
30
|
type: "relationship";
|
|
31
31
|
}>;
|
|
32
32
|
export declare const useXYNodesData: {
|
|
33
|
-
(nodeId: string): Pick<XYFlowNode, "id" | "
|
|
34
|
-
(nodeIds: string[]): Pick<XYFlowNode, "id" | "
|
|
33
|
+
(nodeId: string): Pick<XYFlowNode, "id" | "data" | "type"> | null;
|
|
34
|
+
(nodeIds: string[]): Pick<XYFlowNode, "id" | "data" | "type">[];
|
|
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: () => {
|
|
@@ -44,13 +44,13 @@ export declare const useXYStoreApi: () => {
|
|
|
44
44
|
markerEnd?: import("@xyflow/react").EdgeMarkerType;
|
|
45
45
|
markerStart?: import("@xyflow/react").EdgeMarkerType;
|
|
46
46
|
hidden?: boolean;
|
|
47
|
+
className?: string;
|
|
48
|
+
label?: import("react").ReactNode;
|
|
47
49
|
selected?: boolean;
|
|
48
50
|
selectable?: boolean;
|
|
49
51
|
deletable?: boolean;
|
|
50
52
|
ariaLabel?: string;
|
|
51
|
-
className?: string;
|
|
52
53
|
focusable?: boolean;
|
|
53
|
-
label?: import("react").ReactNode;
|
|
54
54
|
sourceHandle?: string | null;
|
|
55
55
|
targetHandle?: string | null;
|
|
56
56
|
animated?: boolean;
|
|
@@ -73,13 +73,13 @@ export declare const useXYStoreApi: () => {
|
|
|
73
73
|
markerEnd?: import("@xyflow/react").EdgeMarkerType;
|
|
74
74
|
markerStart?: import("@xyflow/react").EdgeMarkerType;
|
|
75
75
|
hidden?: boolean;
|
|
76
|
+
className?: string;
|
|
77
|
+
label?: import("react").ReactNode;
|
|
76
78
|
selected?: boolean;
|
|
77
79
|
selectable?: boolean;
|
|
78
80
|
deletable?: boolean;
|
|
79
81
|
ariaLabel?: string;
|
|
80
|
-
className?: string;
|
|
81
82
|
focusable?: boolean;
|
|
82
|
-
label?: import("react").ReactNode;
|
|
83
83
|
sourceHandle?: string | null;
|
|
84
84
|
targetHandle?: string | null;
|
|
85
85
|
animated?: boolean;
|
|
@@ -101,13 +101,13 @@ export declare const useXYStoreApi: () => {
|
|
|
101
101
|
markerEnd?: import("@xyflow/react").EdgeMarkerType;
|
|
102
102
|
markerStart?: import("@xyflow/react").EdgeMarkerType;
|
|
103
103
|
hidden?: boolean;
|
|
104
|
+
className?: string;
|
|
105
|
+
label?: import("react").ReactNode;
|
|
104
106
|
selected?: boolean;
|
|
105
107
|
selectable?: boolean;
|
|
106
108
|
deletable?: boolean;
|
|
107
109
|
ariaLabel?: string;
|
|
108
|
-
className?: string;
|
|
109
110
|
focusable?: boolean;
|
|
110
|
-
label?: import("react").ReactNode;
|
|
111
111
|
sourceHandle?: string | null;
|
|
112
112
|
targetHandle?: string | null;
|
|
113
113
|
animated?: boolean;
|
|
@@ -129,13 +129,13 @@ export declare const useXYStoreApi: () => {
|
|
|
129
129
|
markerEnd?: import("@xyflow/react").EdgeMarkerType;
|
|
130
130
|
markerStart?: import("@xyflow/react").EdgeMarkerType;
|
|
131
131
|
hidden?: boolean;
|
|
132
|
+
className?: string;
|
|
133
|
+
label?: import("react").ReactNode;
|
|
132
134
|
selected?: boolean;
|
|
133
135
|
selectable?: boolean;
|
|
134
136
|
deletable?: boolean;
|
|
135
137
|
ariaLabel?: string;
|
|
136
|
-
className?: string;
|
|
137
138
|
focusable?: boolean;
|
|
138
|
-
label?: import("react").ReactNode;
|
|
139
139
|
sourceHandle?: string | null;
|
|
140
140
|
targetHandle?: string | null;
|
|
141
141
|
animated?: boolean;
|
|
@@ -157,13 +157,13 @@ export declare const useXYStoreApi: () => {
|
|
|
157
157
|
markerEnd?: import("@xyflow/react").EdgeMarkerType;
|
|
158
158
|
markerStart?: import("@xyflow/react").EdgeMarkerType;
|
|
159
159
|
hidden?: boolean;
|
|
160
|
+
className?: string;
|
|
161
|
+
label?: import("react").ReactNode;
|
|
160
162
|
selected?: boolean;
|
|
161
163
|
selectable?: boolean;
|
|
162
164
|
deletable?: boolean;
|
|
163
165
|
ariaLabel?: string;
|
|
164
|
-
className?: string;
|
|
165
166
|
focusable?: boolean;
|
|
166
|
-
label?: import("react").ReactNode;
|
|
167
167
|
sourceHandle?: string | null;
|
|
168
168
|
targetHandle?: string | null;
|
|
169
169
|
animated?: boolean;
|
|
@@ -185,13 +185,13 @@ export declare const useXYStoreApi: () => {
|
|
|
185
185
|
markerEnd?: import("@xyflow/react").EdgeMarkerType;
|
|
186
186
|
markerStart?: import("@xyflow/react").EdgeMarkerType;
|
|
187
187
|
hidden?: boolean;
|
|
188
|
+
className?: string;
|
|
189
|
+
label?: import("react").ReactNode;
|
|
188
190
|
selected?: boolean;
|
|
189
191
|
selectable?: boolean;
|
|
190
192
|
deletable?: boolean;
|
|
191
193
|
ariaLabel?: string;
|
|
192
|
-
className?: string;
|
|
193
194
|
focusable?: boolean;
|
|
194
|
-
label?: import("react").ReactNode;
|
|
195
195
|
sourceHandle?: string | null;
|
|
196
196
|
targetHandle?: string | null;
|
|
197
197
|
animated?: boolean;
|
|
@@ -214,13 +214,13 @@ export declare const useXYStoreApi: () => {
|
|
|
214
214
|
markerEnd?: import("@xyflow/react").EdgeMarkerType;
|
|
215
215
|
markerStart?: import("@xyflow/react").EdgeMarkerType;
|
|
216
216
|
hidden?: boolean;
|
|
217
|
+
className?: string;
|
|
218
|
+
label?: import("react").ReactNode;
|
|
217
219
|
selected?: boolean;
|
|
218
220
|
selectable?: boolean;
|
|
219
221
|
deletable?: boolean;
|
|
220
222
|
ariaLabel?: string;
|
|
221
|
-
className?: string;
|
|
222
223
|
focusable?: boolean;
|
|
223
|
-
label?: import("react").ReactNode;
|
|
224
224
|
sourceHandle?: string | null;
|
|
225
225
|
targetHandle?: string | null;
|
|
226
226
|
animated?: boolean;
|
|
@@ -242,13 +242,13 @@ export declare const useXYStoreApi: () => {
|
|
|
242
242
|
markerEnd?: import("@xyflow/react").EdgeMarkerType;
|
|
243
243
|
markerStart?: import("@xyflow/react").EdgeMarkerType;
|
|
244
244
|
hidden?: boolean;
|
|
245
|
+
className?: string;
|
|
246
|
+
label?: import("react").ReactNode;
|
|
245
247
|
selected?: boolean;
|
|
246
248
|
selectable?: boolean;
|
|
247
249
|
deletable?: boolean;
|
|
248
250
|
ariaLabel?: string;
|
|
249
|
-
className?: string;
|
|
250
251
|
focusable?: boolean;
|
|
251
|
-
label?: import("react").ReactNode;
|
|
252
252
|
sourceHandle?: string | null;
|
|
253
253
|
targetHandle?: string | null;
|
|
254
254
|
animated?: boolean;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export declare const
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const
|
|
1
|
+
export declare const container: string;
|
|
2
|
+
export declare const varTransparency: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
|
|
3
|
+
export declare const compoundBody: string;
|
|
4
|
+
export declare const transparent: string;
|
|
5
|
+
export declare const title: string;
|
|
6
|
+
export declare const indicator: string;
|
|
7
|
+
export declare const navigateBtn: string;
|
package/dist/xyflow/types.d.ts
CHANGED
|
@@ -48,13 +48,13 @@ export declare namespace XYFlowEdge {
|
|
|
48
48
|
markerEnd?: import('@xyflow/react').EdgeMarkerType;
|
|
49
49
|
markerStart?: import('@xyflow/react').EdgeMarkerType;
|
|
50
50
|
hidden?: boolean;
|
|
51
|
+
className?: string;
|
|
52
|
+
label?: import('react').ReactNode;
|
|
51
53
|
selected?: boolean;
|
|
52
54
|
selectable?: boolean;
|
|
53
55
|
deletable?: boolean;
|
|
54
56
|
ariaLabel?: string;
|
|
55
|
-
className?: string;
|
|
56
57
|
focusable?: boolean;
|
|
57
|
-
label?: import('react').ReactNode;
|
|
58
58
|
sourceHandle?: string | null;
|
|
59
59
|
targetHandle?: string | null;
|
|
60
60
|
animated?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@likec4/diagram",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"bugs": "https://github.com/likec4/likec4/issues",
|
|
6
6
|
"homepage": "https://likec4.dev",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"clean": "run -T rimraf -v -g 'dist/*' .tsbuildinfo"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@likec4/core": "1.0
|
|
53
|
+
"@likec4/core": "1.1.0",
|
|
54
54
|
"@react-hookz/web": "^24.0.4",
|
|
55
55
|
"esm-env": "^1.0.0",
|
|
56
56
|
"fast-equals": "^5.0.1",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"@vitejs/plugin-react": "^4.2.1",
|
|
79
79
|
"@xyflow/react": "^12.0.0-next",
|
|
80
80
|
"clsx": "^2.1.1",
|
|
81
|
-
"execa": "^
|
|
81
|
+
"execa": "^9.1.0",
|
|
82
82
|
"khroma": "^2.1.0",
|
|
83
83
|
"react": "^18.2.0",
|
|
84
84
|
"react-dom": "^18.2.0",
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { Box } from '@mantine/core'
|
|
2
2
|
import clsx from 'clsx'
|
|
3
|
-
import type
|
|
4
|
-
import
|
|
3
|
+
import { type HTMLAttributes, useId } from 'react'
|
|
4
|
+
import * as css from './LikeC4Diagram.css'
|
|
5
5
|
|
|
6
|
-
type
|
|
6
|
+
type KeepAspectRatioContainerProps = HTMLAttributes<HTMLDivElement> & {
|
|
7
|
+
// Whether to keep the aspect ratio
|
|
7
8
|
enabled: boolean
|
|
8
9
|
width: number
|
|
9
10
|
height: number
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
export function
|
|
13
|
+
export function KeepAspectRatioContainer({
|
|
13
14
|
children,
|
|
14
15
|
width,
|
|
15
16
|
height,
|
|
@@ -17,11 +18,11 @@ export function KeepAspectRatio({
|
|
|
17
18
|
className,
|
|
18
19
|
style,
|
|
19
20
|
...rest
|
|
20
|
-
}:
|
|
21
|
+
}: KeepAspectRatioContainerProps) {
|
|
21
22
|
return (
|
|
22
23
|
<Box
|
|
23
24
|
{...rest}
|
|
24
|
-
className={clsx(
|
|
25
|
+
className={clsx(css.keepAspectRatioContainer, className)}
|
|
25
26
|
style={enabled
|
|
26
27
|
? {
|
|
27
28
|
...style,
|
package/src/LikeC4Diagram.css.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
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
|
+
width: '100%',
|
|
6
|
+
height: '100%',
|
|
7
|
+
padding: 0
|
|
8
|
+
})
|
|
9
|
+
|
|
4
10
|
export const cssReactFlow = style({})
|
|
5
11
|
|
|
6
12
|
globalStyle(`.react-flow${cssReactFlow}`, {
|
package/src/LikeC4Diagram.tsx
CHANGED
|
@@ -2,18 +2,18 @@ import { ReactFlowProvider as XYFlowProvider } from '@xyflow/react'
|
|
|
2
2
|
import clsx from 'clsx'
|
|
3
3
|
import { useRef } from 'react'
|
|
4
4
|
import { rootClassName } from './globals.css'
|
|
5
|
+
import { KeepAspectRatioContainer } from './KeepAspectRatioContainer'
|
|
5
6
|
import { cssDisablePan, cssNoControls, cssReactFlow, cssTransparentBg } from './LikeC4Diagram.css'
|
|
6
7
|
import { type LikeC4DiagramEventHandlers, type LikeC4DiagramProperties } from './LikeC4Diagram.props'
|
|
7
8
|
import { EnsureMantine } from './mantine/EnsureMantine'
|
|
8
9
|
import { DiagramContextProvider } from './state/DiagramContext'
|
|
9
10
|
import { WhenInitialized } from './state/WhenInitialized'
|
|
10
|
-
import { KeepAspectRatio } from './ui/KeepAspectRatio'
|
|
11
11
|
import OptionsPanel from './ui/OptionsPanel'
|
|
12
12
|
import { diagramViewToXYFlowData } from './xyflow/diagram-to-xyflow'
|
|
13
13
|
import { FitViewOnDiagramChange } from './xyflow/FitviewOnDiagramChange'
|
|
14
14
|
import { SyncWithDiagram } from './xyflow/SyncWithDiagram'
|
|
15
15
|
import type { XYFlowData } from './xyflow/types'
|
|
16
|
-
import { XYFlow } from './xyflow/
|
|
16
|
+
import { XYFlow } from './xyflow/XYFlow'
|
|
17
17
|
|
|
18
18
|
export type LikeC4DiagramProps = LikeC4DiagramProperties & LikeC4DiagramEventHandlers
|
|
19
19
|
export function LikeC4Diagram({
|
|
@@ -69,6 +69,8 @@ export function LikeC4Diagram({
|
|
|
69
69
|
<DiagramContextProvider
|
|
70
70
|
view={view}
|
|
71
71
|
readonly={readonly}
|
|
72
|
+
pannable={pannable}
|
|
73
|
+
zoomable={zoomable}
|
|
72
74
|
fitViewEnabled={fitView}
|
|
73
75
|
fitViewPadding={fitViewPadding}
|
|
74
76
|
showElementLinks={showElementLinks}
|
|
@@ -84,7 +86,7 @@ export function LikeC4Diagram({
|
|
|
84
86
|
onNavigateTo={onNavigateTo}
|
|
85
87
|
onCanvasDblClick={onCanvasDblClick}
|
|
86
88
|
>
|
|
87
|
-
<
|
|
89
|
+
<KeepAspectRatioContainer
|
|
88
90
|
className={clsx(rootClassName, className)}
|
|
89
91
|
enabled={keepAspectRatio}
|
|
90
92
|
width={view.width}
|
|
@@ -102,12 +104,10 @@ export function LikeC4Diagram({
|
|
|
102
104
|
controls={controls}
|
|
103
105
|
defaultNodes={initialRef.current.defaultNodes}
|
|
104
106
|
defaultEdges={initialRef.current.defaultEdges}
|
|
105
|
-
pannable={pannable}
|
|
106
|
-
zoomable={zoomable}
|
|
107
107
|
>
|
|
108
108
|
{readonly !== true && <OptionsPanel />}
|
|
109
109
|
</XYFlow>
|
|
110
|
-
</
|
|
110
|
+
</KeepAspectRatioContainer>
|
|
111
111
|
<WhenInitialized>
|
|
112
112
|
<SyncWithDiagram />
|
|
113
113
|
<FitViewOnDiagramChange />
|
package/src/globals.css.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ThemeColor } from '@likec4/core'
|
|
2
1
|
import { defaultTheme } from '@likec4/core'
|
|
3
2
|
import { createGlobalTheme } from '@vanilla-extract/css'
|
|
4
|
-
import {
|
|
3
|
+
import { scale, toHex } from 'khroma'
|
|
4
|
+
import { keys, omit } from 'remeda'
|
|
5
5
|
import { mantine } from './mantine.css'
|
|
6
6
|
import { vars } from './theme.css'
|
|
7
7
|
|
|
@@ -75,38 +75,7 @@ createGlobalTheme(`:where([data-mantine-color-scheme='light']) .${rootClassName}
|
|
|
75
75
|
}
|
|
76
76
|
})
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
// boxSizing: 'border-box',
|
|
80
|
-
// outline: 'none',
|
|
81
|
-
// borderWidth: 0,
|
|
82
|
-
// borderStyle: 'solid',
|
|
83
|
-
// borderColor: 'transparent',
|
|
84
|
-
// })
|
|
85
|
-
|
|
86
|
-
// createGlobalTheme(':where(.likec4-diagram-root)', {
|
|
87
|
-
// ...omit(vars, ['optionsPanel', 'defaults']),
|
|
88
|
-
// }, {
|
|
89
|
-
// likec4: {
|
|
90
|
-
// font: `var(--likec4-default-font-family,'ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"')`,
|
|
91
|
-
// backgroundColor: mantine.colors.body
|
|
92
|
-
// },
|
|
93
|
-
// compound: {
|
|
94
|
-
// font: vars.likec4.font,
|
|
95
|
-
// titleColor: vars.element.loContrast
|
|
96
|
-
// },
|
|
97
|
-
// element: {
|
|
98
|
-
// font: vars.likec4.font,
|
|
99
|
-
// ...defaultTheme.elements.primary
|
|
100
|
-
// },
|
|
101
|
-
// relation: {
|
|
102
|
-
// ...defaultTheme.relationships.slate
|
|
103
|
-
// }
|
|
104
|
-
// })
|
|
105
|
-
|
|
106
|
-
for (const color of Object.keys(defaultTheme.elements)) {
|
|
107
|
-
if (!(color in defaultTheme.elements) || !(color in defaultTheme.relationships)) {
|
|
108
|
-
continue
|
|
109
|
-
}
|
|
78
|
+
for (const color of keys.strict(defaultTheme.elements)) {
|
|
110
79
|
createGlobalTheme(`:where([data-likec4-color='${color}'])`, {
|
|
111
80
|
element: {
|
|
112
81
|
fill: vars.element.fill,
|
|
@@ -119,10 +88,46 @@ for (const color of Object.keys(defaultTheme.elements)) {
|
|
|
119
88
|
},
|
|
120
89
|
relation: vars.relation
|
|
121
90
|
}, {
|
|
122
|
-
element: defaultTheme.elements[color
|
|
91
|
+
element: defaultTheme.elements[color],
|
|
123
92
|
compound: {
|
|
124
|
-
titleColor: defaultTheme.elements[color
|
|
93
|
+
titleColor: defaultTheme.elements[color].loContrast
|
|
125
94
|
},
|
|
126
|
-
relation: defaultTheme.relationships[color
|
|
95
|
+
relation: defaultTheme.relationships[color]
|
|
127
96
|
})
|
|
97
|
+
|
|
98
|
+
const compoundDarkColor = (color: string, depth: number) =>
|
|
99
|
+
toHex(
|
|
100
|
+
scale(color, {
|
|
101
|
+
l: -22 - 5 * depth,
|
|
102
|
+
s: -10 - 6 * depth
|
|
103
|
+
})
|
|
104
|
+
)
|
|
105
|
+
const compoundLightColor = (color: string, depth: number) =>
|
|
106
|
+
toHex(
|
|
107
|
+
scale(color, {
|
|
108
|
+
l: -20 - 3 * depth,
|
|
109
|
+
s: -3 - 6 * depth
|
|
110
|
+
})
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
const compounds = {
|
|
114
|
+
fill: vars.element.fill,
|
|
115
|
+
stroke: vars.element.stroke
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
for (let depth = 1; depth <= 6; depth++) {
|
|
119
|
+
createGlobalTheme(`:where([data-likec4-color='${color}'][data-compound-depth='${depth}'])`, compounds, {
|
|
120
|
+
fill: compoundDarkColor(defaultTheme.elements[color].fill, depth),
|
|
121
|
+
stroke: compoundDarkColor(defaultTheme.elements[color].stroke, depth)
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
createGlobalTheme(
|
|
125
|
+
`:where([data-mantine-color-scheme='light']) :where([data-likec4-color='${color}'][data-compound-depth='${depth}'])`,
|
|
126
|
+
compounds,
|
|
127
|
+
{
|
|
128
|
+
fill: compoundLightColor(defaultTheme.elements[color].fill, depth),
|
|
129
|
+
stroke: compoundLightColor(defaultTheme.elements[color].stroke, depth)
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
}
|
|
128
133
|
}
|