@likec4/diagram 1.42.0 → 1.42.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/bundle/index.js +1170 -1038
- package/dist/LikeC4Diagram.d.ts +1 -1
- package/dist/LikeC4Diagram.js +38 -12
- package/dist/LikeC4Diagram.props.d.ts +0 -10
- package/dist/components/Logo.js +42 -0
- package/dist/components/RootContainer.js +10 -7
- package/dist/context/RootContainerContext.d.ts +11 -0
- package/dist/context/RootContainerContext.js +14 -1
- package/dist/hooks/useReducedGraphics.d.ts +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/likec4diagram/DiagramXYFlow.js +2 -4
- package/dist/likec4diagram/state/DiagramActorProvider.js +3 -4
- package/dist/navigationpanel/NavigationPanelControls.js +2 -2
- package/dist/navigationpanel/NavigationPanelDropdown.js +30 -6
- package/dist/navigationpanel/controls/BurgerButton.js +46 -8
- package/dist/navigationpanel/styles.css.js +1 -1
- package/dist/node_modules/.pnpm/@tabler_icons-react@3.35.0_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconDirectionSignFilled.js +14 -0
- package/dist/styles.css2.js +1 -1
- package/package.json +7 -7
- package/panda.buildinfo.json +9 -5
- package/styles-min.css +1 -1
- package/styles.css +1 -1
- package/dist/context/ControlsCustomLayout.d.ts +0 -12
- package/dist/context/ControlsCustomLayout.js +0 -8
- package/dist/context/ReduceGraphics.d.ts +0 -12
- package/dist/context/ReduceGraphics.js +0 -26
- package/dist/node_modules/.pnpm/@tabler_icons-react@3.35.0_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconMenu2.js +0 -14
package/dist/LikeC4Diagram.d.ts
CHANGED
|
@@ -8,4 +8,4 @@ export type LikeC4DiagramProps<A extends Any = Any> = PropsWithChildren<LikeC4Di
|
|
|
8
8
|
*
|
|
9
9
|
* Use {@link ReactLikeC4} or {@link LikeC4View} for ready-to-use component
|
|
10
10
|
*/
|
|
11
|
-
export declare function LikeC4Diagram<A extends Any = Any>({ onCanvasClick, onCanvasContextMenu, onCanvasDblClick, onEdgeClick, onChange, onEdgeContextMenu, onNavigateTo, onNodeClick, onNodeContextMenu, onOpenSource, onBurgerMenuClick, onInitialized, view, className, readonly, controls, fitView, fitViewPadding, pannable, zoomable, background, enableElementTags, enableFocusMode, enableElementDetails, enableRelationshipDetails, enableRelationshipBrowser, nodesDraggable, nodesSelectable, showNotations, showNavigationButtons, enableDynamicViewWalkthrough, dynamicViewVariant, enableSearch, initialWidth, initialHeight, experimentalEdgeEditing, reduceGraphics, renderIcon,
|
|
11
|
+
export declare function LikeC4Diagram<A extends Any = Any>({ onCanvasClick, onCanvasContextMenu, onCanvasDblClick, onEdgeClick, onChange, onEdgeContextMenu, onNavigateTo, onNodeClick, onNodeContextMenu, onOpenSource, onBurgerMenuClick, onInitialized, view, className, readonly, controls, fitView, fitViewPadding: _fitViewPadding, pannable, zoomable, background, enableElementTags, enableFocusMode, enableElementDetails, enableRelationshipDetails, enableRelationshipBrowser, nodesDraggable, nodesSelectable, showNotations, showNavigationButtons, enableDynamicViewWalkthrough, dynamicViewVariant, enableSearch, initialWidth, initialHeight, experimentalEdgeEditing, reduceGraphics, renderIcon, where, reactFlowProps, renderNodes, children, }: LikeC4DiagramProps<A>): import("react/jsx-runtime").JSX.Element;
|
package/dist/LikeC4Diagram.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { useCustomCompareMemo } from '@react-hookz/web';
|
|
2
3
|
import { ReactFlowProvider } from '@xyflow/react';
|
|
4
|
+
import { deepEqual } from 'fast-equals';
|
|
3
5
|
import { useRef } from 'react';
|
|
6
|
+
import { isPlainObject, mapValues } from 'remeda';
|
|
4
7
|
import { RootContainer } from './components/RootContainer.js';
|
|
5
|
-
import { ControlsCustomLayoutProvider } from './context/ControlsCustomLayout.js';
|
|
6
|
-
import { ReduceGraphicsContext } from './context/ReduceGraphics.js';
|
|
7
8
|
import { TagStylesProvider } from './context/TagStylesContext.js';
|
|
8
9
|
import { useId } from './hooks/useId.js';
|
|
9
10
|
import { LikeC4DiagramUI } from './likec4diagram/DiagramUI.js';
|
|
@@ -11,12 +12,12 @@ import { LikeC4DiagramXYFlow } from './likec4diagram/DiagramXYFlow.js';
|
|
|
11
12
|
import { DiagramActorProvider } from './likec4diagram/state/DiagramActorProvider.js';
|
|
12
13
|
import { LikeC4Styles } from './LikeC4Styles.js';
|
|
13
14
|
import { getViewBounds } from './utils/get-view-bounds.js';
|
|
15
|
+
import { MinZoom, MaxZoom, FitViewPaddings } from './base/const.js';
|
|
14
16
|
import { EnsureMantine } from './context/EnsureMantine.js';
|
|
15
17
|
import { FramerMotionConfig } from './context/FramerMotionConfig.js';
|
|
16
18
|
import { IconRendererProvider } from './context/IconRenderer.js';
|
|
17
19
|
import { DiagramFeatures } from './context/DiagramFeatures.js';
|
|
18
20
|
import { DiagramEventHandlers } from './context/DiagramEventHandlers.js';
|
|
19
|
-
import { FitViewPaddings } from './base/const.js';
|
|
20
21
|
|
|
21
22
|
function LikeC4Diagram({
|
|
22
23
|
onCanvasClick,
|
|
@@ -36,7 +37,7 @@ function LikeC4Diagram({
|
|
|
36
37
|
readonly = true,
|
|
37
38
|
controls = !readonly,
|
|
38
39
|
fitView = true,
|
|
39
|
-
fitViewPadding = controls ? FitViewPaddings.withControls : FitViewPaddings.default,
|
|
40
|
+
fitViewPadding: _fitViewPadding = controls ? FitViewPaddings.withControls : FitViewPaddings.default,
|
|
40
41
|
pannable = true,
|
|
41
42
|
zoomable = true,
|
|
42
43
|
background = "dots",
|
|
@@ -57,7 +58,6 @@ function LikeC4Diagram({
|
|
|
57
58
|
experimentalEdgeEditing = !readonly,
|
|
58
59
|
reduceGraphics = "auto",
|
|
59
60
|
renderIcon,
|
|
60
|
-
renderControls,
|
|
61
61
|
where,
|
|
62
62
|
reactFlowProps,
|
|
63
63
|
renderNodes,
|
|
@@ -66,15 +66,23 @@ function LikeC4Diagram({
|
|
|
66
66
|
const id = useId();
|
|
67
67
|
const initialRef = useRef(null);
|
|
68
68
|
const bounds = getViewBounds(view, dynamicViewVariant);
|
|
69
|
+
const fitViewPadding = useNormalizedViewPadding(_fitViewPadding);
|
|
69
70
|
if (initialRef.current == null) {
|
|
70
71
|
initialRef.current = {
|
|
71
72
|
defaultEdges: [],
|
|
72
73
|
defaultNodes: [],
|
|
73
74
|
initialWidth: initialWidth ?? bounds.width,
|
|
74
|
-
initialHeight: initialHeight ?? bounds.height
|
|
75
|
+
initialHeight: initialHeight ?? bounds.height,
|
|
76
|
+
initialFitViewOptions: {
|
|
77
|
+
maxZoom: MaxZoom,
|
|
78
|
+
minZoom: MinZoom,
|
|
79
|
+
padding: fitViewPadding
|
|
80
|
+
},
|
|
81
|
+
initialMaxZoom: MaxZoom,
|
|
82
|
+
initialMinZoom: MinZoom
|
|
75
83
|
};
|
|
76
84
|
}
|
|
77
|
-
const isReducedGraphicsMode = reduceGraphics === "auto" ? pannable && (bounds.width ?? 1) * (bounds.height ?? 1) > 6e6 : reduceGraphics;
|
|
85
|
+
const isReducedGraphicsMode = reduceGraphics === "auto" ? pannable && (bounds.width ?? 1) * (bounds.height ?? 1) > 6e6 && view.nodes.some((n) => n.children?.length > 0) : reduceGraphics;
|
|
78
86
|
return /* @__PURE__ */ jsx(EnsureMantine, { children: /* @__PURE__ */ jsx(
|
|
79
87
|
FramerMotionConfig,
|
|
80
88
|
{
|
|
@@ -118,12 +126,12 @@ function LikeC4Diagram({
|
|
|
118
126
|
},
|
|
119
127
|
children: [
|
|
120
128
|
/* @__PURE__ */ jsx(LikeC4Styles, { id }),
|
|
121
|
-
/* @__PURE__ */ jsx(TagStylesProvider, { rootSelector: `#${id}`, children: /* @__PURE__ */ jsx(
|
|
129
|
+
/* @__PURE__ */ jsx(TagStylesProvider, { rootSelector: `#${id}`, children: /* @__PURE__ */ jsx(RootContainer, { id, className, reduceGraphics: isReducedGraphicsMode, children: /* @__PURE__ */ jsx(
|
|
122
130
|
ReactFlowProvider,
|
|
123
131
|
{
|
|
124
132
|
fitView,
|
|
125
133
|
...initialRef.current,
|
|
126
|
-
children: /* @__PURE__ */
|
|
134
|
+
children: /* @__PURE__ */ jsxs(
|
|
127
135
|
DiagramActorProvider,
|
|
128
136
|
{
|
|
129
137
|
view,
|
|
@@ -133,7 +141,7 @@ function LikeC4Diagram({
|
|
|
133
141
|
nodesSelectable,
|
|
134
142
|
where: where ?? null,
|
|
135
143
|
dynamicViewVariant,
|
|
136
|
-
children:
|
|
144
|
+
children: [
|
|
137
145
|
/* @__PURE__ */ jsx(
|
|
138
146
|
LikeC4DiagramXYFlow,
|
|
139
147
|
{
|
|
@@ -146,11 +154,11 @@ function LikeC4Diagram({
|
|
|
146
154
|
}
|
|
147
155
|
),
|
|
148
156
|
/* @__PURE__ */ jsx(LikeC4DiagramUI, {})
|
|
149
|
-
]
|
|
157
|
+
]
|
|
150
158
|
}
|
|
151
159
|
)
|
|
152
160
|
}
|
|
153
|
-
) }) })
|
|
161
|
+
) }) })
|
|
154
162
|
]
|
|
155
163
|
}
|
|
156
164
|
)
|
|
@@ -159,5 +167,23 @@ function LikeC4Diagram({
|
|
|
159
167
|
}
|
|
160
168
|
) });
|
|
161
169
|
}
|
|
170
|
+
const toLiteralPaddingWithUnit = (value) => {
|
|
171
|
+
if (typeof value === "number") {
|
|
172
|
+
return `${value}px`;
|
|
173
|
+
}
|
|
174
|
+
return value;
|
|
175
|
+
};
|
|
176
|
+
function useNormalizedViewPadding(raw) {
|
|
177
|
+
return useCustomCompareMemo(
|
|
178
|
+
() => {
|
|
179
|
+
if (isPlainObject(raw)) {
|
|
180
|
+
return mapValues(raw, toLiteralPaddingWithUnit);
|
|
181
|
+
}
|
|
182
|
+
return toLiteralPaddingWithUnit(raw);
|
|
183
|
+
},
|
|
184
|
+
[raw],
|
|
185
|
+
deepEqual
|
|
186
|
+
);
|
|
187
|
+
}
|
|
162
188
|
|
|
163
189
|
export { LikeC4Diagram };
|
|
@@ -2,7 +2,6 @@ import { DiagramEdge, DiagramNode, DynamicViewDisplayVariant, LayoutedView, View
|
|
|
2
2
|
import { ReactFlowProps } from '@xyflow/react';
|
|
3
3
|
import { MouseEvent as ReactMouseEvent, ReactNode } from 'react';
|
|
4
4
|
import { CamelCasedProperties, SetRequired } from 'type-fest';
|
|
5
|
-
import { ControlsCustomLayout } from './context/ControlsCustomLayout';
|
|
6
5
|
import { DiagramApi } from './hooks/useDiagram';
|
|
7
6
|
import { XYFlowInstance } from './hooks/useXYFlow';
|
|
8
7
|
import { Types } from './likec4diagram/types';
|
|
@@ -198,15 +197,6 @@ export interface LikeC4DiagramProperties<A extends Any = Unknown> {
|
|
|
198
197
|
* By default, if icon is http:// or https://, it will be rendered as an image
|
|
199
198
|
*/
|
|
200
199
|
renderIcon?: ElementIconRenderer | undefined;
|
|
201
|
-
/**
|
|
202
|
-
* Customize layout of the controls on the top left
|
|
203
|
-
*
|
|
204
|
-
* @note
|
|
205
|
-
* Ignored if `controls="next"`
|
|
206
|
-
*
|
|
207
|
-
* @see {@link controls}
|
|
208
|
-
*/
|
|
209
|
-
renderControls?: ControlsCustomLayout | undefined;
|
|
210
200
|
/**
|
|
211
201
|
* Override node renderers
|
|
212
202
|
*/
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { css } from '@likec4/styles/css';
|
|
3
|
+
import { forwardRef } from 'react';
|
|
4
|
+
|
|
5
|
+
const Logo = forwardRef(
|
|
6
|
+
(props, ref) => {
|
|
7
|
+
return /* @__PURE__ */ jsxs("svg", { ref, xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 222 56", ...props, children: [
|
|
8
|
+
/* @__PURE__ */ jsx(
|
|
9
|
+
"path",
|
|
10
|
+
{
|
|
11
|
+
fill: "#5E98AF",
|
|
12
|
+
d: "M33.95 33.78V0H2.37A2.37 2.37 0 0 0 0 2.35V33.9h33.95v-.12ZM38.57 33.78H55.6v-14.6c0-1.3-1.06-2.35-2.36-2.35H38.57v16.95ZM33.95 38.37H17.04v14.6c0 1.29 1.06 2.35 2.36 2.35h14.67V38.37h-.12ZM38.57 38.37v16.95h14.67c1.3 0 2.36-1.06 2.36-2.36v-14.6H38.57Z"
|
|
13
|
+
}
|
|
14
|
+
),
|
|
15
|
+
/* @__PURE__ */ jsx(
|
|
16
|
+
"path",
|
|
17
|
+
{
|
|
18
|
+
className: css({
|
|
19
|
+
fill: "[#FCFBF7]",
|
|
20
|
+
_light: {
|
|
21
|
+
fill: "[#222221]"
|
|
22
|
+
}
|
|
23
|
+
}),
|
|
24
|
+
d: "M71.61 12.08c-.06 3.61.3 29.95.23 31.87 0 1.8 0 3.6.06 5.41 0 .3.18.58.47.58 4.1.18 8.13-.17 12.22-.11 1.34.05 2.69 0 3.97 0 1.29-.06 1.4-.59 1.35-1.63-.06-1.63-.06-3.08-.06-4.65-.06-.82-.53-1.11-1.23-1.11-2.4.06-4.8-.06-7.19.06-.4.06-.82.06-1.23.06-.7-.06-.87-.24-.93-1v-.86c-.18-4.83.17-9.83.17-14.66-.06-4.07 0-7.73-.06-11.34 0-1.57 0-3.14-.05-4.65-.06-.93 0-1.92-.24-2.85-.11-.35-.29-.81-.7-.81h-5.5c-.93 0-1.22.64-1.28 1.57v4.12ZM103.81 35c-.17-6.63-.1-13.67-.05-20.24 0-2.04-.12-4.25-.12-6.28 0-2.21-.87-2.1-2.04-2.15-1.7-.06-2.46-.06-4.15-.06-1.11-.06-1.58.23-1.58 1.34 0 5.7-.18 21.8-.12 24.13.06 2.33.3 12.91.18 15.24-.06.81 0 1.62.06 2.44.05.29.23.58.7.58 1.93-.12 3.74-.12 5.67-.17.7-.06 1.28-.24 1.58-1 .05-.4-.12-11.04-.12-13.83Zm13.92 4.47c0-2.03-.3-7.56-.23-8.72 0-.17.11-.4.17-.4.12 0 .35.11.41.17 1.87 2.44 10.64 19.36 11.7 19.42.28.06.58.06.87.06 1.99-.12 3.74 0 5.73 0 2.04 0 .7-1.98.35-2.5-.53-.76-7.48-13.14-7.9-13.9-1.16-1.98-2.16-4.13-3.32-6.05-.12-.23-.24-.58-.18-.81.12-.7.3-1.34.59-1.98a93.18 93.18 0 0 1 4.55-8.14c1.88-2.97 2.93-4.83 4.45-7.5.35-.64.58-1.34.82-2.1.05-.29-.18-.58-.53-.58-1.11-.05-5.15 0-6.43 0-.59 0-1.17.12-1.46.64-.76 1.46-8.6 15.7-9.35 16.98-.06.12-.24.18-.41.18 0 0-.12-.18-.12-.3-.06-3.25.53-13.9.4-16.04-.05-1.28-.28-1.4-1.57-1.46-1.4-.05-3.33-.05-4.73-.05-1.3 0-1.4.7-1.58 1.62-.06.18-.06 5.64-.06 8.09 0 3.54-.3 25.76.11 32.8 0 .7.18 1.1.77 1.1 1.57-.12 3.91 0 5.49 0 1.11 0 1.29-.12 1.29-1.98 0-2.5.23-4.77.23-7.85 0-.23-.06-.46-.06-.7Zm25.66-1.4h-.06c0 1.46-.05 2.97 0 4.49.06 1.86.18 3.72.3 5.58 0 .64.17.81.76.93 1.22.29 2.4.35 3.62.35 3.16-.12 6.31.11 9.47 0 1.29-.06 1.87.06 3.16-.18 1.17-.23 1.58-.87 1.58-2.61-.12-1.1-.06-1.57-.06-2.91 0-1.92-1.35-2.56-2.52-2.5-.81.06-4.73-.06-6.31-.06-2.63.06-2.22.4-2.22-2.33 0-2.2.06-5.05.06-7.32 0-1.22.11-1.63 1.28-1.63h7.31c1.17.17 1.99-.64 1.99-1.86 0-1.22.12-1.28.12-2.5l-.18-1.75c-.12-.99-.47-1.33-1.46-1.33-.64 0-1.29.05-1.93.11-2.52.18-3.68-.17-6.14 0-.82 0-.93-.11-1-.87-.23-2.27 0-4.77.24-7.04.06-.93.3-1.1 1.17-1.16l8.24-.06c1.11-.11 1.46-.06 1.4-1.16-.11-1.69.06-3.43-.11-5.12-.12-.93-.41-1.1-1.46-1.1-1.76.05-2.17.05-3.92.17-1.75.06-8.77.06-10.46.06-2.46 0-2.63-.18-2.7 2.8-.1 2.32-.05 4.7-.05 7.09 0 4.07-.23 18.66-.12 21.92Zm47.76-24.82c.06-1.92 0-3.5 0-5.35 0-2.15-3.92-1.92-5.32-1.86a18.95 18.95 0 0 0-15.08 9.77c-.82 1.57-1.4 3.2-1.81 4.88a34 34 0 0 0-.59 12.15c.41 3.78 1.4 7.56 3.74 10.59 4.04 5.3 11.46 7.15 17.83 6.16.3-.06.59-.11.82-.29.18-.11.35-.35.35-.58l.18-3.31c.06-1.05 0-1 0-2.04 0-1.4-2.93-.35-4.74-.35-1.75 0-3.62-.06-5.2-.87-2.8-1.57-4.38-4.71-5.26-7.68-1-3.2-1.23-6.63-.64-9.88.7-4.25 2.74-9.13 7.25-10.59 2.57-.87 5.31-.58 7.89-.29.35.06.58-.17.58-.46Zm26.77 15.3c.06-2.5 0-14.84 0-18.38.06-.82 0-1.63-.11-2.45-.06-.99-.24-1.28-1.29-1.33h-4.44c-.82 0-1.35.4-1.82 1.27-1.34 3.2-10.75 24.02-12.15 26.58-.53.99-1 1.63-1 2.68v4.24c0 .76-.06 1.28 1.23 1.28l11.1-.06c1.47 0 1.47.3 1.47 1.1 0 .88-.12 4.9-.12 5.3 0 .58.12 1.16 1.23 1.16h5.08c1.23 0 1.23-.7 1.23-2.03.06-1.17-.06-3.5-.06-4.66 0-.93.18-.98 1.76-.98 1.22 0 1.75-.12 1.75-.88.06-1.57 0-2.67 0-4.42 0-1.04-.93-.98-2.92-.98-.65 0-.7-.18-.7-1.05-.12-1.8-.24-4.6-.24-6.4Zm-7.25-5.94c-.05.7-.11 10.82-.11 12.27-.06.81-.24 1.05-1 1.1-1.93.06-3.85.06-5.78.06-.47 0-.65-.4-.41-.87.23-.4 4.85-11.57 6.13-14.48.18-.17.24-.35.41-.52.18-.12.41-.18.59-.23.06 0 .23.29.23.46 0 .76-.06 1.51-.06 2.21Z"
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
] });
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
const LogoIcon = forwardRef(
|
|
31
|
+
(props, ref) => {
|
|
32
|
+
return /* @__PURE__ */ jsx("svg", { ref, xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 56 56", ...props, children: /* @__PURE__ */ jsx(
|
|
33
|
+
"path",
|
|
34
|
+
{
|
|
35
|
+
fill: "#5E98AF",
|
|
36
|
+
d: "M33.95 33.78V0H2.37A2.37 2.37 0 0 0 0 2.35V33.9h33.95v-.12ZM38.57 33.78H55.6v-14.6c0-1.3-1.06-2.35-2.36-2.35H38.57v16.95ZM33.95 38.37H17.04v14.6c0 1.29 1.06 2.35 2.36 2.35h14.67V38.37h-.12ZM38.57 38.37v16.95h14.67c1.3 0 2.36-1.06 2.36-2.36v-14.6H38.57Z"
|
|
37
|
+
}
|
|
38
|
+
) });
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
export { Logo, LogoIcon };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { cx } from '@likec4/styles/css';
|
|
3
3
|
import { useIsomorphicLayoutEffect } from '@react-hookz/web';
|
|
4
|
+
import { atom } from 'nanostores';
|
|
4
5
|
import { useState, useRef, useEffect, useMemo } from 'react';
|
|
5
|
-
import {
|
|
6
|
-
import { RootContainerContext } from '../context/RootContainerContext.js';
|
|
6
|
+
import { PanningAtomSafeCtx, ReduceGraphicsModeCtx, RootContainerContext } from '../context/RootContainerContext.js';
|
|
7
7
|
|
|
8
8
|
function RootContainer({
|
|
9
9
|
id,
|
|
@@ -13,17 +13,20 @@ function RootContainer({
|
|
|
13
13
|
}) {
|
|
14
14
|
const [mounted, setMounted] = useState(false);
|
|
15
15
|
const ref = useRef(null);
|
|
16
|
-
const $
|
|
16
|
+
const $isPanningRef = useRef(null);
|
|
17
|
+
if (!$isPanningRef.current) {
|
|
18
|
+
$isPanningRef.current = atom(false);
|
|
19
|
+
}
|
|
17
20
|
useIsomorphicLayoutEffect(() => {
|
|
18
21
|
setMounted(true);
|
|
19
22
|
}, []);
|
|
20
23
|
useEffect(() => {
|
|
21
|
-
return $
|
|
24
|
+
return $isPanningRef.current?.subscribe((isPanning) => {
|
|
22
25
|
ref.current?.setAttribute("data-likec4-diagram-panning", isPanning ? "true" : "false");
|
|
23
26
|
});
|
|
24
|
-
}, [
|
|
27
|
+
}, []);
|
|
25
28
|
const ctx = useMemo(() => ({ id, ref }), [id, ref]);
|
|
26
|
-
return /* @__PURE__ */ jsx(
|
|
29
|
+
return /* @__PURE__ */ jsx(PanningAtomSafeCtx, { value: $isPanningRef.current, children: /* @__PURE__ */ jsx(ReduceGraphicsModeCtx.Provider, { value: reduceGraphics, children: /* @__PURE__ */ jsx(
|
|
27
30
|
"div",
|
|
28
31
|
{
|
|
29
32
|
id,
|
|
@@ -34,7 +37,7 @@ function RootContainer({
|
|
|
34
37
|
},
|
|
35
38
|
children: mounted && !!ctx.ref.current && /* @__PURE__ */ jsx(RootContainerContext.Provider, { value: ctx, children })
|
|
36
39
|
}
|
|
37
|
-
);
|
|
40
|
+
) }) });
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
export { RootContainer };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { WritableAtom } from 'nanostores';
|
|
1
2
|
import { RefObject, Context } from 'react';
|
|
2
3
|
export declare const RootContainerContext: Context<{
|
|
3
4
|
id: string;
|
|
@@ -9,3 +10,13 @@ export declare function useRootContainer(): {
|
|
|
9
10
|
};
|
|
10
11
|
export declare function useRootContainerRef(): RefObject<HTMLDivElement | null>;
|
|
11
12
|
export declare function useRootContainerElement(): HTMLDivElement | null;
|
|
13
|
+
export declare const ReduceGraphicsModeCtx: Context<boolean | null>;
|
|
14
|
+
/**
|
|
15
|
+
* Hook to determine if reduced graphics mode is enabled.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useIsReducedGraphics(): boolean;
|
|
18
|
+
export declare const PanningAtomSafeCtx: ({ children, value }: {
|
|
19
|
+
value: WritableAtom<boolean>;
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
}) => import("react/jsx-runtime").JSX.Element, usePanningAtom: () => WritableAtom<boolean>;
|
|
22
|
+
export declare function useIsPanning(): boolean;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { createSafeContext } from '@mantine/core';
|
|
2
|
+
import '@nanostores/react';
|
|
1
3
|
import { createContext, useContext } from 'react';
|
|
2
4
|
|
|
3
5
|
const RootContainerContext = createContext(null);
|
|
@@ -14,5 +16,16 @@ function useRootContainerRef() {
|
|
|
14
16
|
function useRootContainerElement() {
|
|
15
17
|
return useRootContainer().ref.current;
|
|
16
18
|
}
|
|
19
|
+
const ReduceGraphicsModeCtx = createContext(null);
|
|
20
|
+
function useIsReducedGraphics() {
|
|
21
|
+
const isReduced = useContext(ReduceGraphicsModeCtx);
|
|
22
|
+
if (isReduced === null) {
|
|
23
|
+
console.warn("ReduceGraphicsMode is not provided");
|
|
24
|
+
}
|
|
25
|
+
return isReduced ?? false;
|
|
26
|
+
}
|
|
27
|
+
const [PanningAtomSafeCtx, usePanningAtom] = createSafeContext(
|
|
28
|
+
"PanningAtomSafeCtx is not provided"
|
|
29
|
+
);
|
|
17
30
|
|
|
18
|
-
export { RootContainerContext, useRootContainer, useRootContainerElement, useRootContainerRef };
|
|
31
|
+
export { PanningAtomSafeCtx, ReduceGraphicsModeCtx, RootContainerContext, useIsReducedGraphics, usePanningAtom, useRootContainer, useRootContainerElement, useRootContainerRef };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { useIsPanning, useIsReducedGraphics } from '../context/
|
|
1
|
+
export { useIsPanning, useIsReducedGraphics } from '../context/RootContainerContext';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export type { ControlsCustomLayout, ControlsCustomLayoutProps } from './context/ControlsCustomLayout';
|
|
2
1
|
export { IconRendererProvider } from './context/IconRenderer';
|
|
3
2
|
export { LikeC4Diagram, type LikeC4DiagramProps, } from './LikeC4Diagram';
|
|
4
3
|
export type { ElementIconRenderer, ElementIconRendererProps, LikeC4ColorScheme, NodeRenderers, OnCanvasClick, OnChange, OnEdgeClick, OnInitialized, OnNavigateTo, OnNodeClick, OnOpenSource, PaddingWithUnit, ViewPadding, WhereOperator, } from './LikeC4Diagram.props';
|
|
@@ -7,7 +7,7 @@ import { deepEqual, shallowEqual } from 'fast-equals';
|
|
|
7
7
|
import { isEmpty } from 'remeda';
|
|
8
8
|
import { memoNode } from '../base-primitives/memoNode.js';
|
|
9
9
|
import { BaseXYFlow } from '../base/BaseXYFlow.js';
|
|
10
|
-
import { useIsReducedGraphics, usePanningAtom } from '../context/
|
|
10
|
+
import { useIsReducedGraphics, usePanningAtom } from '../context/RootContainerContext.js';
|
|
11
11
|
import { useDiagram, useDiagramContext } from '../hooks/useDiagram.js';
|
|
12
12
|
import { depsShallowEqual, useUpdateEffect } from '../hooks/useUpdateEffect.js';
|
|
13
13
|
import { BuiltinEdges, BuiltinNodes } from './custom/index.js';
|
|
@@ -174,9 +174,7 @@ function LikeC4DiagramXYFlow({
|
|
|
174
174
|
diagram.send({ type: "xyflow.edgeMouseLeave", edge, event });
|
|
175
175
|
}
|
|
176
176
|
}),
|
|
177
|
-
|
|
178
|
-
onMove
|
|
179
|
-
},
|
|
177
|
+
onMove,
|
|
180
178
|
onMoveEnd,
|
|
181
179
|
onInit: useCallbackRef((instance) => {
|
|
182
180
|
diagram.send({ type: "xyflow.init", instance });
|
|
@@ -3,7 +3,7 @@ import { useCustomCompareEffect, useRafEffect } from '@react-hookz/web';
|
|
|
3
3
|
import { useActorRef, useSelector } from '@xstate/react';
|
|
4
4
|
import { useStoreApi } from '@xyflow/react';
|
|
5
5
|
import { shallowEqual, deepEqual } from 'fast-equals';
|
|
6
|
-
import { useRef,
|
|
6
|
+
import { useRef, useEffect, useMemo } from 'react';
|
|
7
7
|
import { ErrorBoundary } from '../../components/ErrorFallback.js';
|
|
8
8
|
import { useDiagramEventHandlers } from '../../context/DiagramEventHandlers.js';
|
|
9
9
|
import { useEnabledFeatures, DiagramFeatures } from '../../context/DiagramFeatures.js';
|
|
@@ -70,12 +70,11 @@ function DiagramActorProvider({
|
|
|
70
70
|
[features],
|
|
71
71
|
shallowEqual
|
|
72
72
|
);
|
|
73
|
-
|
|
73
|
+
useEffect(
|
|
74
74
|
() => {
|
|
75
75
|
actorRef.send({ type: "update.inputs", inputs: { zoomable, pannable, fitViewPadding, nodesSelectable } });
|
|
76
76
|
},
|
|
77
|
-
[zoomable, pannable, fitViewPadding, nodesSelectable]
|
|
78
|
-
deepEqual
|
|
77
|
+
[zoomable, pannable, fitViewPadding, nodesSelectable]
|
|
79
78
|
);
|
|
80
79
|
const dynamicViewVariant = useSelector(actorRef, selectDynamicViewVariant);
|
|
81
80
|
const update = useMemo(
|
|
@@ -102,7 +102,7 @@ const NavigationPanelControls = () => {
|
|
|
102
102
|
{
|
|
103
103
|
layout: "position",
|
|
104
104
|
className: hstack({
|
|
105
|
-
gap: "
|
|
105
|
+
gap: "1",
|
|
106
106
|
flexShrink: 1,
|
|
107
107
|
flexGrow: 1,
|
|
108
108
|
overflow: "hidden"
|
|
@@ -119,7 +119,7 @@ const NavigationPanelControls = () => {
|
|
|
119
119
|
{
|
|
120
120
|
layout: "position",
|
|
121
121
|
className: hstack({
|
|
122
|
-
gap: "
|
|
122
|
+
gap: "0.5",
|
|
123
123
|
flexGrow: 0,
|
|
124
124
|
_empty: {
|
|
125
125
|
display: "none"
|
|
@@ -6,8 +6,10 @@ import { HStack, VStack, Box } from '@likec4/styles/jsx';
|
|
|
6
6
|
import { vstack, hstack } from '@likec4/styles/patterns';
|
|
7
7
|
import { PopoverDropdown, createScopedKeydownHandler, ScrollAreaAutosize, Input, rem, Button, Divider, Highlight, UnstyledButton, Breadcrumbs } from '@mantine/core';
|
|
8
8
|
import { useThrottledCallback, useUncontrolled } from '@mantine/hooks';
|
|
9
|
+
import { useMountEffect } from '@react-hookz/web';
|
|
9
10
|
import { useSelector } from '@xstate/react';
|
|
10
11
|
import { deepEqual } from 'fast-equals';
|
|
12
|
+
import { useRef } from 'react';
|
|
11
13
|
import { isEmpty, pipe, sort, isArray } from 'remeda';
|
|
12
14
|
import { NavigationLink } from '../components/NavigationLink.js';
|
|
13
15
|
import { useLikeC4Model } from '../hooks/useLikeC4Model.js';
|
|
@@ -17,6 +19,7 @@ import { breadcrumbTitle } from './styles.css.js';
|
|
|
17
19
|
import { useOnDiagramEvent } from '../hooks/useDiagram.js';
|
|
18
20
|
import IconSearch from '../node_modules/.pnpm/@tabler_icons-react@3.35.0_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconSearch.js';
|
|
19
21
|
import IconChevronRight from '../node_modules/.pnpm/@tabler_icons-react@3.35.0_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronRight.js';
|
|
22
|
+
import IconDirectionSignFilled from '../node_modules/.pnpm/@tabler_icons-react@3.35.0_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconDirectionSignFilled.js';
|
|
20
23
|
import IconStack2 from '../node_modules/.pnpm/@tabler_icons-react@3.35.0_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconStack2.js';
|
|
21
24
|
import IconZoomScan from '../node_modules/.pnpm/@tabler_icons-react@3.35.0_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconZoomScan.js';
|
|
22
25
|
import IconStarFilled from '../node_modules/.pnpm/@tabler_icons-react@3.35.0_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconStarFilled.js';
|
|
@@ -70,7 +73,7 @@ function NavigationPanelDropdown() {
|
|
|
70
73
|
/* @__PURE__ */ jsx(
|
|
71
74
|
ScrollAreaAutosize,
|
|
72
75
|
{
|
|
73
|
-
scrollbars: "
|
|
76
|
+
scrollbars: "x",
|
|
74
77
|
type: "auto",
|
|
75
78
|
offsetScrollbars: "present",
|
|
76
79
|
classNames: {
|
|
@@ -81,6 +84,11 @@ function NavigationPanelDropdown() {
|
|
|
81
84
|
]
|
|
82
85
|
})
|
|
83
86
|
},
|
|
87
|
+
styles: {
|
|
88
|
+
viewport: {
|
|
89
|
+
overscrollBehavior: "none"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
84
92
|
children: hasSearchQuery ? /* @__PURE__ */ jsx(SearchResults, { searchQuery: normalizeViewPath(searchQuery).toLowerCase() }) : /* @__PURE__ */ jsx(FolderColumns, {})
|
|
85
93
|
}
|
|
86
94
|
)
|
|
@@ -123,7 +131,7 @@ function SearchResults({ searchQuery }) {
|
|
|
123
131
|
"calc(100cqh - 200px)"
|
|
124
132
|
]
|
|
125
133
|
}),
|
|
126
|
-
children: /* @__PURE__ */ jsx(VStack, { gap: "
|
|
134
|
+
children: /* @__PURE__ */ jsx(VStack, { gap: "0.5", children: found.map((v) => /* @__PURE__ */ jsx(
|
|
127
135
|
FoundedView,
|
|
128
136
|
{
|
|
129
137
|
view: v,
|
|
@@ -282,7 +290,7 @@ const ViewTypeIcon = {
|
|
|
282
290
|
}
|
|
283
291
|
),
|
|
284
292
|
deployment: /* @__PURE__ */ jsx(IconStack2, { size: 16, stroke: 1.5, className: viewTypeIconCss }),
|
|
285
|
-
dynamic: /* @__PURE__ */ jsx(
|
|
293
|
+
dynamic: /* @__PURE__ */ jsx(IconDirectionSignFilled, { size: 18, className: viewTypeIconCss })
|
|
286
294
|
};
|
|
287
295
|
const ColumnScrollArea = ScrollAreaAutosize.withProps({
|
|
288
296
|
scrollbars: "y",
|
|
@@ -332,10 +340,18 @@ function FolderColumns() {
|
|
|
332
340
|
const columns = useNavigationActorContext(selectColumns, deepEqual);
|
|
333
341
|
return /* @__PURE__ */ jsx(HStack, { gap: "xs", alignItems: "stretch", children: columns.flatMap((column, i) => [
|
|
334
342
|
i > 0 && /* @__PURE__ */ jsx(Divider, { orientation: "vertical" }, "divider" + i),
|
|
335
|
-
/* @__PURE__ */ jsx(
|
|
343
|
+
/* @__PURE__ */ jsx(
|
|
344
|
+
FolderColumn,
|
|
345
|
+
{
|
|
346
|
+
data: column,
|
|
347
|
+
isLast: i == columns.length - 1
|
|
348
|
+
},
|
|
349
|
+
column.folderPath
|
|
350
|
+
)
|
|
336
351
|
]) });
|
|
337
352
|
}
|
|
338
|
-
function FolderColumn({ data }) {
|
|
353
|
+
function FolderColumn({ data, isLast }) {
|
|
354
|
+
const ref = useRef(null);
|
|
339
355
|
const actor = useNavigationActorRef();
|
|
340
356
|
const onItemClicked = (item) => (e) => {
|
|
341
357
|
e.stopPropagation();
|
|
@@ -345,7 +361,15 @@ function FolderColumn({ data }) {
|
|
|
345
361
|
actor.send({ type: "select.view", viewId: item.viewId });
|
|
346
362
|
}
|
|
347
363
|
};
|
|
348
|
-
|
|
364
|
+
useMountEffect(() => {
|
|
365
|
+
if (isLast && ref.current) {
|
|
366
|
+
ref.current.scrollIntoView({
|
|
367
|
+
inline: "nearest",
|
|
368
|
+
behavior: "smooth"
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
return /* @__PURE__ */ jsx(Box, { mb: "1", ref, children: /* @__PURE__ */ jsx(ColumnScrollArea, { children: /* @__PURE__ */ jsx(VStack, { gap: "0.5", children: data.items.map((item, i) => /* @__PURE__ */ jsx(
|
|
349
373
|
FolderColumnItem,
|
|
350
374
|
{
|
|
351
375
|
columnItem: item,
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import { jsx } from 'react/jsx-runtime';
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { cx, css } from '@likec4/styles/css';
|
|
3
|
+
import { hstack } from '@likec4/styles/patterns';
|
|
4
|
+
import { UnstyledButton } from '@mantine/core';
|
|
5
|
+
import * as m from 'motion/react-m';
|
|
6
|
+
import { Logo, LogoIcon } from '../../components/Logo.js';
|
|
2
7
|
import { useDiagramEventHandlers } from '../../context/DiagramEventHandlers.js';
|
|
3
|
-
import { PanelActionIcon } from '../_common.js';
|
|
4
8
|
import { useNavigationActor } from '../hooks.js';
|
|
5
|
-
import IconMenu2 from '../../node_modules/.pnpm/@tabler_icons-react@3.35.0_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconMenu2.js';
|
|
6
9
|
|
|
7
10
|
const BurgerButton = () => {
|
|
8
11
|
const actor = useNavigationActor();
|
|
9
12
|
const { onBurgerMenuClick } = useDiagramEventHandlers();
|
|
10
|
-
return /* @__PURE__ */ jsx(
|
|
11
|
-
|
|
13
|
+
return /* @__PURE__ */ jsx(m.div, { layout: "position", children: /* @__PURE__ */ jsxs(
|
|
14
|
+
UnstyledButton,
|
|
12
15
|
{
|
|
13
|
-
layout: "position",
|
|
14
16
|
onMouseEnter: () => {
|
|
15
17
|
actor.send({ type: "breadcrumbs.mouseEnter.root" });
|
|
16
18
|
},
|
|
@@ -26,9 +28,45 @@ const BurgerButton = () => {
|
|
|
26
28
|
}
|
|
27
29
|
actor.send({ type: "breadcrumbs.click.root" });
|
|
28
30
|
},
|
|
29
|
-
|
|
31
|
+
className: cx(
|
|
32
|
+
"mantine-active",
|
|
33
|
+
hstack({
|
|
34
|
+
padding: "0.5",
|
|
35
|
+
// _active: {
|
|
36
|
+
// transform: 'translateY(1px)',
|
|
37
|
+
// },
|
|
38
|
+
width: {
|
|
39
|
+
base: "[20px]",
|
|
40
|
+
"@/md": "[64px]"
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
),
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ jsx(
|
|
46
|
+
Logo,
|
|
47
|
+
{
|
|
48
|
+
className: css({
|
|
49
|
+
display: {
|
|
50
|
+
base: "none",
|
|
51
|
+
"@/md": "block"
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
),
|
|
56
|
+
/* @__PURE__ */ jsx(
|
|
57
|
+
LogoIcon,
|
|
58
|
+
{
|
|
59
|
+
className: css({
|
|
60
|
+
display: {
|
|
61
|
+
base: "block",
|
|
62
|
+
"@/md": "none"
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
]
|
|
30
68
|
}
|
|
31
|
-
);
|
|
69
|
+
) });
|
|
32
70
|
};
|
|
33
71
|
|
|
34
72
|
export { BurgerButton };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import createReactComponent from '../createReactComponent.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @license @tabler/icons-react v3.35.0 - MIT
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license.
|
|
7
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const __iconNode = [["path", { "d": "M10.52 2.614a2.095 2.095 0 0 1 2.835 -.117l.126 .117l7.905 7.905c.777 .777 .816 2.013 .117 2.836l-.117 .126l-7.905 7.905a2.094 2.094 0 0 1 -2.836 .117l-.126 -.117l-7.907 -7.906a2.096 2.096 0 0 1 -.115 -2.835l.117 -.126l7.905 -7.905zm5.969 9.535l.01 -.116l-.003 -.12l-.016 -.114l-.03 -.11l-.044 -.112l-.052 -.098l-.076 -.105l-.07 -.081l-3.5 -3.5l-.095 -.083a1 1 0 0 0 -1.226 0l-.094 .083l-.083 .094a1 1 0 0 0 0 1.226l.083 .094l1.792 1.793h-5.085l-.117 .007a1 1 0 0 0 0 1.986l.117 .007h5.085l-1.792 1.793l-.083 .094a1 1 0 0 0 1.403 1.403l.094 -.083l3.5 -3.5l.097 -.112l.05 -.074l.037 -.067l.05 -.112l.023 -.076l.025 -.117z", "key": "svg-0" }]];
|
|
12
|
+
const IconDirectionSignFilled = createReactComponent("filled", "direction-sign-filled", "DirectionSignFilled", __iconNode);
|
|
13
|
+
|
|
14
|
+
export { __iconNode, IconDirectionSignFilled as default };
|