@likec4/diagram 1.1.0 → 1.1.1
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/LikeC4Diagram.d.ts +1 -1
- package/dist/LikeC4Diagram.props.d.ts +16 -11
- package/dist/index.mjs +413 -101
- package/dist/state/DiagramContext.d.ts +18 -9
- package/dist/state/diagramStore.d.ts +19 -9
- package/dist/state/useDiagramStore.d.ts +18 -9
- package/dist/style.css +99 -35
- package/dist/ui/DiagramTitlePanel.css.d.ts +4 -0
- package/dist/ui/DiagramTitlePanel.d.ts +2 -0
- package/dist/ui/OptionsPanel.d.ts +1 -2
- package/dist/xyflow/SelectEdgesOnNodeFocus.d.ts +1 -0
- package/dist/xyflow/XYFlowEvents.d.ts +46 -40
- package/dist/xyflow/edges/edges.css.d.ts +1 -0
- package/package.json +4 -2
- package/src/LikeC4Diagram.css.ts +2 -1
- package/src/LikeC4Diagram.props.ts +17 -12
- package/src/LikeC4Diagram.tsx +3 -0
- package/src/StaticLikeC4Diagram.tsx +1 -0
- package/src/globals.css.ts +6 -1
- package/src/state/diagramStore.ts +101 -63
- package/src/ui/DiagramTitlePanel.css.ts +32 -0
- package/src/ui/DiagramTitlePanel.tsx +139 -0
- package/src/ui/OptionsPanel.tsx +4 -23
- package/src/ui/options/NodeOptions.tsx +107 -30
- package/src/xyflow/FitviewOnDiagramChange.tsx +2 -2
- package/src/xyflow/SelectEdgesOnNodeFocus.tsx +57 -0
- package/src/xyflow/SyncWithDiagram.tsx +12 -6
- package/src/xyflow/XYFlow.tsx +7 -3
- package/src/xyflow/XYFlowEvents.tsx +145 -104
- package/src/xyflow/edges/RelationshipEdge.tsx +43 -47
- package/src/xyflow/edges/edges.css.ts +77 -36
- package/src/xyflow/nodes/compound/CompoundNode.css.ts +17 -13
- package/src/xyflow/nodes/element/element.css.ts +1 -0
package/dist/index.mjs
CHANGED
|
@@ -2,18 +2,20 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => (__defNormalProp(obj, typeof key != "symbol" ? key + "" : key, value), value);
|
|
4
4
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
5
|
-
import { createContext, memo, useState,
|
|
5
|
+
import { createContext, memo, useState, useEffect, useContext, useMemo, forwardRef, useCallback, useRef, useLayoutEffect, useId } from "react";
|
|
6
6
|
import { createWithEqualityFn, useStoreWithEqualityFn } from "zustand/traditional";
|
|
7
7
|
import { shallow } from "zustand/shallow";
|
|
8
8
|
import { createPortal } from "react-dom";
|
|
9
|
-
import { Box, MantineContext, Stack, Text,
|
|
9
|
+
import { Box, MantineContext, Paper, Stack, Group, Text, Spoiler, Button, Anchor, CopyButton, Divider, TooltipGroup, Flex, Tooltip, ColorSwatch, CheckIcon, rem, Select, Slider, SegmentedControl, Card, ActionIcon, HoverCard, HoverCardTarget, UnstyledButton, HoverCardDropdown, useMantineColorScheme } from "@mantine/core";
|
|
10
10
|
import { invariant, isAncestor, nonNullable, nonexhaustive, defaultTheme, ElementShapes } from "@likec4/core";
|
|
11
11
|
import { DEV } from "esm-env";
|
|
12
12
|
import { shallowEqual, deepEqual } from "fast-equals";
|
|
13
|
+
import { isNullish, entries, keys, hasAtLeast, takeWhile, clamp as clamp$1, isNumber } from "remeda";
|
|
13
14
|
import { subscribeWithSelector, devtools } from "zustand/middleware";
|
|
14
15
|
import { useFirstMountState, useCustomCompareEffect, useDebouncedCallback, useRafEffect, useDebouncedEffect } from "@react-hookz/web";
|
|
15
16
|
import { AnimatePresence, motion } from "framer-motion";
|
|
16
|
-
import {
|
|
17
|
+
import { useLocalStorage } from "@mantine/hooks";
|
|
18
|
+
import { line, curveCatmullRomOpen } from "d3-shape";
|
|
17
19
|
var rootClassName = "likec4-diagram-root";
|
|
18
20
|
function cc(names) {
|
|
19
21
|
if (typeof names == "string" || typeof names == "number")
|
|
@@ -4669,9 +4671,9 @@ function useVisibleNodeIds(onlyRenderVisible) {
|
|
|
4669
4671
|
}
|
|
4670
4672
|
const selector$e = (s) => s.updateNodeInternals;
|
|
4671
4673
|
function useResizeObserver() {
|
|
4672
|
-
const updateNodeInternals2 = useStore(selector$e), [resizeObserver] = useState(() => typeof ResizeObserver > "u" ? null : new ResizeObserver((
|
|
4674
|
+
const updateNodeInternals2 = useStore(selector$e), [resizeObserver] = useState(() => typeof ResizeObserver > "u" ? null : new ResizeObserver((entries2) => {
|
|
4673
4675
|
const updates = /* @__PURE__ */ new Map();
|
|
4674
|
-
|
|
4676
|
+
entries2.forEach((entry) => {
|
|
4675
4677
|
const id2 = entry.target.getAttribute("data-id");
|
|
4676
4678
|
updates.set(id2, {
|
|
4677
4679
|
id: id2,
|
|
@@ -5645,7 +5647,7 @@ function NodeComponentWrapperInner({ id: id2, nodeOrigin, nodeColorFunc, nodeStr
|
|
|
5645
5647
|
}
|
|
5646
5648
|
const NodeComponentWrapper = memo(NodeComponentWrapperInner);
|
|
5647
5649
|
var MiniMapNodes$1 = memo(MiniMapNodes);
|
|
5648
|
-
const defaultWidth = 200, defaultHeight = 150, selector$1 = (s) => {
|
|
5650
|
+
const defaultWidth = 200, defaultHeight = 150, selector$1$1 = (s) => {
|
|
5649
5651
|
const viewBB = {
|
|
5650
5652
|
x: -s.transform[0] / s.transform[2],
|
|
5651
5653
|
y: -s.transform[1] / s.transform[2],
|
|
@@ -5688,7 +5690,7 @@ function MiniMapComponent({
|
|
|
5688
5690
|
zoomStep = 10,
|
|
5689
5691
|
offsetScale = 5
|
|
5690
5692
|
}) {
|
|
5691
|
-
const store = useStoreApi(), svg = useRef(null), { boundingRect, viewBB, rfId, panZoom, translateExtent, flowWidth, flowHeight } = useStore(selector$1, shallow), elementWidth = (style2 == null ? void 0 : style2.width) ?? defaultWidth, elementHeight = (style2 == null ? void 0 : style2.height) ?? defaultHeight, scaledWidth = boundingRect.width / elementWidth, scaledHeight = boundingRect.height / elementHeight, viewScale = Math.max(scaledWidth, scaledHeight), viewWidth = viewScale * elementWidth, viewHeight = viewScale * elementHeight, offset = offsetScale * viewScale, x = boundingRect.x - (viewWidth - boundingRect.width) / 2 - offset, y = boundingRect.y - (viewHeight - boundingRect.height) / 2 - offset, width = viewWidth + offset * 2, height = viewHeight + offset * 2, labelledBy = `${ARIA_LABEL_KEY}-${rfId}`, viewScaleRef = useRef(0), minimapInstance = useRef();
|
|
5693
|
+
const store = useStoreApi(), svg = useRef(null), { boundingRect, viewBB, rfId, panZoom, translateExtent, flowWidth, flowHeight } = useStore(selector$1$1, shallow), elementWidth = (style2 == null ? void 0 : style2.width) ?? defaultWidth, elementHeight = (style2 == null ? void 0 : style2.height) ?? defaultHeight, scaledWidth = boundingRect.width / elementWidth, scaledHeight = boundingRect.height / elementHeight, viewScale = Math.max(scaledWidth, scaledHeight), viewWidth = viewScale * elementWidth, viewHeight = viewScale * elementHeight, offset = offsetScale * viewScale, x = boundingRect.x - (viewWidth - boundingRect.width) / 2 - offset, y = boundingRect.y - (viewHeight - boundingRect.height) / 2 - offset, width = viewWidth + offset * 2, height = viewHeight + offset * 2, labelledBy = `${ARIA_LABEL_KEY}-${rfId}`, viewScaleRef = useRef(0), minimapInstance = useRef();
|
|
5692
5694
|
viewScaleRef.current = viewScale, useEffect(() => {
|
|
5693
5695
|
if (svg.current && panZoom)
|
|
5694
5696
|
return minimapInstance.current = XYMinimap({
|
|
@@ -7294,51 +7296,87 @@ function createDiagramStore(props) {
|
|
|
7294
7296
|
setLastClickedEdge: (edgeId) => {
|
|
7295
7297
|
edgeId !== get2().lastClickedEdgeId && set2({ lastClickedEdgeId: edgeId }, noReplace, edgeId ? "setLastClickedEdge" : "unsetLastClickedEdge");
|
|
7296
7298
|
},
|
|
7299
|
+
resetLastClicked: () => {
|
|
7300
|
+
let {
|
|
7301
|
+
focusedNodeId,
|
|
7302
|
+
lastClickedNodeId,
|
|
7303
|
+
lastClickedEdgeId
|
|
7304
|
+
} = get2();
|
|
7305
|
+
(focusedNodeId || lastClickedNodeId || lastClickedEdgeId) && set2(
|
|
7306
|
+
{
|
|
7307
|
+
focusedNodeId: null,
|
|
7308
|
+
lastClickedNodeId: null,
|
|
7309
|
+
lastClickedEdgeId: null
|
|
7310
|
+
},
|
|
7311
|
+
noReplace,
|
|
7312
|
+
"resetLastClicked"
|
|
7313
|
+
);
|
|
7314
|
+
},
|
|
7297
7315
|
getElement: (fqn) => {
|
|
7298
7316
|
const { view } = get2();
|
|
7299
7317
|
return view.nodes.find(({ id: id2 }) => id2 === fqn) ?? null;
|
|
7300
7318
|
},
|
|
7301
7319
|
triggerOnChange: (changes) => {
|
|
7302
7320
|
var _a, _b;
|
|
7303
|
-
|
|
7321
|
+
DEV && console.debug("triggerOnChange", changes);
|
|
7322
|
+
const newShapes = /* @__PURE__ */ new Map(), newColor = /* @__PURE__ */ new Map(), newOpacity = /* @__PURE__ */ new Map(), newBorder = /* @__PURE__ */ new Map();
|
|
7304
7323
|
for (const change of changes) {
|
|
7305
|
-
|
|
7306
|
-
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7324
|
+
change.op !== "change-element-style" && nonexhaustive(change.op);
|
|
7325
|
+
for (const target of change.targets)
|
|
7326
|
+
for (const [key, value] of entries.strict(change.style))
|
|
7327
|
+
switch (key) {
|
|
7328
|
+
case "shape":
|
|
7329
|
+
newShapes.set(target, value);
|
|
7330
|
+
break;
|
|
7331
|
+
case "color":
|
|
7332
|
+
newColor.set(target, value);
|
|
7333
|
+
break;
|
|
7334
|
+
case "opacity":
|
|
7335
|
+
newOpacity.set(target, value);
|
|
7336
|
+
break;
|
|
7337
|
+
case "border":
|
|
7338
|
+
newBorder.set(target, value);
|
|
7339
|
+
break;
|
|
7340
|
+
default:
|
|
7341
|
+
nonexhaustive(key);
|
|
7342
|
+
}
|
|
7316
7343
|
}
|
|
7317
7344
|
get2().xyflow.setNodes(
|
|
7318
7345
|
(nodes) => nodes.map((node) => {
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7346
|
+
var _a2, _b2;
|
|
7347
|
+
let element = node.data.element;
|
|
7348
|
+
const shape = newShapes.get(element.id);
|
|
7349
|
+
shape && shape !== element.shape && (element = {
|
|
7350
|
+
...element,
|
|
7351
|
+
shape
|
|
7352
|
+
});
|
|
7353
|
+
const color2 = newColor.get(element.id);
|
|
7354
|
+
color2 && color2 !== element.color && (element = {
|
|
7355
|
+
...element,
|
|
7356
|
+
color: color2
|
|
7357
|
+
});
|
|
7358
|
+
const opacity = newOpacity.get(element.id);
|
|
7359
|
+
opacity && opacity !== ((_a2 = element.style) == null ? void 0 : _a2.opacity) && (element = {
|
|
7360
|
+
...element,
|
|
7361
|
+
style: {
|
|
7362
|
+
...element.style,
|
|
7363
|
+
opacity
|
|
7329
7364
|
}
|
|
7330
|
-
}
|
|
7331
|
-
const
|
|
7332
|
-
return
|
|
7365
|
+
});
|
|
7366
|
+
const border = newBorder.get(element.id);
|
|
7367
|
+
return border && border !== ((_b2 = element.style) == null ? void 0 : _b2.border) && (element = {
|
|
7368
|
+
...element,
|
|
7369
|
+
style: {
|
|
7370
|
+
...element.style,
|
|
7371
|
+
border
|
|
7372
|
+
}
|
|
7373
|
+
}), element === node.data.element ? node : {
|
|
7333
7374
|
...node,
|
|
7334
7375
|
data: {
|
|
7335
|
-
...data,
|
|
7336
|
-
element
|
|
7337
|
-
...data.element,
|
|
7338
|
-
color: color2
|
|
7339
|
-
}
|
|
7376
|
+
...node.data,
|
|
7377
|
+
element
|
|
7340
7378
|
}
|
|
7341
|
-
}
|
|
7379
|
+
};
|
|
7342
7380
|
})
|
|
7343
7381
|
), (_b = (_a = get2()).onChange) == null || _b.call(_a, { changes });
|
|
7344
7382
|
},
|
|
@@ -7376,7 +7414,7 @@ function createDiagramStore(props) {
|
|
|
7376
7414
|
xyflow.fitView({
|
|
7377
7415
|
includeHiddenNodes: !0,
|
|
7378
7416
|
duration: centerNode && focusedNodeId ? 300 : 400,
|
|
7379
|
-
padding:
|
|
7417
|
+
padding: fitViewPadding,
|
|
7380
7418
|
minZoom: MinZoom,
|
|
7381
7419
|
maxZoom: 1,
|
|
7382
7420
|
...centerNode && { nodes: [centerNode] }
|
|
@@ -7420,6 +7458,146 @@ function DiagramContextProvider({ children: children2, view, ...props }) {
|
|
|
7420
7458
|
[props]
|
|
7421
7459
|
), /* @__PURE__ */ jsx(DiagramContext.Provider, { value: store.current, children: children2 });
|
|
7422
7460
|
}
|
|
7461
|
+
var container$3 = "hbkbtj0", paper = "hbkbtj1", title$2 = "hbkbtj2", description$1 = "hbkbtj3";
|
|
7462
|
+
const selector$1 = (s) => ({
|
|
7463
|
+
id: s.view.id,
|
|
7464
|
+
title: s.view.title ?? "untitled",
|
|
7465
|
+
description: s.view.description,
|
|
7466
|
+
links: s.view.links
|
|
7467
|
+
});
|
|
7468
|
+
function DiagramTitlePanel() {
|
|
7469
|
+
const { id: id2, title: title2, description: description2, links } = useDiagramState(selector$1), [isCollapsed, setCollapsed] = useLocalStorage({
|
|
7470
|
+
key: "diagram-title-panel-collapsed",
|
|
7471
|
+
defaultValue: !1
|
|
7472
|
+
}), toggle = () => setCollapsed((v) => !v);
|
|
7473
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsx(
|
|
7474
|
+
motion.div,
|
|
7475
|
+
{
|
|
7476
|
+
initial: { opacity: 0.05, scale: 0.7 },
|
|
7477
|
+
animate: { opacity: 1, scale: 1 },
|
|
7478
|
+
exit: {
|
|
7479
|
+
opacity: 0.05,
|
|
7480
|
+
scale: 0.6
|
|
7481
|
+
},
|
|
7482
|
+
className: clsx("react-flow__panel", container$3),
|
|
7483
|
+
style: {
|
|
7484
|
+
transformOrigin: "left center"
|
|
7485
|
+
},
|
|
7486
|
+
children: /* @__PURE__ */ jsx(
|
|
7487
|
+
Paper,
|
|
7488
|
+
{
|
|
7489
|
+
radius: "sm",
|
|
7490
|
+
withBorder: !isCollapsed,
|
|
7491
|
+
className: paper,
|
|
7492
|
+
p: isCollapsed ? "sm" : "md",
|
|
7493
|
+
onDoubleClick: (e) => e.stopPropagation(),
|
|
7494
|
+
children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", justify: "stretch", align: "stretch", children: [
|
|
7495
|
+
/* @__PURE__ */ jsxs(Group, { justify: "stretch", wrap: "nowrap", onClick: toggle, style: { cursor: "pointer" }, children: [
|
|
7496
|
+
/* @__PURE__ */ jsx(
|
|
7497
|
+
Text,
|
|
7498
|
+
{
|
|
7499
|
+
component: "div",
|
|
7500
|
+
flex: "1",
|
|
7501
|
+
size: isCollapsed ? "sm" : "lg",
|
|
7502
|
+
fw: 500,
|
|
7503
|
+
lh: 1.1,
|
|
7504
|
+
className: title$2,
|
|
7505
|
+
children: title2
|
|
7506
|
+
}
|
|
7507
|
+
),
|
|
7508
|
+
/* @__PURE__ */ jsxs(
|
|
7509
|
+
Text,
|
|
7510
|
+
{
|
|
7511
|
+
hidden: isCollapsed,
|
|
7512
|
+
component: "div",
|
|
7513
|
+
flex: "0 0 auto",
|
|
7514
|
+
inline: !0,
|
|
7515
|
+
size: "xs",
|
|
7516
|
+
fz: 9,
|
|
7517
|
+
fw: 500,
|
|
7518
|
+
c: "dimmed",
|
|
7519
|
+
style: {
|
|
7520
|
+
userSelect: "all"
|
|
7521
|
+
},
|
|
7522
|
+
children: [
|
|
7523
|
+
/* @__PURE__ */ jsxs("span", { style: { userSelect: "none" }, children: [
|
|
7524
|
+
"id:",
|
|
7525
|
+
" "
|
|
7526
|
+
] }),
|
|
7527
|
+
id2
|
|
7528
|
+
]
|
|
7529
|
+
}
|
|
7530
|
+
)
|
|
7531
|
+
] }),
|
|
7532
|
+
!isCollapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7533
|
+
description2 && /* @__PURE__ */ jsx(
|
|
7534
|
+
Spoiler,
|
|
7535
|
+
{
|
|
7536
|
+
maxHeight: 42,
|
|
7537
|
+
showLabel: /* @__PURE__ */ jsx(Button, { color: "gray", variant: "light", fz: "10", size: "compact-xs", children: "show more" }),
|
|
7538
|
+
hideLabel: /* @__PURE__ */ jsx(Button, { color: "gray", variant: "light", fz: "10", size: "compact-xs", children: "hide" }),
|
|
7539
|
+
children: /* @__PURE__ */ jsx(
|
|
7540
|
+
Text,
|
|
7541
|
+
{
|
|
7542
|
+
component: "div",
|
|
7543
|
+
size: "sm",
|
|
7544
|
+
className: description$1,
|
|
7545
|
+
children: description2 || "no description"
|
|
7546
|
+
}
|
|
7547
|
+
)
|
|
7548
|
+
}
|
|
7549
|
+
),
|
|
7550
|
+
!description2 && /* @__PURE__ */ jsx(
|
|
7551
|
+
Text,
|
|
7552
|
+
{
|
|
7553
|
+
component: "div",
|
|
7554
|
+
size: "xs",
|
|
7555
|
+
c: "dimmed",
|
|
7556
|
+
children: "no description"
|
|
7557
|
+
}
|
|
7558
|
+
),
|
|
7559
|
+
links && /* @__PURE__ */ jsx(
|
|
7560
|
+
Stack,
|
|
7561
|
+
{
|
|
7562
|
+
gap: 3,
|
|
7563
|
+
justify: "stretch",
|
|
7564
|
+
align: "stretch",
|
|
7565
|
+
children: links.map((link) => /* @__PURE__ */ jsxs(Group, { wrap: "nowrap", align: "center", gap: "sm", children: [
|
|
7566
|
+
/* @__PURE__ */ jsx(Box, { flex: "1", style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx(
|
|
7567
|
+
Anchor,
|
|
7568
|
+
{
|
|
7569
|
+
href: link,
|
|
7570
|
+
target: "_blank",
|
|
7571
|
+
fz: "xs",
|
|
7572
|
+
truncate: "end",
|
|
7573
|
+
display: "inline-block",
|
|
7574
|
+
w: "100%",
|
|
7575
|
+
children: link
|
|
7576
|
+
}
|
|
7577
|
+
) }),
|
|
7578
|
+
/* @__PURE__ */ jsx(CopyButton, { value: link, children: ({ copied, copy }) => /* @__PURE__ */ jsx(
|
|
7579
|
+
Button,
|
|
7580
|
+
{
|
|
7581
|
+
size: "compact-xs",
|
|
7582
|
+
fz: "10",
|
|
7583
|
+
variant: "light",
|
|
7584
|
+
onClick: copy,
|
|
7585
|
+
color: copied ? "teal" : "gray",
|
|
7586
|
+
children: copied ? "copied" : "copy"
|
|
7587
|
+
}
|
|
7588
|
+
) })
|
|
7589
|
+
] }, link))
|
|
7590
|
+
}
|
|
7591
|
+
)
|
|
7592
|
+
] })
|
|
7593
|
+
] })
|
|
7594
|
+
}
|
|
7595
|
+
)
|
|
7596
|
+
},
|
|
7597
|
+
id2
|
|
7598
|
+
) });
|
|
7599
|
+
}
|
|
7600
|
+
var panel = "_1lmzt1h0";
|
|
7423
7601
|
const {
|
|
7424
7602
|
primary,
|
|
7425
7603
|
secondary,
|
|
@@ -7437,7 +7615,16 @@ function NodeOptions({ selectedNodeIds }) {
|
|
|
7437
7615
|
const diagramApi = useDiagramStoreApi(), nodes = useXYNodesData(selectedNodeIds);
|
|
7438
7616
|
if (!hasAtLeast(nodes, 1))
|
|
7439
7617
|
return null;
|
|
7440
|
-
|
|
7618
|
+
if (nodes.length !== selectedNodeIds.length)
|
|
7619
|
+
throw new Error("NodeOptions: nodes and props.nodes should have the same length");
|
|
7620
|
+
const showShapeOption = nodes.some((node) => node.type === "element"), [firstNode, ...rest] = nodes, showOpacityOption = rest.length === 0 && firstNode.type === "compound", triggerChange = (style2) => {
|
|
7621
|
+
const targets = nodes.map((node) => node.data.element.id);
|
|
7622
|
+
invariant(hasAtLeast(targets, 1), "At least one target is required"), diagramApi.getState().triggerOnChange([{
|
|
7623
|
+
op: "change-element-style",
|
|
7624
|
+
style: style2,
|
|
7625
|
+
targets
|
|
7626
|
+
}]);
|
|
7627
|
+
};
|
|
7441
7628
|
return /* @__PURE__ */ jsxs(Stack, { children: [
|
|
7442
7629
|
/* @__PURE__ */ jsx(Box, { maw: 200, children: /* @__PURE__ */ jsx(Text, { size: "xs", c: rest.length > 0 ? "dimmed" : "", truncate: !0, children: rest.length === 0 ? firstNode.data.element.title : "[ multiple ]" }) }),
|
|
7443
7630
|
showShapeOption && /* @__PURE__ */ jsx(
|
|
@@ -7445,14 +7632,7 @@ function NodeOptions({ selectedNodeIds }) {
|
|
|
7445
7632
|
{
|
|
7446
7633
|
nodes,
|
|
7447
7634
|
onShapeChange: (shape) => {
|
|
7448
|
-
|
|
7449
|
-
for (const nd of nodes)
|
|
7450
|
-
nd.data.element.shape !== shape && targets.push(nd.data.element.id);
|
|
7451
|
-
hasAtLeast(targets, 1) && diagramApi.getState().triggerOnChange([{
|
|
7452
|
-
op: "change-shape",
|
|
7453
|
-
shape,
|
|
7454
|
-
targets
|
|
7455
|
-
}]);
|
|
7635
|
+
triggerChange({ shape });
|
|
7456
7636
|
}
|
|
7457
7637
|
}
|
|
7458
7638
|
),
|
|
@@ -7461,18 +7641,32 @@ function NodeOptions({ selectedNodeIds }) {
|
|
|
7461
7641
|
{
|
|
7462
7642
|
nodes,
|
|
7463
7643
|
onColorChange: (color2) => {
|
|
7464
|
-
|
|
7465
|
-
for (const nd of nodes)
|
|
7466
|
-
nd.data.element.color !== color2 && targets.push(nd.data.element.id);
|
|
7467
|
-
hasAtLeast(targets, 1) && diagramApi.getState().triggerOnChange([{
|
|
7468
|
-
op: "change-color",
|
|
7469
|
-
color: color2,
|
|
7470
|
-
targets
|
|
7471
|
-
}]);
|
|
7644
|
+
triggerChange({ color: color2 });
|
|
7472
7645
|
}
|
|
7473
7646
|
}
|
|
7474
7647
|
),
|
|
7475
|
-
/* @__PURE__ */ jsx(NavigateToOption, { nodes })
|
|
7648
|
+
/* @__PURE__ */ jsx(NavigateToOption, { nodes }),
|
|
7649
|
+
/* @__PURE__ */ jsx(Box, { children: showOpacityOption && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7650
|
+
/* @__PURE__ */ jsx(Divider, { label: "opacity and border", labelPosition: "left" }),
|
|
7651
|
+
/* @__PURE__ */ jsx(
|
|
7652
|
+
OpacityOption,
|
|
7653
|
+
{
|
|
7654
|
+
node: firstNode,
|
|
7655
|
+
onOpacityChange: (opacity) => {
|
|
7656
|
+
triggerChange({ opacity });
|
|
7657
|
+
}
|
|
7658
|
+
}
|
|
7659
|
+
),
|
|
7660
|
+
/* @__PURE__ */ jsx(
|
|
7661
|
+
BorderStyleOption,
|
|
7662
|
+
{
|
|
7663
|
+
node: firstNode,
|
|
7664
|
+
onChange: (border) => {
|
|
7665
|
+
triggerChange({ border });
|
|
7666
|
+
}
|
|
7667
|
+
}
|
|
7668
|
+
)
|
|
7669
|
+
] }) }, firstNode.id)
|
|
7476
7670
|
] });
|
|
7477
7671
|
}
|
|
7478
7672
|
function Colors({
|
|
@@ -7578,8 +7772,54 @@ function NavigateToOption({
|
|
|
7578
7772
|
)
|
|
7579
7773
|
] });
|
|
7580
7774
|
}
|
|
7581
|
-
|
|
7582
|
-
|
|
7775
|
+
function OpacityOption({
|
|
7776
|
+
node,
|
|
7777
|
+
onOpacityChange
|
|
7778
|
+
}) {
|
|
7779
|
+
let selectedOpacity = node.data.element.style.opacity ?? 100;
|
|
7780
|
+
const [value, setValue] = useState(selectedOpacity);
|
|
7781
|
+
return useEffect(() => {
|
|
7782
|
+
setValue(selectedOpacity);
|
|
7783
|
+
}, [selectedOpacity]), /* @__PURE__ */ jsx(
|
|
7784
|
+
Slider,
|
|
7785
|
+
{
|
|
7786
|
+
mt: "xs",
|
|
7787
|
+
size: "sm",
|
|
7788
|
+
color: "dark",
|
|
7789
|
+
value,
|
|
7790
|
+
onChange: setValue,
|
|
7791
|
+
onChangeEnd: onOpacityChange
|
|
7792
|
+
}
|
|
7793
|
+
);
|
|
7794
|
+
}
|
|
7795
|
+
function BorderStyleOption({
|
|
7796
|
+
node,
|
|
7797
|
+
onChange
|
|
7798
|
+
}) {
|
|
7799
|
+
let selecteBorderStyle = node.data.element.style.border ?? "dashed";
|
|
7800
|
+
const [value, setValue] = useState(selecteBorderStyle);
|
|
7801
|
+
return useEffect(() => {
|
|
7802
|
+
setValue(selecteBorderStyle);
|
|
7803
|
+
}, [selecteBorderStyle]), /* @__PURE__ */ jsx(Box, { mt: "md", children: /* @__PURE__ */ jsx(
|
|
7804
|
+
SegmentedControl,
|
|
7805
|
+
{
|
|
7806
|
+
size: "xs",
|
|
7807
|
+
fullWidth: !0,
|
|
7808
|
+
withItemsBorders: !1,
|
|
7809
|
+
value,
|
|
7810
|
+
onChange: (v) => {
|
|
7811
|
+
setValue(v), onChange(v);
|
|
7812
|
+
},
|
|
7813
|
+
data: [
|
|
7814
|
+
{ label: "Solid", value: "solid" },
|
|
7815
|
+
{ label: "Dashed", value: "dashed" },
|
|
7816
|
+
{ label: "Dotted", value: "dotted" },
|
|
7817
|
+
{ label: "None", value: "none" }
|
|
7818
|
+
]
|
|
7819
|
+
}
|
|
7820
|
+
) });
|
|
7821
|
+
}
|
|
7822
|
+
function OptionsPanel() {
|
|
7583
7823
|
const [selectedNodes, setSelectedNodes] = useState([]);
|
|
7584
7824
|
return useOnSelectionChange({
|
|
7585
7825
|
onChange: ({ nodes }) => {
|
|
@@ -7603,7 +7843,7 @@ const OptionsPanelMemo = /* @__PURE__ */ memo(function() {
|
|
|
7603
7843
|
children: /* @__PURE__ */ jsx(Card, { shadow: "sm", children: /* @__PURE__ */ jsx(NodeOptions, { selectedNodeIds: selectedNodes }) })
|
|
7604
7844
|
}
|
|
7605
7845
|
) });
|
|
7606
|
-
}
|
|
7846
|
+
}
|
|
7607
7847
|
function deriveEdgePoints(bezierSpline) {
|
|
7608
7848
|
let [start2, ...bezierPoints] = bezierSpline;
|
|
7609
7849
|
invariant(start2, "start should be defined");
|
|
@@ -7758,12 +7998,12 @@ function FitViewOnDiagramChanges() {
|
|
|
7758
7998
|
(s) => s.viewportChanged,
|
|
7759
7999
|
setViewportMoved
|
|
7760
8000
|
),
|
|
7761
|
-
[diagramApi]
|
|
8001
|
+
[diagramApi, setViewportMoved]
|
|
7762
8002
|
), useRafEffect(
|
|
7763
8003
|
() => {
|
|
7764
8004
|
!isReady || processedChangeId === pendingChangeId || (diagramApi.getState().fitDiagram(), setProcessed(pendingChangeId));
|
|
7765
8005
|
},
|
|
7766
|
-
[isReady, processedChangeId, pendingChangeId]
|
|
8006
|
+
[isReady, processedChangeId, pendingChangeId, diagramApi]
|
|
7767
8007
|
), !viewportMoved && isReady ? /* @__PURE__ */ jsx(FitViewOnViewportResize, { diagramApi }) : null;
|
|
7768
8008
|
}
|
|
7769
8009
|
const selectFitViewFlag = (s) => s.fitViewEnabled, FitViewOnDiagramChange = memo(() => useDiagramState(selectFitViewFlag) ? /* @__PURE__ */ jsx(FitViewOnDiagramChanges, {}) : null);
|
|
@@ -7779,13 +8019,19 @@ const isSameNode = (a) => (b) => a.id === b.id && a.type === b.type && Object.is
|
|
|
7779
8019
|
(state) => ({
|
|
7780
8020
|
viewId: state.view.id,
|
|
7781
8021
|
nodes: state.view.nodes,
|
|
7782
|
-
edges: state.view.edges
|
|
7783
|
-
draggable: state.nodesDraggable,
|
|
7784
|
-
selectable: state.nodesSelectable
|
|
8022
|
+
edges: state.view.edges
|
|
7785
8023
|
}),
|
|
7786
8024
|
// listener
|
|
7787
|
-
({ viewId, nodes, edges
|
|
7788
|
-
const {
|
|
8025
|
+
({ viewId, nodes, edges }) => {
|
|
8026
|
+
const {
|
|
8027
|
+
lastOnNavigate,
|
|
8028
|
+
nodesDraggable,
|
|
8029
|
+
nodesSelectable,
|
|
8030
|
+
focusedNodeId
|
|
8031
|
+
} = diagramStoreApi.getState(), updates = diagramViewToXYFlowData({ nodes, edges }, {
|
|
8032
|
+
draggable: nodesDraggable,
|
|
8033
|
+
selectable: nodesSelectable || focusedNodeId !== null
|
|
8034
|
+
});
|
|
7789
8035
|
if (xyflowRef.current.setNodes(
|
|
7790
8036
|
(prev) => updates.nodes.map((update) => {
|
|
7791
8037
|
const existing = prev.find(isSameNode(update));
|
|
@@ -7888,7 +8134,7 @@ function assignInlineVars(varsOrContract, tokens) {
|
|
|
7888
8134
|
writable: !1
|
|
7889
8135
|
}), styles;
|
|
7890
8136
|
}
|
|
7891
|
-
var container$2 = "
|
|
8137
|
+
var container$2 = "bexn7q1", edgePathBg = "bexn7q2", fillStrokeCtx = "bexn7q3", cssEdgePath = "bexn7q6", varLabelX = "var(--bexn7q7)", varLabelY = "var(--bexn7q8)", edgeLabel = "bexn7qa", edgeLabelBody = "bexn7qb";
|
|
7892
8138
|
function getNodeIntersection(intersectionNode, targetNode) {
|
|
7893
8139
|
const {
|
|
7894
8140
|
width: intersectionNodeWidth,
|
|
@@ -7950,28 +8196,23 @@ function bezierPath(bezierSpline) {
|
|
|
7950
8196
|
}
|
|
7951
8197
|
return invariant(points.length === 0, "all points should be consumed"), path;
|
|
7952
8198
|
}
|
|
7953
|
-
const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, by]) => isSamePoint(a.x, bx) && isSamePoint(a.y, by), isEqualProps = (prev, next) => prev.id === next.id && prev.source === next.source && prev.target === next.target && isSamePoint(prev.sourceX, next.sourceX) && isSamePoint(prev.sourceY, next.sourceY) && isSamePoint(prev.targetX, next.targetX) && isSamePoint(prev.targetY, next.targetY) && deepEqual(prev.data, next.data), RelationshipEdge = /* @__PURE__ */ memo(function({
|
|
8199
|
+
const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, by]) => isSamePoint(a.x, bx) && isSamePoint(a.y, by), isEqualProps = (prev, next) => prev.id === next.id && prev.source === next.source && prev.target === next.target && deepEqual(prev.selected ?? !1, next.selected ?? !1) && isSamePoint(prev.sourceX, next.sourceX) && isSamePoint(prev.sourceY, next.sourceY) && isSamePoint(prev.targetX, next.targetX) && isSamePoint(prev.targetY, next.targetY) && deepEqual(prev.data, next.data), curve = line().curve(curveCatmullRomOpen.alpha(1)), RelationshipEdge = /* @__PURE__ */ memo(function({
|
|
7954
8200
|
id: id2,
|
|
7955
8201
|
data,
|
|
7956
8202
|
selected: _selected,
|
|
7957
|
-
markerEnd: _markerEnd,
|
|
7958
8203
|
style: style2,
|
|
7959
8204
|
source,
|
|
7960
8205
|
target,
|
|
7961
8206
|
interactionWidth
|
|
7962
8207
|
}) {
|
|
7963
8208
|
var _a, _b, _c;
|
|
7964
|
-
const { nodeLookup, edgeLookup } = useXYStoreApi().getState(), sourceNode = nonNullable(nodeLookup.get(source), `source node ${source} not found`), targetNode = nonNullable(nodeLookup.get(target), `target node ${target} not found`), isNotModified = isSamePosition(sourceNode.internals.positionAbsolute, sourceNode.data.element.position) && isSamePosition(targetNode.internals.positionAbsolute, targetNode.data.element.position);
|
|
7965
|
-
invariant(data, "data is required");
|
|
7966
|
-
const {
|
|
7967
|
-
edge
|
|
7968
|
-
} = data, color2 = edge.color ?? "gray", isHovered = useDiagramState((s) => s.hoveredEdgeId === id2), line = edge.line ?? "dashed", isDotted = line === "dotted", isDashed = isDotted || line === "dashed";
|
|
8209
|
+
const { nodeLookup, edgeLookup } = useXYStoreApi().getState(), sourceNode = nonNullable(nodeLookup.get(source), `source node ${source} not found`), targetNode = nonNullable(nodeLookup.get(target), `target node ${target} not found`), isNotModified = isSamePosition(sourceNode.internals.positionAbsolute, sourceNode.data.element.position) && isSamePosition(targetNode.internals.positionAbsolute, targetNode.data.element.position), { edge: diagramEdge, controlPoints } = data, color2 = diagramEdge.color ?? "gray", isHovered = useDiagramState((s) => s.hoveredEdgeId === id2), line2 = diagramEdge.line ?? "dashed", isDotted = line2 === "dotted", isDashed = isDotted || line2 === "dashed";
|
|
7969
8210
|
let strokeDasharray;
|
|
7970
8211
|
isDotted ? strokeDasharray = "1,8" : isDashed && (strokeDasharray = "8,10");
|
|
7971
8212
|
const marker = `url(#arrow-${id2})`;
|
|
7972
8213
|
let edgePath, labelX, labelY;
|
|
7973
8214
|
if (isNotModified)
|
|
7974
|
-
edgePath = bezierPath(
|
|
8215
|
+
edgePath = bezierPath(diagramEdge.points), labelX = ((_a = data.label) == null ? void 0 : _a.bbox.x) ?? 0, labelY = ((_b = data.label) == null ? void 0 : _b.bbox.y) ?? 0;
|
|
7975
8216
|
else {
|
|
7976
8217
|
const { sx, sy, tx, ty, sourcePos, targetPos } = getEdgeParams(sourceNode, targetNode), [_edgePath, _labelX, _labelY] = getBezierPath({
|
|
7977
8218
|
sourceX: sx,
|
|
@@ -7982,6 +8223,14 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, b
|
|
|
7982
8223
|
targetY: ty
|
|
7983
8224
|
});
|
|
7984
8225
|
edgePath = _edgePath, labelX = _labelX, labelY = _labelY;
|
|
8226
|
+
const sourceCenterPos = getNodePositionWithOrigin(sourceNode, [-0.5, -0.5]), targetCenterPos = getNodePositionWithOrigin(targetNode, [-0.5, -0.5]);
|
|
8227
|
+
edgePath = curve([
|
|
8228
|
+
[sourceCenterPos.positionAbsolute.x, sourceCenterPos.positionAbsolute.y],
|
|
8229
|
+
[sx, sy],
|
|
8230
|
+
...controlPoints,
|
|
8231
|
+
[tx, ty],
|
|
8232
|
+
[targetCenterPos.positionAbsolute.x, targetCenterPos.positionAbsolute.y]
|
|
8233
|
+
]);
|
|
7985
8234
|
}
|
|
7986
8235
|
return /* @__PURE__ */ jsxs("g", { className: clsx(container$2), "data-likec4-color": color2, "data-edge-hovered": isHovered, children: [
|
|
7987
8236
|
/* @__PURE__ */ jsx("g", { className: clsx(fillStrokeCtx), children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
|
|
@@ -8005,8 +8254,8 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, b
|
|
|
8005
8254
|
edgePath,
|
|
8006
8255
|
interactionWidth: interactionWidth ?? 10,
|
|
8007
8256
|
strokeDasharray,
|
|
8008
|
-
markerStart:
|
|
8009
|
-
markerEnd:
|
|
8257
|
+
markerStart: diagramEdge.tailArrow ? marker : void 0,
|
|
8258
|
+
markerEnd: diagramEdge.headArrow ? marker : void 0,
|
|
8010
8259
|
style: style2
|
|
8011
8260
|
}
|
|
8012
8261
|
),
|
|
@@ -8030,7 +8279,7 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, b
|
|
|
8030
8279
|
}
|
|
8031
8280
|
) })
|
|
8032
8281
|
] });
|
|
8033
|
-
}, isEqualProps), RelationshipPath =
|
|
8282
|
+
}, isEqualProps), RelationshipPath = ({
|
|
8034
8283
|
edgePath,
|
|
8035
8284
|
interactionWidth,
|
|
8036
8285
|
strokeDasharray,
|
|
@@ -8069,7 +8318,7 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, b
|
|
|
8069
8318
|
strokeWidth: interactionWidth
|
|
8070
8319
|
}
|
|
8071
8320
|
)
|
|
8072
|
-
] })
|
|
8321
|
+
] }), Link = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
8073
8322
|
"svg",
|
|
8074
8323
|
{
|
|
8075
8324
|
ref,
|
|
@@ -8596,6 +8845,36 @@ function ElementNode({
|
|
|
8596
8845
|
}
|
|
8597
8846
|
);
|
|
8598
8847
|
}
|
|
8848
|
+
function SelectEdgesOnNodeFocus() {
|
|
8849
|
+
const focusedNodeId = useDiagramState((s) => s.focusedNodeId), xyflowApi = useXYStoreApi();
|
|
8850
|
+
return useUpdateEffect(() => {
|
|
8851
|
+
const edgeChanges = [], nodeChanges = [], { edges, nodes, triggerNodeChanges, triggerEdgeChanges } = xyflowApi.getState();
|
|
8852
|
+
if (focusedNodeId) {
|
|
8853
|
+
for (const edge of edges)
|
|
8854
|
+
edge.source === focusedNodeId || edge.target === focusedNodeId ? edgeChanges.push({
|
|
8855
|
+
id: edge.id,
|
|
8856
|
+
type: "select",
|
|
8857
|
+
selected: !0
|
|
8858
|
+
}) : edge.selected && edgeChanges.push({
|
|
8859
|
+
id: edge.id,
|
|
8860
|
+
type: "select",
|
|
8861
|
+
selected: !1
|
|
8862
|
+
});
|
|
8863
|
+
for (const node of nodes)
|
|
8864
|
+
node.selected && node.id !== focusedNodeId && nodeChanges.push({
|
|
8865
|
+
id: node.id,
|
|
8866
|
+
type: "select",
|
|
8867
|
+
selected: !1
|
|
8868
|
+
});
|
|
8869
|
+
nodeChanges.push({
|
|
8870
|
+
id: focusedNodeId,
|
|
8871
|
+
type: "select",
|
|
8872
|
+
selected: !0
|
|
8873
|
+
}), edgeChanges.length > 0 && triggerEdgeChanges(edgeChanges), nodeChanges.length > 0 && triggerNodeChanges(nodeChanges);
|
|
8874
|
+
} else
|
|
8875
|
+
xyflowApi.getState().resetSelectedElements();
|
|
8876
|
+
}, [focusedNodeId]), null;
|
|
8877
|
+
}
|
|
8599
8878
|
function literalToEnum(value) {
|
|
8600
8879
|
switch (value) {
|
|
8601
8880
|
case "dots":
|
|
@@ -8613,14 +8892,19 @@ const XYFlowBackground = memo(({ background }) => {
|
|
|
8613
8892
|
return /* @__PURE__ */ jsx(Background, { variant: literalToEnum(background) });
|
|
8614
8893
|
const { variant, ...rest } = background;
|
|
8615
8894
|
return /* @__PURE__ */ jsx(Background, { variant: literalToEnum(variant), ...rest });
|
|
8616
|
-
}, deepEqual)
|
|
8895
|
+
}, deepEqual), viewportDomNode = (state) => {
|
|
8896
|
+
var _a;
|
|
8897
|
+
return ((_a = state.domNode) == null ? void 0 : _a.querySelector(".react-flow__viewport")) ?? null;
|
|
8898
|
+
};
|
|
8617
8899
|
function useXYFlowEvents() {
|
|
8618
|
-
const diagramApi = useDiagramStoreApi(), xyflowApi = useXYStoreApi(), dblclickTimeout = useRef(), dbclickGuarg = () => dblclickTimeout.current !== void 0 ? !0 : (dblclickTimeout.current = window.setTimeout(() => {
|
|
8900
|
+
const diagramApi = useDiagramStoreApi(), xyflowApi = useXYStoreApi(), dblclickTimeout = useRef(), viewportRef = useRef(viewportDomNode(xyflowApi.getState())), dbclickGuarg = () => dblclickTimeout.current !== void 0 ? !0 : (dblclickTimeout.current = window.setTimeout(() => {
|
|
8619
8901
|
dblclickTimeout.current = void 0;
|
|
8620
|
-
}, 250), !1);
|
|
8621
|
-
return
|
|
8902
|
+
}, 250), !1), transformRef = useRef(""), cbRef = useRef();
|
|
8903
|
+
return useEffect(() => xyflowApi.subscribe((state, prev) => {
|
|
8904
|
+
(state.domNode !== prev.domNode || state.domNode && !viewportRef.current) && (viewportRef.current = viewportDomNode(state));
|
|
8905
|
+
}), [xyflowApi]), useMemo(() => ({
|
|
8622
8906
|
onDoubleClick: (event) => {
|
|
8623
|
-
diagramApi.getState().
|
|
8907
|
+
diagramApi.getState().resetLastClicked();
|
|
8624
8908
|
const diagramState = diagramApi.getState();
|
|
8625
8909
|
if (diagramState.onCanvasDblClick) {
|
|
8626
8910
|
diagramState.onCanvasDblClick(event);
|
|
@@ -8634,9 +8918,8 @@ function useXYFlowEvents() {
|
|
|
8634
8918
|
onPaneClick: (event) => {
|
|
8635
8919
|
if (dbclickGuarg())
|
|
8636
8920
|
return;
|
|
8637
|
-
|
|
8638
|
-
|
|
8639
|
-
if (onCanvasClick) {
|
|
8921
|
+
const { focusedNodeId, fitDiagram, onCanvasClick, resetLastClicked } = diagramApi.getState();
|
|
8922
|
+
if (resetLastClicked(), onCanvasClick) {
|
|
8640
8923
|
onCanvasClick(event);
|
|
8641
8924
|
return;
|
|
8642
8925
|
}
|
|
@@ -8652,7 +8935,7 @@ function useXYFlowEvents() {
|
|
|
8652
8935
|
},
|
|
8653
8936
|
onPaneContextMenu: (event) => {
|
|
8654
8937
|
var _a, _b;
|
|
8655
|
-
diagramApi.getState().
|
|
8938
|
+
diagramApi.getState().resetLastClicked(), (_b = (_a = diagramApi.getState()).onCanvasContextMenu) == null || _b.call(_a, event);
|
|
8656
8939
|
},
|
|
8657
8940
|
onEdgeContextMenu: (event, xyedge) => {
|
|
8658
8941
|
var _a, _b;
|
|
@@ -8676,16 +8959,25 @@ function useXYFlowEvents() {
|
|
|
8676
8959
|
focusedNodeId && focusedNodeId !== xynode.id && (fitDiagram(xynode), event.stopPropagation());
|
|
8677
8960
|
},
|
|
8678
8961
|
onNodeDoubleClick: (event, xynode) => {
|
|
8679
|
-
|
|
8680
|
-
|
|
8962
|
+
diagramApi.getState().setLastClickedNode(xynode.id);
|
|
8963
|
+
const { zoomable, fitViewEnabled, fitDiagram, onNodeClick } = diagramApi.getState();
|
|
8964
|
+
onNodeClick || zoomable && fitViewEnabled && (fitDiagram(xynode), event.stopPropagation());
|
|
8681
8965
|
},
|
|
8682
8966
|
onEdgeClick: (event, xyedge) => {
|
|
8683
|
-
|
|
8684
|
-
|
|
8685
|
-
|
|
8686
|
-
|
|
8687
|
-
|
|
8688
|
-
|
|
8967
|
+
diagramApi.getState().setLastClickedEdge(xyedge.id);
|
|
8968
|
+
const { focusedNodeId, fitDiagram, onEdgeClick, xyflow } = diagramApi.getState();
|
|
8969
|
+
if (onEdgeClick) {
|
|
8970
|
+
onEdgeClick({
|
|
8971
|
+
relation: xyedge.data.edge,
|
|
8972
|
+
xyedge,
|
|
8973
|
+
event
|
|
8974
|
+
});
|
|
8975
|
+
return;
|
|
8976
|
+
}
|
|
8977
|
+
if (focusedNodeId && (focusedNodeId === xyedge.source || focusedNodeId === xyedge.target)) {
|
|
8978
|
+
const nextFocus = focusedNodeId === xyedge.source ? xyedge.target : xyedge.source;
|
|
8979
|
+
fitDiagram(xyflow.getNode(nextFocus)), event.stopPropagation();
|
|
8980
|
+
}
|
|
8689
8981
|
},
|
|
8690
8982
|
onMoveEnd: (event, _viewport) => {
|
|
8691
8983
|
const viewportChanged = !!event;
|
|
@@ -8702,6 +8994,19 @@ function useXYFlowEvents() {
|
|
|
8702
8994
|
},
|
|
8703
8995
|
onEdgeMouseLeave: (event, xyedge) => {
|
|
8704
8996
|
diagramApi.getState().setHoveredEdge(null);
|
|
8997
|
+
},
|
|
8998
|
+
/**
|
|
8999
|
+
* WOKAROUND:
|
|
9000
|
+
* Viewport transform is not rounded to integers which results in blurry nodes on some resolution
|
|
9001
|
+
* https://github.com/xyflow/xyflow/issues/3282
|
|
9002
|
+
*/
|
|
9003
|
+
onViewportChange: ({ x, y, zoom: zoom2 }) => {
|
|
9004
|
+
const scale = zoom2 != 1 ? zoom2.toFixed(6) : "1";
|
|
9005
|
+
transformRef.current = `translate(${Math.round(x)}px, ${Math.round(y)}px) scale(${scale})`, cbRef.current ?? (cbRef.current = requestIdleCallback(() => {
|
|
9006
|
+
cbRef.current = void 0, viewportRef.current && viewportRef.current.style.transform !== transformRef.current && (viewportRef.current.style.transform = transformRef.current);
|
|
9007
|
+
}, {
|
|
9008
|
+
timeout: 1e3
|
|
9009
|
+
}));
|
|
8705
9010
|
}
|
|
8706
9011
|
}), [diagramApi, xyflowApi]);
|
|
8707
9012
|
}
|
|
@@ -8711,7 +9016,7 @@ const nodeTypes = {
|
|
|
8711
9016
|
}, edgeTypes = {
|
|
8712
9017
|
relationship: RelationshipEdge
|
|
8713
9018
|
}, selector = (s) => ({
|
|
8714
|
-
nodesSelectable: s.nodesSelectable,
|
|
9019
|
+
nodesSelectable: s.nodesSelectable || s.focusedNodeId !== null,
|
|
8715
9020
|
nodesDraggable: s.nodesDraggable,
|
|
8716
9021
|
fitView: s.fitViewEnabled,
|
|
8717
9022
|
fitViewPadding: s.fitViewPadding,
|
|
@@ -8797,6 +9102,7 @@ function XYFlowWrapper({
|
|
|
8797
9102
|
onNodeClick: handlers.onNodeClick,
|
|
8798
9103
|
onNodeDoubleClick: handlers.onNodeDoubleClick,
|
|
8799
9104
|
onEdgeClick: handlers.onEdgeClick,
|
|
9105
|
+
onViewportChange: handlers.onViewportChange,
|
|
8800
9106
|
onInit: () => {
|
|
8801
9107
|
diagramApi.setState({ initialized: !0 }, !1, "initialized");
|
|
8802
9108
|
},
|
|
@@ -8811,7 +9117,8 @@ function XYFlowWrapper({
|
|
|
8811
9117
|
},
|
|
8812
9118
|
children: [
|
|
8813
9119
|
isBgWithPattern && /* @__PURE__ */ jsx(XYFlowBackground, { background }),
|
|
8814
|
-
controls && /* @__PURE__ */ jsx(Controls, {}),
|
|
9120
|
+
controls && /* @__PURE__ */ jsx(Controls, { position: "bottom-right" }),
|
|
9121
|
+
zoomable && !editor.hasOnNodeClick && /* @__PURE__ */ jsx(SelectEdgesOnNodeFocus, {}),
|
|
8815
9122
|
children2
|
|
8816
9123
|
]
|
|
8817
9124
|
}
|
|
@@ -8831,6 +9138,7 @@ function LikeC4Diagram({
|
|
|
8831
9138
|
background = "dots",
|
|
8832
9139
|
controls = !1,
|
|
8833
9140
|
showElementLinks = !0,
|
|
9141
|
+
showDiagramTitle = !0,
|
|
8834
9142
|
initialWidth,
|
|
8835
9143
|
initialHeight,
|
|
8836
9144
|
keepAspectRatio = !1,
|
|
@@ -8891,7 +9199,7 @@ function LikeC4Diagram({
|
|
|
8891
9199
|
enabled: keepAspectRatio,
|
|
8892
9200
|
width: view.width,
|
|
8893
9201
|
height: view.height,
|
|
8894
|
-
children: /* @__PURE__ */
|
|
9202
|
+
children: /* @__PURE__ */ jsxs(
|
|
8895
9203
|
XYFlow,
|
|
8896
9204
|
{
|
|
8897
9205
|
className: clsx(
|
|
@@ -8905,7 +9213,10 @@ function LikeC4Diagram({
|
|
|
8905
9213
|
controls,
|
|
8906
9214
|
defaultNodes: initialRef.current.defaultNodes,
|
|
8907
9215
|
defaultEdges: initialRef.current.defaultEdges,
|
|
8908
|
-
children:
|
|
9216
|
+
children: [
|
|
9217
|
+
readonly !== !0 && /* @__PURE__ */ jsx(OptionsPanel, {}),
|
|
9218
|
+
showDiagramTitle === !0 && /* @__PURE__ */ jsx(DiagramTitlePanel, {})
|
|
9219
|
+
]
|
|
8909
9220
|
}
|
|
8910
9221
|
)
|
|
8911
9222
|
}
|
|
@@ -8939,6 +9250,7 @@ function StaticLikeC4Diagram({
|
|
|
8939
9250
|
controls: !1,
|
|
8940
9251
|
background,
|
|
8941
9252
|
showElementLinks: !0,
|
|
9253
|
+
showDiagramTitle: !1,
|
|
8942
9254
|
nodesSelectable: !1,
|
|
8943
9255
|
nodesDraggable: !1,
|
|
8944
9256
|
...rest
|