likec4 0.44.2 → 0.45.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/@likec4/diagrams/components/primitives/fullscreen/FullscreenDiagram.js +8 -7
- package/dist/@likec4/diagrams/diagram/Diagram.js +16 -5
- package/dist/@likec4/diagrams/diagram/Edges.js +32 -16
- package/dist/@likec4/diagrams/diagram/Nodes.js +75 -77
- package/dist/@likec4/diagrams/diagram/icons/ZoomIn.js +2 -3
- package/dist/@likec4/diagrams/diagram/shapes/Browser.js +43 -9
- package/dist/@likec4/diagrams/diagram/shapes/Compound.js +8 -10
- package/dist/@likec4/diagrams/diagram/shapes/Cylinder.js +3 -1
- package/dist/@likec4/diagrams/diagram/shapes/Edge.js +7 -7
- package/dist/@likec4/diagrams/diagram/shapes/Mobile.js +19 -4
- package/dist/@likec4/diagrams/diagram/shapes/NodeIcon.js +47 -9
- package/dist/@likec4/diagrams/diagram/shapes/NodeLabel.js +31 -54
- package/dist/@likec4/diagrams/diagram/shapes/Person.js +3 -1
- package/dist/@likec4/diagrams/diagram/shapes/Queue.js +3 -1
- package/dist/@likec4/diagrams/diagram/shapes/Rectangle.js +3 -1
- package/dist/@likec4/diagrams/diagram/shapes/index.js +1 -1
- package/dist/@likec4/diagrams/diagram/shapes/utils.js +1 -1
- package/dist/@likec4/diagrams/diagram/state/atoms.js +6 -0
- package/dist/@likec4/diagrams/diagram/state/hooks.js +10 -1
- package/dist/@likec4/diagrams/hooks/useImageLoader.js +7 -1
- package/dist/__app__/likec4.css +4 -0
- package/dist/__app__/src/App.jsx +25 -5
- package/dist/__app__/src/components/DiagramNotFound.jsx +10 -4
- package/dist/__app__/src/pages/embed.page.jsx +12 -0
- package/dist/__app__/src/pages/export.page.jsx +9 -6
- package/dist/__app__/src/pages/index.js +1 -0
- package/dist/__app__/src/pages/view.page.jsx +8 -8
- package/dist/__app__/src/router.js +2 -2
- package/dist/__app__/tailwind.config.cjs +1 -3
- package/dist/__app__/tsconfig.json +1 -2
- package/dist/cli/index.js +143 -143
- package/package.json +6 -7
- package/dist/@likec4/diagrams/hooks/useDarkMode.js +0 -5
- package/dist/@likec4/diagrams/index.mjs +0 -1927
|
@@ -12,23 +12,24 @@ const StyleOverlay = {
|
|
|
12
12
|
left: 0,
|
|
13
13
|
right: 0,
|
|
14
14
|
bottom: 0,
|
|
15
|
-
backgroundColor: "var(--likec4-browser-overlay-bg, rgba(18,18,18,0.
|
|
15
|
+
backgroundColor: "var(--likec4-browser-overlay-bg, rgba(18,18,18,0.9))",
|
|
16
16
|
backdropFilter: "var(--likec4-browser-backdrop, blur(4px))",
|
|
17
17
|
zIndex: "var(--likec4-overlay-z-index, 100)",
|
|
18
|
-
display: "flex",
|
|
19
|
-
placeContent: "strech",
|
|
20
|
-
placeItems: "strech",
|
|
21
|
-
touchAction: "pan-x pan-y pinch-zoom",
|
|
22
18
|
boxSizing: "border-box",
|
|
23
19
|
margin: 0,
|
|
24
20
|
padding: 0,
|
|
25
21
|
border: "0 solid transparent"
|
|
26
22
|
};
|
|
27
23
|
const StyleContainer = {
|
|
24
|
+
position: "absolute",
|
|
25
|
+
top: 0,
|
|
26
|
+
left: 0,
|
|
27
|
+
right: 0,
|
|
28
|
+
bottom: 0,
|
|
28
29
|
margin: 0,
|
|
29
30
|
padding: 0,
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
overflow: "hidden",
|
|
32
|
+
touchAction: "pan-x pan-y pinch-zoom"
|
|
32
33
|
};
|
|
33
34
|
export function FullscreenDiagram({
|
|
34
35
|
diagram,
|
|
@@ -8,7 +8,7 @@ import { AnimatedStage, Layer } from "../konva.js";
|
|
|
8
8
|
import { Edges } from "./Edges.js";
|
|
9
9
|
import { createUseGesture, dragAction, pinchAction } from "@use-gesture/react";
|
|
10
10
|
import { Nodes } from "./Nodes.js";
|
|
11
|
-
import { DiagramGesture } from "./state/index.js";
|
|
11
|
+
import { DiagramGesture, useResetHoveredStates } from "./state/index.js";
|
|
12
12
|
const useGesture = createUseGesture([dragAction, pinchAction]);
|
|
13
13
|
const useSyncedRef = (value) => {
|
|
14
14
|
const ref = useRef(value);
|
|
@@ -42,6 +42,8 @@ export const Diagram = /* @__PURE__ */ forwardRef(
|
|
|
42
42
|
onStageContextMenu,
|
|
43
43
|
width: _width,
|
|
44
44
|
height: _height,
|
|
45
|
+
minZoom = 0.2,
|
|
46
|
+
maxZoom = 1.1,
|
|
45
47
|
...props
|
|
46
48
|
}, ref) => {
|
|
47
49
|
const immediate = !animate;
|
|
@@ -62,7 +64,7 @@ export const Diagram = /* @__PURE__ */ forwardRef(
|
|
|
62
64
|
const viewRect = {
|
|
63
65
|
width: Math.min(container?.clientWidth ?? width, width) - paddingLeft - paddingRight,
|
|
64
66
|
height: Math.min(container?.clientHeight ?? height, height) - paddingTop - paddingBottom
|
|
65
|
-
}, viewScale = Math.min(viewRect.width / centerTo.width, viewRect.height / centerTo.height), scale = clamp(
|
|
67
|
+
}, viewScale = Math.min(viewRect.width / centerTo.width, viewRect.height / centerTo.height), scale = clamp(minZoom, maxZoom, viewScale), centeringAjustment = {
|
|
66
68
|
x: ((width - centerTo.width) * scale + viewRect.width) / 2,
|
|
67
69
|
y: ((height - centerTo.height) * scale + viewRect.height) / 2
|
|
68
70
|
}, finalPosition = {
|
|
@@ -147,6 +149,10 @@ export const Diagram = /* @__PURE__ */ forwardRef(
|
|
|
147
149
|
}),
|
|
148
150
|
[refs, id, stageRef]
|
|
149
151
|
);
|
|
152
|
+
const resetHoveredStates = useResetHoveredStates();
|
|
153
|
+
useUpdateEffect(() => {
|
|
154
|
+
resetHoveredStates();
|
|
155
|
+
}, [id]);
|
|
150
156
|
useUpdateEffect(() => {
|
|
151
157
|
refs.current.centerAndFit(80, 650);
|
|
152
158
|
}, [id, height, width]);
|
|
@@ -213,21 +219,26 @@ export const Diagram = /* @__PURE__ */ forwardRef(
|
|
|
213
219
|
{
|
|
214
220
|
target: containerRef,
|
|
215
221
|
drag: {
|
|
222
|
+
target: containerRef,
|
|
216
223
|
enabled: pannable,
|
|
217
224
|
threshold: 4,
|
|
218
225
|
from: () => [stageProps.x.get(), stageProps.y.get()],
|
|
219
226
|
pointer: {
|
|
220
227
|
buttons: -1,
|
|
221
|
-
keys: false
|
|
228
|
+
keys: false,
|
|
229
|
+
touch: true,
|
|
230
|
+
capture: true
|
|
222
231
|
}
|
|
223
232
|
},
|
|
224
233
|
pinch: {
|
|
234
|
+
target: containerRef,
|
|
225
235
|
pointer: {
|
|
226
236
|
touch: true
|
|
227
237
|
},
|
|
228
238
|
enabled: zoomable,
|
|
229
|
-
|
|
230
|
-
|
|
239
|
+
// eventOptions
|
|
240
|
+
scaleBounds: { min: minZoom, max: maxZoom + 0.4 },
|
|
241
|
+
rubberband: 0.04,
|
|
231
242
|
pinchOnWheel: true
|
|
232
243
|
}
|
|
233
244
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { DefaultRelationshipColor } from "@likec4/core";
|
|
3
|
+
import { isEqualSimple } from "@react-hookz/deep-equal/esnext";
|
|
3
4
|
import { useTransition } from "@react-spring/konva";
|
|
4
5
|
import { scale, toHex } from "khroma";
|
|
5
6
|
import { memoize } from "rambdax";
|
|
6
|
-
import { useCallback } from "react";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { memo, useCallback } from "react";
|
|
8
|
+
import { AnimatedGroup } from "../konva.js";
|
|
9
|
+
import { Edge } from "./shapes/Edge.js";
|
|
9
10
|
import { mouseDefault, mousePointer } from "./shapes/utils.js";
|
|
10
11
|
import { DiagramGesture, useHoveredEdgeId, useSetHoveredEdge } from "./state/index.js";
|
|
11
12
|
const edgeColors = memoize((colors, isHovered) => {
|
|
@@ -13,13 +14,13 @@ const edgeColors = memoize((colors, isHovered) => {
|
|
|
13
14
|
return {
|
|
14
15
|
lineColor: toHex(
|
|
15
16
|
scale(colors.lineColor, {
|
|
16
|
-
l:
|
|
17
|
-
s: -5
|
|
17
|
+
l: 30
|
|
18
18
|
})
|
|
19
19
|
),
|
|
20
20
|
labelColor: toHex(
|
|
21
21
|
scale(colors.labelColor, {
|
|
22
|
-
l: 40
|
|
22
|
+
l: 40,
|
|
23
|
+
s: 5
|
|
23
24
|
})
|
|
24
25
|
),
|
|
25
26
|
labelBgColor: toHex(
|
|
@@ -34,7 +35,6 @@ const edgeColors = memoize((colors, isHovered) => {
|
|
|
34
35
|
});
|
|
35
36
|
export function Edges({ animate, theme, diagram, onEdgeClick }) {
|
|
36
37
|
const hoveredEdgeId = useHoveredEdgeId();
|
|
37
|
-
const setHoveredEdge = useSetHoveredEdge();
|
|
38
38
|
const edgeSprings = useCallback(
|
|
39
39
|
(edge, isHovered = false) => {
|
|
40
40
|
return {
|
|
@@ -83,9 +83,25 @@ export function Edges({ animate, theme, diagram, onEdgeClick }) {
|
|
|
83
83
|
// to avoid any issues with diagram-to-diagram transitions
|
|
84
84
|
keys: (e) => e.id + diagram.id
|
|
85
85
|
});
|
|
86
|
-
return edgeTransitions((
|
|
87
|
-
|
|
86
|
+
return edgeTransitions((_, edge, { key, ctrl }) => /* @__PURE__ */ jsx(
|
|
87
|
+
EdgeShape,
|
|
88
|
+
{
|
|
89
|
+
animate,
|
|
90
|
+
edge,
|
|
91
|
+
isHovered: hoveredEdgeId === edge.id,
|
|
92
|
+
theme,
|
|
93
|
+
ctrl,
|
|
94
|
+
onEdgeClick
|
|
95
|
+
},
|
|
96
|
+
key
|
|
97
|
+
));
|
|
98
|
+
}
|
|
99
|
+
const EdgeShape = memo(({ animate, edge, ctrl, theme, isHovered, onEdgeClick }) => {
|
|
100
|
+
const setHoveredEdge = useSetHoveredEdge();
|
|
101
|
+
return /* @__PURE__ */ jsx(
|
|
102
|
+
AnimatedGroup,
|
|
88
103
|
{
|
|
104
|
+
opacity: ctrl.springs.opacity,
|
|
89
105
|
onPointerClick: (e) => {
|
|
90
106
|
if (!onEdgeClick || DiagramGesture.isDragging || e.evt.button !== 0) {
|
|
91
107
|
return;
|
|
@@ -104,16 +120,16 @@ export function Edges({ animate, theme, diagram, onEdgeClick }) {
|
|
|
104
120
|
mouseDefault(e);
|
|
105
121
|
},
|
|
106
122
|
children: /* @__PURE__ */ jsx(
|
|
107
|
-
|
|
123
|
+
Edge,
|
|
108
124
|
{
|
|
109
125
|
animate,
|
|
110
126
|
edge,
|
|
111
|
-
isHovered
|
|
127
|
+
isHovered,
|
|
112
128
|
theme,
|
|
113
|
-
springs
|
|
129
|
+
springs: ctrl.springs
|
|
114
130
|
}
|
|
115
131
|
)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
}, isEqualSimple);
|
|
135
|
+
EdgeShape.displayName = "EdgeShape";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { nonexhaustive } from "@likec4/core";
|
|
3
|
+
import { isEqualSimple } from "@react-hookz/deep-equal/esnext";
|
|
3
4
|
import { useTransition } from "@react-spring/konva";
|
|
4
|
-
import { useRef } from "react";
|
|
5
|
+
import { memo, useRef } from "react";
|
|
5
6
|
import { AnimatedGroup } from "../konva.js";
|
|
6
7
|
import { Portal } from "../konva-portal.js";
|
|
7
8
|
import { ZoomInIcon } from "./icons/index.js";
|
|
@@ -115,7 +116,7 @@ export function Nodes({ animate, theme, diagram, onNodeClick }) {
|
|
|
115
116
|
keys: keyOf
|
|
116
117
|
});
|
|
117
118
|
return nodeTransitions((_, node, { key, ctrl, expired }) => /* @__PURE__ */ jsx(
|
|
118
|
-
|
|
119
|
+
NodeShape,
|
|
119
120
|
{
|
|
120
121
|
animate,
|
|
121
122
|
node,
|
|
@@ -128,81 +129,78 @@ export function Nodes({ animate, theme, diagram, onNodeClick }) {
|
|
|
128
129
|
key
|
|
129
130
|
));
|
|
130
131
|
}
|
|
131
|
-
|
|
132
|
-
animate,
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
{
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
132
|
+
const NodeShape = memo(
|
|
133
|
+
({ animate, node, ctrl, theme, isHovered, expired, onNodeClick }) => {
|
|
134
|
+
const setHoveredNode = useSetHoveredNode();
|
|
135
|
+
const _isCompound = isCompound(node);
|
|
136
|
+
const isNavigatable = !!node.navigateTo && !!onNodeClick;
|
|
137
|
+
const Shape = nodeShape(node);
|
|
138
|
+
const springs = ctrl.springs;
|
|
139
|
+
let zoomInIconY;
|
|
140
|
+
switch (node.shape) {
|
|
141
|
+
case "browser":
|
|
142
|
+
case "mobile":
|
|
143
|
+
zoomInIconY = node.size.height - 20;
|
|
144
|
+
break;
|
|
145
|
+
default:
|
|
146
|
+
zoomInIconY = node.size.height - 16;
|
|
147
|
+
}
|
|
148
|
+
return /* @__PURE__ */ jsx(Portal, { selector: ".top", enabled: isHovered && !_isCompound, children: /* @__PURE__ */ jsxs(
|
|
149
|
+
AnimatedGroup,
|
|
150
|
+
{
|
|
151
|
+
name: node.id,
|
|
152
|
+
visible: expired !== true,
|
|
153
|
+
...animate && {
|
|
154
|
+
onPointerEnter: (e) => {
|
|
155
|
+
setHoveredNode(node);
|
|
156
|
+
if (isNavigatable) {
|
|
157
|
+
mousePointer(e);
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
onPointerLeave: (e) => {
|
|
161
|
+
setHoveredNode(null);
|
|
162
|
+
mouseDefault(e);
|
|
155
163
|
}
|
|
156
164
|
},
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
},
|
|
162
|
-
...onNodeClick && {
|
|
163
|
-
onPointerClick: (e) => {
|
|
164
|
-
if (DiagramGesture.isDragging || e.evt.button !== 0) {
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
e.cancelBubble = true;
|
|
168
|
-
onNodeClick(node, e);
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
x: springs.x,
|
|
172
|
-
y: springs.y,
|
|
173
|
-
offsetX: springs.offsetX,
|
|
174
|
-
offsetY: springs.offsetY,
|
|
175
|
-
width: springs.width,
|
|
176
|
-
height: springs.height,
|
|
177
|
-
scaleX: springs.scaleX,
|
|
178
|
-
scaleY: springs.scaleY,
|
|
179
|
-
opacity: springs.opacity,
|
|
180
|
-
children: [
|
|
181
|
-
_isCompound && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
182
|
-
/* @__PURE__ */ jsx(
|
|
183
|
-
CompoundShape,
|
|
184
|
-
{
|
|
185
|
-
node,
|
|
186
|
-
theme,
|
|
187
|
-
springs,
|
|
188
|
-
labelOffsetX: isNavigatable ? -12 : 4
|
|
165
|
+
...onNodeClick && {
|
|
166
|
+
onPointerClick: (e) => {
|
|
167
|
+
if (DiagramGesture.isDragging || e.evt.button !== 0) {
|
|
168
|
+
return;
|
|
189
169
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
170
|
+
e.cancelBubble = true;
|
|
171
|
+
onNodeClick(node, e);
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
x: springs.x,
|
|
175
|
+
y: springs.y,
|
|
176
|
+
offsetX: springs.offsetX,
|
|
177
|
+
offsetY: springs.offsetY,
|
|
178
|
+
width: springs.width,
|
|
179
|
+
height: springs.height,
|
|
180
|
+
scaleX: springs.scaleX,
|
|
181
|
+
scaleY: springs.scaleY,
|
|
182
|
+
opacity: springs.opacity,
|
|
183
|
+
children: [
|
|
184
|
+
_isCompound && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
185
|
+
/* @__PURE__ */ jsx(
|
|
186
|
+
CompoundShape,
|
|
187
|
+
{
|
|
188
|
+
node,
|
|
189
|
+
theme,
|
|
190
|
+
springs,
|
|
191
|
+
labelOffsetX: isNavigatable ? -18 : 0
|
|
192
|
+
}
|
|
193
|
+
),
|
|
194
|
+
isNavigatable && /* @__PURE__ */ jsx(ZoomInIcon, { opacity: 0.9, size: 18, x: 18, y: 22 })
|
|
195
|
+
] }),
|
|
196
|
+
!_isCompound && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
197
|
+
/* @__PURE__ */ jsx(Shape, { node, theme, springs, isHovered }),
|
|
198
|
+
isNavigatable && /* @__PURE__ */ jsx(ZoomInIcon, { size: 16, x: node.size.width / 2, y: zoomInIconY })
|
|
199
|
+
] })
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
) });
|
|
203
|
+
},
|
|
204
|
+
isEqualSimple
|
|
205
|
+
);
|
|
206
|
+
NodeShape.displayName = "NodeShape";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Path } from "../../konva.js";
|
|
3
|
-
export const ZoomInIcon = ({ fill, opacity = 1, size = 20, x, y }) => {
|
|
3
|
+
export const ZoomInIcon = ({ fill = "#BABABA", opacity = 1, size = 20, x, y }) => {
|
|
4
4
|
const originalSize = 15;
|
|
5
5
|
const scale = size / originalSize;
|
|
6
6
|
const offsetIcon = originalSize / 2;
|
|
@@ -20,8 +20,7 @@ export const ZoomInIcon = ({ fill, opacity = 1, size = 20, x, y }) => {
|
|
|
20
20
|
width: originalSize,
|
|
21
21
|
height: originalSize,
|
|
22
22
|
opacity,
|
|
23
|
-
globalCompositeOperation: "luminosity"
|
|
24
|
-
hitStrokeWidth: 5
|
|
23
|
+
globalCompositeOperation: "luminosity"
|
|
25
24
|
}
|
|
26
25
|
);
|
|
27
26
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { AnimatedCircle, AnimatedRect } from "../../konva.js";
|
|
2
3
|
import { useShadowSprings } from "../springs.js";
|
|
3
|
-
import {
|
|
4
|
+
import { NodeIcon } from "./NodeIcon.js";
|
|
4
5
|
import { NodeLabels } from "./NodeLabel.js";
|
|
5
6
|
export function BrowserShape({ node, theme, springs, isHovered }) {
|
|
6
|
-
const colors = theme.elements[node.color];
|
|
7
7
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8
8
|
/* @__PURE__ */ jsx(
|
|
9
9
|
AnimatedRect,
|
|
@@ -13,12 +13,43 @@ export function BrowserShape({ node, theme, springs, isHovered }) {
|
|
|
13
13
|
strokeEnabled: false,
|
|
14
14
|
width: springs.width,
|
|
15
15
|
height: springs.height,
|
|
16
|
-
fill: springs.stroke
|
|
16
|
+
fill: springs.stroke,
|
|
17
|
+
perfectDrawEnabled: false
|
|
18
|
+
}
|
|
19
|
+
),
|
|
20
|
+
/* @__PURE__ */ jsx(
|
|
21
|
+
AnimatedCircle,
|
|
22
|
+
{
|
|
23
|
+
x: 16,
|
|
24
|
+
y: 15,
|
|
25
|
+
radius: 7,
|
|
26
|
+
fill: springs.fill,
|
|
27
|
+
listening: false,
|
|
28
|
+
perfectDrawEnabled: false
|
|
29
|
+
}
|
|
30
|
+
),
|
|
31
|
+
/* @__PURE__ */ jsx(
|
|
32
|
+
AnimatedCircle,
|
|
33
|
+
{
|
|
34
|
+
x: 36,
|
|
35
|
+
y: 15,
|
|
36
|
+
radius: 7,
|
|
37
|
+
fill: springs.fill,
|
|
38
|
+
listening: false,
|
|
39
|
+
perfectDrawEnabled: false
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
/* @__PURE__ */ jsx(
|
|
43
|
+
AnimatedCircle,
|
|
44
|
+
{
|
|
45
|
+
x: 56,
|
|
46
|
+
y: 15,
|
|
47
|
+
radius: 7,
|
|
48
|
+
fill: springs.fill,
|
|
49
|
+
listening: false,
|
|
50
|
+
perfectDrawEnabled: false
|
|
17
51
|
}
|
|
18
52
|
),
|
|
19
|
-
/* @__PURE__ */ jsx(Circle, { x: 16, y: 15, radius: 7, fill: colors.fill, listening: false }),
|
|
20
|
-
/* @__PURE__ */ jsx(Circle, { x: 36, y: 15, radius: 7, fill: colors.fill, listening: false }),
|
|
21
|
-
/* @__PURE__ */ jsx(Circle, { x: 56, y: 15, radius: 7, fill: colors.fill, listening: false }),
|
|
22
53
|
/* @__PURE__ */ jsx(
|
|
23
54
|
AnimatedRect,
|
|
24
55
|
{
|
|
@@ -28,7 +59,8 @@ export function BrowserShape({ node, theme, springs, isHovered }) {
|
|
|
28
59
|
width: springs.width.to((w) => w - 80),
|
|
29
60
|
height: 16,
|
|
30
61
|
fill: springs.fill,
|
|
31
|
-
listening: false
|
|
62
|
+
listening: false,
|
|
63
|
+
perfectDrawEnabled: false
|
|
32
64
|
}
|
|
33
65
|
),
|
|
34
66
|
/* @__PURE__ */ jsx(
|
|
@@ -40,9 +72,11 @@ export function BrowserShape({ node, theme, springs, isHovered }) {
|
|
|
40
72
|
width: springs.width.to((w) => w - 18),
|
|
41
73
|
height: springs.height.to((h) => h - 40),
|
|
42
74
|
fill: springs.fill,
|
|
43
|
-
listening: false
|
|
75
|
+
listening: false,
|
|
76
|
+
perfectDrawEnabled: false
|
|
44
77
|
}
|
|
45
78
|
),
|
|
46
|
-
/* @__PURE__ */ jsx(NodeLabels, { node, theme, offsetY: -
|
|
79
|
+
/* @__PURE__ */ jsx(NodeLabels, { node, theme, offsetY: -6 }),
|
|
80
|
+
/* @__PURE__ */ jsx(NodeIcon, { node, paddingY: 42 })
|
|
47
81
|
] });
|
|
48
82
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { AnimatedRect,
|
|
3
|
-
export function CompoundShape({ node, theme, springs, labelOffsetX =
|
|
2
|
+
import { AnimatedRect, Text } from "../../konva.js";
|
|
3
|
+
export function CompoundShape({ node, theme, springs, labelOffsetX = 0 }) {
|
|
4
4
|
const { labels } = node;
|
|
5
5
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6
6
|
/* @__PURE__ */ jsx(
|
|
@@ -21,25 +21,23 @@ export function CompoundShape({ node, theme, springs, labelOffsetX = 4 }) {
|
|
|
21
21
|
}
|
|
22
22
|
),
|
|
23
23
|
labels.map(({ pt: [x, y], ...label }, i) => /* @__PURE__ */ jsx(
|
|
24
|
-
|
|
24
|
+
Text,
|
|
25
25
|
{
|
|
26
|
-
x,
|
|
27
|
-
y: y -
|
|
26
|
+
x: x - 6,
|
|
27
|
+
y: y - 8,
|
|
28
28
|
offsetX: labelOffsetX,
|
|
29
|
-
|
|
30
|
-
width: springs.width.to((v) => v - x - 4),
|
|
29
|
+
width: node.size.width - x - 8 - 6 + labelOffsetX,
|
|
31
30
|
fill: "#BABABA",
|
|
32
31
|
fontFamily: theme.font,
|
|
33
32
|
fontSize: label.fontSize,
|
|
34
33
|
fontStyle: label.fontStyle ?? "normal",
|
|
35
|
-
letterSpacing: 0.
|
|
34
|
+
letterSpacing: 0.75,
|
|
36
35
|
align: label.align,
|
|
37
36
|
text: label.text,
|
|
38
37
|
wrap: "none",
|
|
39
38
|
ellipsis: true,
|
|
40
39
|
perfectDrawEnabled: false,
|
|
41
|
-
padding:
|
|
42
|
-
hitStrokeWidth: 3,
|
|
40
|
+
padding: 8,
|
|
43
41
|
globalCompositeOperation: "luminosity"
|
|
44
42
|
},
|
|
45
43
|
i
|
|
@@ -3,6 +3,7 @@ import { useSpring } from "@react-spring/konva";
|
|
|
3
3
|
import { AnimatedEllipse, AnimatedPath } from "../../konva.js";
|
|
4
4
|
import { NodeLabels } from "./NodeLabel.js";
|
|
5
5
|
import { useShadowSprings } from "../springs.js";
|
|
6
|
+
import { NodeIcon } from "./NodeIcon.js";
|
|
6
7
|
function cylinderSVGPath(diameter, height, tilt = 0.0825) {
|
|
7
8
|
const radius = Math.round(diameter / 2);
|
|
8
9
|
const rx = radius;
|
|
@@ -51,6 +52,7 @@ export function CylinderShape({ node, theme, springs, isHovered }) {
|
|
|
51
52
|
fill: springs.stroke
|
|
52
53
|
}
|
|
53
54
|
),
|
|
54
|
-
/* @__PURE__ */ jsx(NodeLabels, { node, offsetY: -ry * (node.icon ? 1
|
|
55
|
+
/* @__PURE__ */ jsx(NodeLabels, { node, offsetY: -4 - ry * (node.icon ? 1 : 0), theme }),
|
|
56
|
+
/* @__PURE__ */ jsx(NodeIcon, { node, paddingY: ry + 4, offsetY: -ry - 8 })
|
|
55
57
|
] });
|
|
56
58
|
}
|
|
@@ -16,7 +16,6 @@ function EdgeArrow({
|
|
|
16
16
|
return /* @__PURE__ */ jsx(
|
|
17
17
|
AnimatedLine,
|
|
18
18
|
{
|
|
19
|
-
opacity: springs.opacity,
|
|
20
19
|
points: points.flat(),
|
|
21
20
|
closed: true,
|
|
22
21
|
fill: isOutline ? void 0 : springs.lineColor,
|
|
@@ -25,6 +24,7 @@ function EdgeArrow({
|
|
|
25
24
|
hitStrokeWidth: 5,
|
|
26
25
|
lineCap: "round",
|
|
27
26
|
lineJoin: "miter",
|
|
27
|
+
perfectDrawEnabled: false,
|
|
28
28
|
globalCompositeOperation
|
|
29
29
|
}
|
|
30
30
|
);
|
|
@@ -42,7 +42,7 @@ function EdgeLabelBg({
|
|
|
42
42
|
y: labelBBox.y - padding,
|
|
43
43
|
width: labelBBox.width + padding * 2,
|
|
44
44
|
height: labelBBox.height + padding * 2,
|
|
45
|
-
opacity: isHovered ? 0.
|
|
45
|
+
opacity: isHovered ? 0.5 : 0.12
|
|
46
46
|
},
|
|
47
47
|
immediate: !animate
|
|
48
48
|
});
|
|
@@ -50,6 +50,7 @@ function EdgeLabelBg({
|
|
|
50
50
|
AnimatedRect,
|
|
51
51
|
{
|
|
52
52
|
...props,
|
|
53
|
+
perfectDrawEnabled: false,
|
|
53
54
|
fill: springs.labelBgColor,
|
|
54
55
|
cornerRadius: 2,
|
|
55
56
|
globalCompositeOperation: "darken",
|
|
@@ -57,7 +58,7 @@ function EdgeLabelBg({
|
|
|
57
58
|
}
|
|
58
59
|
);
|
|
59
60
|
}
|
|
60
|
-
export function
|
|
61
|
+
export function Edge({ animate = true, edge, theme, isHovered, springs }) {
|
|
61
62
|
const {
|
|
62
63
|
points,
|
|
63
64
|
head,
|
|
@@ -82,7 +83,6 @@ export function EdgeShape({ animate = true, edge, theme, isHovered, springs }) {
|
|
|
82
83
|
/* @__PURE__ */ jsx(
|
|
83
84
|
AnimatedLine,
|
|
84
85
|
{
|
|
85
|
-
opacity: springs.opacity,
|
|
86
86
|
bezier: true,
|
|
87
87
|
dashEnabled: isDashed,
|
|
88
88
|
dashOffset: 1,
|
|
@@ -93,6 +93,7 @@ export function EdgeShape({ animate = true, edge, theme, isHovered, springs }) {
|
|
|
93
93
|
hitStrokeWidth: 20,
|
|
94
94
|
lineCap: "round",
|
|
95
95
|
lineJoin: "round",
|
|
96
|
+
perfectDrawEnabled: false,
|
|
96
97
|
globalCompositeOperation
|
|
97
98
|
}
|
|
98
99
|
),
|
|
@@ -129,14 +130,13 @@ export function EdgeShape({ animate = true, edge, theme, isHovered, springs }) {
|
|
|
129
130
|
AnimatedText,
|
|
130
131
|
{
|
|
131
132
|
x: label.pt[0],
|
|
132
|
-
y: label.pt[1],
|
|
133
|
-
offsetY: label.fontSize / 2,
|
|
134
|
-
opacity: springs.opacity,
|
|
133
|
+
y: label.pt[1] - label.fontSize,
|
|
135
134
|
fill: springs.labelColor,
|
|
136
135
|
fontFamily: theme.font,
|
|
137
136
|
fontSize: label.fontSize,
|
|
138
137
|
fontStyle: label.fontStyle ?? "normal",
|
|
139
138
|
text: label.text,
|
|
139
|
+
perfectDrawEnabled: false,
|
|
140
140
|
listening: false,
|
|
141
141
|
globalCompositeOperation,
|
|
142
142
|
shadowEnabled: springs.opacity.to((o) => o > 0.5),
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { AnimatedCircle, AnimatedRect } from "../../konva.js";
|
|
3
3
|
import { NodeLabels } from "./NodeLabel.js";
|
|
4
4
|
import { useShadowSprings } from "../springs.js";
|
|
5
|
+
import { NodeIcon } from "./NodeIcon.js";
|
|
5
6
|
export function MobileShape({ node, theme, springs, isHovered }) {
|
|
6
7
|
const colors = theme.elements[node.color];
|
|
8
|
+
const maxWidth = node.size.width - 40 - 30;
|
|
7
9
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8
10
|
/* @__PURE__ */ jsx(
|
|
9
11
|
AnimatedRect,
|
|
@@ -12,10 +14,21 @@ export function MobileShape({ node, theme, springs, isHovered }) {
|
|
|
12
14
|
cornerRadius: 6,
|
|
13
15
|
width: springs.width,
|
|
14
16
|
height: springs.height,
|
|
15
|
-
fill: springs.stroke
|
|
17
|
+
fill: springs.stroke,
|
|
18
|
+
perfectDrawEnabled: false
|
|
19
|
+
}
|
|
20
|
+
),
|
|
21
|
+
/* @__PURE__ */ jsx(
|
|
22
|
+
AnimatedCircle,
|
|
23
|
+
{
|
|
24
|
+
x: 16,
|
|
25
|
+
y: node.size.height / 2,
|
|
26
|
+
radius: 10,
|
|
27
|
+
fill: springs.fill,
|
|
28
|
+
listening: false,
|
|
29
|
+
perfectDrawEnabled: false
|
|
16
30
|
}
|
|
17
31
|
),
|
|
18
|
-
/* @__PURE__ */ jsx(Circle, { x: 16, y: node.size.height / 2, radius: 10, fill: colors.fill, listening: false }),
|
|
19
32
|
/* @__PURE__ */ jsx(
|
|
20
33
|
AnimatedRect,
|
|
21
34
|
{
|
|
@@ -25,9 +38,11 @@ export function MobileShape({ node, theme, springs, isHovered }) {
|
|
|
25
38
|
width: springs.width.to((w) => w - 43),
|
|
26
39
|
height: springs.height.to((h) => h - 24),
|
|
27
40
|
fill: springs.fill,
|
|
41
|
+
perfectDrawEnabled: false,
|
|
28
42
|
listening: false
|
|
29
43
|
}
|
|
30
44
|
),
|
|
31
|
-
/* @__PURE__ */ jsx(NodeLabels, { node, theme, offsetX: -
|
|
45
|
+
/* @__PURE__ */ jsx(NodeLabels, { node, theme, offsetX: -10, maxWidth }),
|
|
46
|
+
/* @__PURE__ */ jsx(NodeIcon, { node, offsetX: -10, maxWidth })
|
|
32
47
|
] });
|
|
33
48
|
}
|