@likec4/diagram 1.56.0 → 1.57.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/LikeC4Diagram.js +3 -1
- package/dist/LikeC4View.js +47 -55
- package/dist/adhoc-editor/ElementsTree.js +2 -6
- package/dist/components/RootContainer.js +19 -18
- package/dist/context/DiagramFeatures.d.ts +1 -1
- package/dist/context/DiagramFeatures.js +5 -0
- package/dist/context/RootContainerContext.d.ts +10 -17
- package/dist/context/RootContainerContext.js +1 -13
- package/dist/custom/index.d.ts +1 -1
- package/dist/custom/index.js +1 -2
- package/dist/editor/LikeC4EditorCallbacks.d.ts +5 -0
- package/dist/editor/actor/actions.d.ts +115 -0
- package/dist/editor/actor/actions.js +122 -0
- package/dist/editor/{hotkeyActor.d.ts → actor/hotkey.d.ts} +1 -1
- package/dist/editor/{hotkeyActor.js → actor/hotkey.js} +4 -4
- package/dist/editor/actor/machine.d.ts +11 -0
- package/dist/editor/actor/machine.js +22 -0
- package/dist/editor/{editorActor.setup.d.ts → actor/setup.d.ts} +13 -49
- package/dist/editor/{editorActor.setup.js → actor/setup.js} +13 -10
- package/dist/editor/actor/state.editor.d.ts +97 -0
- package/dist/editor/actor/state.editor.js +55 -0
- package/dist/editor/actor/state.sync-queue.d.ts +420 -0
- package/dist/editor/actor/state.sync-queue.js +235 -0
- package/dist/editor/actor/types.d.ts +59 -0
- package/dist/editor/actor/types.js +5 -0
- package/dist/editor/applyChangesToManualLayout.js +1 -1
- package/dist/editor/index.d.ts +2 -1
- package/dist/editor/useEditorActorLogic.d.ts +8 -2
- package/dist/editor/useEditorActorLogic.js +26 -6
- package/dist/hooks/useDiagram.js +6 -1
- package/dist/hooks/useDiagramCompareLayout.js +1 -1
- package/dist/hooks/useEditorActor.d.ts +4 -0
- package/dist/hooks/useEditorActor.js +26 -0
- package/dist/hooks/useLikeC4ElementsTree.d.ts +3 -2
- package/dist/hooks/useLikeC4ElementsTree.js +3 -1
- package/dist/likec4diagram/DiagramUI.js +8 -4
- package/dist/likec4diagram/DiagramXYFlow.js +12 -12
- package/dist/likec4diagram/state/aligners.js +3 -0
- package/dist/likec4diagram/state/assign.js +1 -1
- package/dist/likec4diagram/state/diagram-api.d.ts +16 -0
- package/dist/likec4diagram/state/diagram-api.js +13 -7
- package/dist/likec4diagram/state/machine.actions.js +7 -8
- package/dist/likec4diagram/state/machine.d.ts +1 -1
- package/dist/likec4diagram/state/machine.setup.js +1 -1
- package/dist/likec4diagram/state/types.d.ts +1 -1
- package/dist/likec4diagram/state/utils.d.ts +1 -1
- package/dist/likec4diagram/useLayoutConstraints.js +2 -0
- package/dist/navigationpanel/controls/ToggleReadonly.js +4 -2
- package/dist/navigationpanel/editorpanel/ApplySemanticLayout.d.ts +4 -0
- package/dist/navigationpanel/editorpanel/ApplySemanticLayout.js +36 -0
- package/dist/navigationpanel/editorpanel/EditorPanel.js +45 -33
- package/dist/navigationpanel/walkthrough/DynamicViewControls.d.ts +61 -61
- package/dist/overlays/overlay/Overlay.d.ts +16 -0
- package/dist/overlays/overlay/Overlay.js +50 -52
- package/dist/overlays/overlaysActor.js +28 -27
- package/dist/overlays/relationship-details/custom/nodeTypes.d.ts +4 -5
- package/dist/overlays/relationship-details/custom/nodeTypes.js +25 -24
- package/dist/overlays/relationships-browser/SelectElement.js +2 -2
- package/dist/search/Search.d.ts +6 -3
- package/dist/search/Search.js +60 -71
- package/dist/search/components/ElementsColumn.js +12 -8
- package/dist/search/searchActor.js +30 -26
- package/dist/shadowroot/ShadowRoot.d.ts +7 -6
- package/dist/shadowroot/ShadowRoot.js +59 -20
- package/dist/shadowroot/styles.css.d.ts +10 -2
- package/dist/shadowroot/styles.css.js +33 -36
- package/dist/styles2.js +1 -1
- package/package.json +17 -23
- package/panda.buildinfo.json +15 -15
- package/src/styles-font.css +114 -0
- package/src/styles-min.css +2 -0
- package/src/styles-xyflow.css +1 -0
- package/src/styles.css +3 -0
- package/styles-min.css +1 -1
- package/styles.css +1 -1
- package/dist/bundle/index.d.ts +0 -1
- package/dist/editor/editorActor.actions.d.ts +0 -153
- package/dist/editor/editorActor.actions.js +0 -133
- package/dist/editor/editorActor.states.d.ts +0 -9
- package/dist/editor/editorActor.states.js +0 -219
- package/dist/hooks/useOverlaysActor.js +0 -11
- package/dist/hooks/useSearchActor.js +0 -11
package/dist/LikeC4Diagram.js
CHANGED
|
@@ -36,7 +36,8 @@ function LikeC4Diagram({ onCanvasClick, onCanvasContextMenu, onCanvasDblClick, o
|
|
|
36
36
|
const optionalLikeC4Model = useOptionalLikeC4Model();
|
|
37
37
|
enableCompareWithLatest = enableCompareWithLatest && !!onLayoutTypeChange && !!optionalLikeC4Model && !isEmptyish(optionalLikeC4Model.$data.manualLayouts);
|
|
38
38
|
const hasLikeC4Model = !!optionalLikeC4Model;
|
|
39
|
-
const
|
|
39
|
+
const editor = useOptionalLikeC4Editor();
|
|
40
|
+
const hasEditor = !!editor;
|
|
40
41
|
const readonly = !hasEditor;
|
|
41
42
|
nodesSelectable ??= hasEditor || enableFocusMode || !!onNavigateTo || !!onNodeClick;
|
|
42
43
|
const bounds = pickViewBounds(view, dynamicViewVariant);
|
|
@@ -66,6 +67,7 @@ function LikeC4Diagram({ onCanvasClick, onCanvasContextMenu, onCanvasDblClick, o
|
|
|
66
67
|
features: {
|
|
67
68
|
enableFitView: fitView,
|
|
68
69
|
enableEditor: hasEditor,
|
|
70
|
+
enableAISemanticLayout: hasEditor && !!editor.applySemanticLayout,
|
|
69
71
|
enableReadOnly: readonly,
|
|
70
72
|
enableFocusMode,
|
|
71
73
|
enableNavigateTo: !!onNavigateTo,
|
package/dist/LikeC4View.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import "./_virtual/_rolldown/runtime.js";
|
|
2
|
-
import { useCallbackRef } from "./hooks/useCallbackRef.js";
|
|
3
2
|
import { stopPropagation } from "./utils/xyflow.js";
|
|
4
3
|
import { FitViewPaddings } from "./base/const.js";
|
|
5
4
|
import { useOptionalLikeC4Model } from "./context/LikeC4ModelContext.js";
|
|
@@ -10,11 +9,10 @@ import { ErrorMessage } from "./components/ViewNotFound.js";
|
|
|
10
9
|
import { ShadowRoot } from "./shadowroot/ShadowRoot.js";
|
|
11
10
|
import { css, cx } from "@likec4/styles/css";
|
|
12
11
|
import { IconX } from "@tabler/icons-react";
|
|
13
|
-
import {
|
|
12
|
+
import { useState } from "react";
|
|
14
13
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
15
14
|
import { isBoolean } from "remeda";
|
|
16
15
|
import { ActionIcon } from "@mantine/core";
|
|
17
|
-
import { AnimatePresence } from "motion/react";
|
|
18
16
|
import { Box as Box$1 } from "@likec4/styles/jsx";
|
|
19
17
|
//#region src/LikeC4View.tsx
|
|
20
18
|
var cssInteractive = css({
|
|
@@ -31,20 +29,19 @@ var cssInteractive = css({
|
|
|
31
29
|
* Component is wrapped in ShadowRoot to isolate styles.
|
|
32
30
|
*/
|
|
33
31
|
function LikeC4View({ viewId, className, pannable = false, zoomable = false, keepAspectRatio = true, colorScheme, injectFontCss = true, controls = false, layoutType: initialLayoutType = "manual", background = "transparent", browser = true, showNavigationButtons = false, enableNotations, enableFocusMode = false, enableDynamicViewWalkthrough = false, enableElementDetails = false, enableRelationshipDetails = false, enableRelationshipBrowser = enableRelationshipDetails, enableNotes = false, reduceGraphics = "auto", mantineTheme, styleNonce, style, reactFlowProps, renderNodes, children, ...props }) {
|
|
34
|
-
const rootRef = useRef(null);
|
|
35
32
|
const likec4model = useOptionalLikeC4Model();
|
|
36
33
|
const [layoutType, setLayoutType] = useState(initialLayoutType);
|
|
37
34
|
const [browserViewId, _onNavigateTo] = useState(null);
|
|
38
|
-
const onNavigateTo =
|
|
35
|
+
const onNavigateTo = (viewId) => {
|
|
39
36
|
if (viewId && viewId !== browserViewId) setLayoutType(initialLayoutType);
|
|
40
37
|
_onNavigateTo(viewId);
|
|
41
|
-
}
|
|
42
|
-
const onNavigateToThisView =
|
|
38
|
+
};
|
|
39
|
+
const onNavigateToThisView = () => {
|
|
43
40
|
onNavigateTo(viewId);
|
|
44
|
-
}
|
|
45
|
-
const closeBrowser =
|
|
41
|
+
};
|
|
42
|
+
const closeBrowser = () => {
|
|
46
43
|
onNavigateTo(null);
|
|
47
|
-
}
|
|
44
|
+
};
|
|
48
45
|
if (!likec4model) return /* @__PURE__ */ jsx(ErrorMessage, { children: "LikeC4Model not found. Make sure you have LikeC4ModelProvider in the component tree." });
|
|
49
46
|
const viewModel = likec4model.findView(viewId);
|
|
50
47
|
if (!viewModel) return /* @__PURE__ */ jsxs(ErrorMessage, { children: [
|
|
@@ -70,9 +67,7 @@ function LikeC4View({ viewId, className, pannable = false, zoomable = false, kee
|
|
|
70
67
|
const isBrowserEnabled = browser !== false;
|
|
71
68
|
const browserProps = isBoolean(browser) ? {} : browser;
|
|
72
69
|
const bounds = pickViewBounds(view, props.dynamicViewVariant);
|
|
73
|
-
const root = rootRef.current ? { root: rootRef.current } : void 0;
|
|
74
70
|
return /* @__PURE__ */ jsxs(ShadowRoot, {
|
|
75
|
-
ref: rootRef,
|
|
76
71
|
injectFontCss,
|
|
77
72
|
theme: mantineTheme,
|
|
78
73
|
colorScheme,
|
|
@@ -109,49 +104,46 @@ function LikeC4View({ viewId, className, pannable = false, zoomable = false, kee
|
|
|
109
104
|
renderNodes,
|
|
110
105
|
...props,
|
|
111
106
|
children
|
|
112
|
-
}), /* @__PURE__ */
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
})
|
|
153
|
-
})]
|
|
154
|
-
})
|
|
107
|
+
}), browserView && /* @__PURE__ */ jsxs(Overlay, {
|
|
108
|
+
openDelay: 0,
|
|
109
|
+
onClose: closeBrowser,
|
|
110
|
+
children: [/* @__PURE__ */ jsx(LikeC4Diagram, {
|
|
111
|
+
view: browserView,
|
|
112
|
+
pannable: true,
|
|
113
|
+
zoomable: true,
|
|
114
|
+
background: "dots",
|
|
115
|
+
onNavigateTo,
|
|
116
|
+
showNavigationButtons: true,
|
|
117
|
+
enableDynamicViewWalkthrough: true,
|
|
118
|
+
enableFocusMode: true,
|
|
119
|
+
enableRelationshipBrowser: true,
|
|
120
|
+
enableElementDetails: true,
|
|
121
|
+
enableRelationshipDetails: true,
|
|
122
|
+
enableSearch: true,
|
|
123
|
+
enableElementTags: true,
|
|
124
|
+
enableNotes: true,
|
|
125
|
+
enableCompareWithLatest: true,
|
|
126
|
+
controls: true,
|
|
127
|
+
fitView: true,
|
|
128
|
+
...props,
|
|
129
|
+
fitViewPadding: FitViewPaddings.withControls,
|
|
130
|
+
...browserProps,
|
|
131
|
+
enableNotations: browserViewHasNotations && (browserProps.enableNotations ?? true),
|
|
132
|
+
renderNodes,
|
|
133
|
+
onLayoutTypeChange: setLayoutType
|
|
134
|
+
}), /* @__PURE__ */ jsx(Box$1, {
|
|
135
|
+
pos: "absolute",
|
|
136
|
+
top: "4",
|
|
137
|
+
right: "4",
|
|
138
|
+
zIndex: "999",
|
|
139
|
+
onClick: stopPropagation,
|
|
140
|
+
children: /* @__PURE__ */ jsx(ActionIcon, {
|
|
141
|
+
variant: "default",
|
|
142
|
+
color: "gray",
|
|
143
|
+
onClick: closeBrowser,
|
|
144
|
+
children: /* @__PURE__ */ jsx(IconX, {})
|
|
145
|
+
})
|
|
146
|
+
})]
|
|
155
147
|
})]
|
|
156
148
|
});
|
|
157
149
|
}
|
|
@@ -39,12 +39,8 @@ var ElementsTree = memo(() => {
|
|
|
39
39
|
}
|
|
40
40
|
break;
|
|
41
41
|
}
|
|
42
|
-
case "ArrowUp":
|
|
43
|
-
|
|
44
|
-
break;
|
|
45
|
-
default:
|
|
46
|
-
console.log(e.key);
|
|
47
|
-
return;
|
|
42
|
+
case "ArrowUp": break;
|
|
43
|
+
default: return;
|
|
48
44
|
}
|
|
49
45
|
} }),
|
|
50
46
|
children: /* @__PURE__ */ jsxs(Tree$1.Root, {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import {
|
|
2
|
+
import { RootContainerContextProvider } from "../context/RootContainerContext.js";
|
|
3
3
|
import { cx } from "@likec4/styles/css";
|
|
4
4
|
import { useMemo, useRef, useState } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -13,23 +13,24 @@ function RootContainer({ id, className, reduceGraphics = false, children }) {
|
|
|
13
13
|
const ctx = useMemo(() => ({
|
|
14
14
|
id,
|
|
15
15
|
ref,
|
|
16
|
-
selector: `#${id}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
16
|
+
selector: `#${id}`,
|
|
17
|
+
reducedGraphics: reduceGraphics,
|
|
18
|
+
$panning: $isPanning
|
|
19
|
+
}), [
|
|
20
|
+
id,
|
|
21
|
+
ref,
|
|
22
|
+
reduceGraphics,
|
|
23
|
+
$isPanning
|
|
24
|
+
]);
|
|
25
|
+
return /* @__PURE__ */ jsx("div", {
|
|
26
|
+
id,
|
|
27
|
+
className: cx("likec4-root", className),
|
|
28
|
+
ref,
|
|
29
|
+
"data-likec4-diagram-panning": isPanning,
|
|
30
|
+
...reduceGraphics && { ["data-likec4-reduced-graphics"]: true },
|
|
31
|
+
children: /* @__PURE__ */ jsx(RootContainerContextProvider, {
|
|
32
|
+
value: ctx,
|
|
33
|
+
children
|
|
33
34
|
})
|
|
34
35
|
});
|
|
35
36
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ExclusiveUnion } from '@likec4/core/types';
|
|
2
2
|
import { PropsWithChildren } from 'react';
|
|
3
3
|
import { JSX } from 'react/jsx-runtime';
|
|
4
|
-
declare const FeatureNames: readonly ["Controls", "Editor", "ReadOnly", "FocusMode", "NavigateTo", "ElementDetails", "RelationshipDetails", "RelationshipBrowser", "Search", "NavigationButtons", "Notations", "DynamicViewWalkthrough", "FitView", "CompareWithLatest", "Notes", "Vscode", "ElementTags"];
|
|
4
|
+
declare const FeatureNames: readonly ["Controls", "Editor", "AISemanticLayout", "ReadOnly", "FocusMode", "NavigateTo", "ElementDetails", "RelationshipDetails", "RelationshipBrowser", "Search", "NavigationButtons", "Notations", "DynamicViewWalkthrough", "FitView", "CompareWithLatest", "Notes", "Vscode", "ElementTags"];
|
|
5
5
|
export type FeatureName = typeof FeatureNames[number];
|
|
6
6
|
export type TogglableFeature = ('ReadOnly' | 'CompareWithLatest') & FeatureName;
|
|
7
7
|
export type EnabledFeatures = {
|
|
@@ -6,6 +6,10 @@ import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
|
|
|
6
6
|
//#region src/context/DiagramFeatures.tsx
|
|
7
7
|
var DefaultFeatures = {
|
|
8
8
|
enableEditor: false,
|
|
9
|
+
/**
|
|
10
|
+
* Enabled if editor has `applySemanticLayout` method
|
|
11
|
+
*/
|
|
12
|
+
enableAISemanticLayout: false,
|
|
9
13
|
enableReadOnly: true,
|
|
10
14
|
enableCompareWithLatest: false,
|
|
11
15
|
enableControls: false,
|
|
@@ -51,6 +55,7 @@ function DiagramFeatures({ children, features, overrides }) {
|
|
|
51
55
|
var overridesForOverlays = {
|
|
52
56
|
enableControls: false,
|
|
53
57
|
enableReadOnly: true,
|
|
58
|
+
enableAISemanticLayout: false,
|
|
54
59
|
enableCompareWithLatest: false
|
|
55
60
|
};
|
|
56
61
|
DiagramFeatures.Overlays = ({ children }) => {
|
|
@@ -1,26 +1,19 @@
|
|
|
1
1
|
import { WritableAtom } from 'nanostores';
|
|
2
|
-
import { RefObject, Provider
|
|
3
|
-
export
|
|
4
|
-
id: string;
|
|
5
|
-
selector: string;
|
|
6
|
-
ref: RefObject<HTMLDivElement | null>;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
id: string;
|
|
10
|
-
selector: string;
|
|
11
|
-
ref: RefObject<HTMLDivElement | null>;
|
|
12
|
-
} | null;
|
|
13
|
-
export declare function useRootContainer(): {
|
|
14
|
-
id: string;
|
|
15
|
-
selector: string;
|
|
16
|
-
ref: RefObject<HTMLDivElement | null>;
|
|
2
|
+
import { RefObject, Provider } from 'react';
|
|
3
|
+
export type RootContainerContextType = {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly selector: string;
|
|
6
|
+
readonly ref: RefObject<HTMLDivElement | null>;
|
|
7
|
+
readonly $panning: WritableAtom<boolean>;
|
|
8
|
+
readonly reducedGraphics: boolean;
|
|
17
9
|
};
|
|
10
|
+
export declare const RootContainerContextProvider: Provider<RootContainerContextType | null>;
|
|
11
|
+
export declare function useRootContainerContext(): RootContainerContextType | null;
|
|
12
|
+
export declare function useRootContainer(): RootContainerContextType;
|
|
18
13
|
export declare function useRootContainerRef(): RefObject<HTMLDivElement | null>;
|
|
19
14
|
export declare function useRootContainerElement(): HTMLDivElement | null;
|
|
20
|
-
export declare const ReduceGraphicsModeProvider: Provider<boolean | null>;
|
|
21
15
|
/**
|
|
22
16
|
* Hook to determine if reduced graphics mode is enabled.
|
|
23
17
|
*/
|
|
24
18
|
export declare function useIsReducedGraphics(): boolean;
|
|
25
|
-
export declare const PanningAtomSafeCtx: Context<WritableAtom<boolean> | null>, usePanningAtom: () => WritableAtom<boolean>;
|
|
26
19
|
export declare function useIsPanning(): boolean;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import "../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { createContext, useContext } from "react";
|
|
3
|
-
import { createSafeContext } from "@mantine/core";
|
|
4
3
|
import "@nanostores/react";
|
|
5
4
|
//#region src/context/RootContainerContext.tsx
|
|
6
5
|
var RootContainerContext = createContext(null);
|
|
@@ -19,16 +18,5 @@ function useRootContainerRef() {
|
|
|
19
18
|
function useRootContainerElement() {
|
|
20
19
|
return useRootContainer().ref.current;
|
|
21
20
|
}
|
|
22
|
-
var ReduceGraphicsModeCtx = createContext(null);
|
|
23
|
-
var ReduceGraphicsModeProvider = ReduceGraphicsModeCtx.Provider;
|
|
24
|
-
/**
|
|
25
|
-
* Hook to determine if reduced graphics mode is enabled.
|
|
26
|
-
*/
|
|
27
|
-
function useIsReducedGraphics() {
|
|
28
|
-
const isReduced = useContext(ReduceGraphicsModeCtx);
|
|
29
|
-
if (isReduced === null) console.warn("ReduceGraphicsMode is not provided");
|
|
30
|
-
return isReduced ?? false;
|
|
31
|
-
}
|
|
32
|
-
var [PanningAtomSafeCtx, usePanningAtom] = createSafeContext("PanningAtomSafeCtx is not provided");
|
|
33
21
|
//#endregion
|
|
34
|
-
export {
|
|
22
|
+
export { RootContainerContextProvider, useRootContainer, useRootContainerContext, useRootContainerElement, useRootContainerRef };
|
package/dist/custom/index.d.ts
CHANGED
|
@@ -5,11 +5,11 @@ export * from './primitives';
|
|
|
5
5
|
export type { BaseEdge, BaseEdgeData, BaseEdgeProps, BaseEdgePropsWithData, BaseNode, BaseNodeData, BaseNodeProps, BaseNodePropsWithData, } from '../base/types';
|
|
6
6
|
export type { DiagramNodeWithNavigate, ElementIconRenderer, ElementIconRendererProps, LikeC4ColorScheme, LikeC4DiagramEventHandlers, LikeC4DiagramProperties, NodeRenderers, OnCanvasClick, OnEdgeClick, OnNavigateTo, OnNodeClick, OpenSourceParams, PaddingUnit, PaddingWithUnit, ViewPadding, WhereOperator, } from '../LikeC4Diagram.props';
|
|
7
7
|
export { Base } from '../base/Base';
|
|
8
|
+
export type { XYStoreState } from '../hooks/useXYFlow';
|
|
8
9
|
export type { Types } from '../likec4diagram/types';
|
|
9
10
|
export { type EnabledFeatures, IfEnabled, IfNotEnabled, IfNotReadOnly, IfReadOnly, useEnabledFeatures, } from '../context/DiagramFeatures';
|
|
10
11
|
export { Overlay } from '../overlays/overlay/Overlay';
|
|
11
12
|
export type { OverlayProps } from '../overlays/overlay/Overlay';
|
|
12
13
|
export { PortalToContainer } from '../components/PortalToContainer';
|
|
13
|
-
export { ShadowRoot } from '../shadowroot/ShadowRoot';
|
|
14
14
|
export { FramerMotionConfig } from '../context/FramerMotionConfig';
|
|
15
15
|
export { NavigationPanel } from '../components/NavigationPanel';
|
package/dist/custom/index.js
CHANGED
|
@@ -35,7 +35,6 @@ import { CompoundDeploymentToolbar, CompoundElementToolbar } from "../likec4diag
|
|
|
35
35
|
import { DeploymentElementToolbar, ElementToolbar } from "../likec4diagram/custom/nodes/toolbar/ElementToolbar.js";
|
|
36
36
|
import { CompoundDeploymentNode, CompoundDetailsButtonWithHandler, CompoundElementNode, DeploymentNode, ElementDetailsButtonWithHandler, ElementNode, ViewGroupNode } from "../likec4diagram/custom/nodes/nodes.js";
|
|
37
37
|
import { SequenceActorNode, SequenceParallelArea } from "../likec4diagram/custom/nodes/SequenceActorNode.js";
|
|
38
|
-
import { ShadowRoot } from "../shadowroot/ShadowRoot.js";
|
|
39
38
|
import { NavigationPanel } from "../components/NavigationPanel.js";
|
|
40
39
|
import { compoundDeploymentNode, compoundElementNode, deploymentNode, elementNode, sequenceActorNode, viewGroupNode } from "./customNodes.js";
|
|
41
|
-
export { Base, CompoundActionButton, CompoundActions, CompoundDeploymentNode, CompoundDeploymentToolbar, CompoundDetailsButton, CompoundDetailsButtonWithHandler, CompoundElementNode, CompoundElementToolbar, CompoundNodeContainer, CompoundTitle, DefaultHandles, DeploymentElementActions, DeploymentElementToolbar, DeploymentNode, ElementActionButtons, ElementActions, ElementData, ElementDetailsButton, ElementDetailsButtonWithHandler, ElementNode, ElementNodeContainer, ElementShape, ElementTag, ElementTags, ElementToolbar, FramerMotionConfig, IfEnabled, IfNotEnabled, IfNotReadOnly, IfReadOnly, Markdown, NavigationPanel, Overlay, PortalToContainer, SequenceActorNode, SequenceParallelArea,
|
|
40
|
+
export { Base, CompoundActionButton, CompoundActions, CompoundDeploymentNode, CompoundDeploymentToolbar, CompoundDetailsButton, CompoundDetailsButtonWithHandler, CompoundElementNode, CompoundElementToolbar, CompoundNodeContainer, CompoundTitle, DefaultHandles, DeploymentElementActions, DeploymentElementToolbar, DeploymentNode, ElementActionButtons, ElementActions, ElementData, ElementDetailsButton, ElementDetailsButtonWithHandler, ElementNode, ElementNodeContainer, ElementShape, ElementTag, ElementTags, ElementToolbar, FramerMotionConfig, IfEnabled, IfNotEnabled, IfNotReadOnly, IfReadOnly, Markdown, NavigationPanel, Overlay, PortalToContainer, SequenceActorNode, SequenceParallelArea, Toolbar, ViewGroupNode, compoundDeploymentNode, compoundElementNode, deploymentNode, elementNode, memoEdge, memoNode, sequenceActorNode, useCurrentView, useCurrentViewId, useCurrentViewModel, useDiagram, useDiagramActorRef, useDiagramContext, useDiagramEventHandlers, useEnabledFeatures, useHasProjects, useLikeC4Model, useLikeC4Project, useLikeC4ProjectId, useLikeC4Projects, useLikeC4ProjectsContext, useLikeC4Specification, useLikeC4Styles, useLikeC4ViewModel, useOnDiagramEvent, useOptionalCurrentViewModel, useOptionalLikeC4Model, useSetState, useUpdateEffect, viewGroupNode };
|
|
@@ -3,6 +3,11 @@ import type * as t from '@likec4/core/types';
|
|
|
3
3
|
* Callbacks from LikeC4 Editor.
|
|
4
4
|
*/
|
|
5
5
|
export interface LikeC4EditorCallbacks {
|
|
6
|
+
/**
|
|
7
|
+
* Apply semantic layout to a view (if AI is available)
|
|
8
|
+
* See vite-plugin settings for more details
|
|
9
|
+
*/
|
|
10
|
+
applySemanticLayout?: undefined | ((viewId: t.ViewId) => Promise<void>);
|
|
6
11
|
/**
|
|
7
12
|
* Fetch a view by its ID and layout type.
|
|
8
13
|
*
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { ActorSystem, ActionFunction, CancelAction, PromiseActorLogic, EventObject, NonReducibleUnknown } from 'xstate';
|
|
2
|
+
import { DiagramMachineRef } from '../../likec4diagram/state/machine';
|
|
3
|
+
import { Snapshot, EditorActorContext, EditorActorEvent, EditorActorEmitedEvent } from './types';
|
|
4
|
+
import { HotkeyActorLogic } from './hotkey';
|
|
5
|
+
import type * as t from '@likec4/core/types';
|
|
6
|
+
/**
|
|
7
|
+
* Actually this is DiagramActorRef
|
|
8
|
+
* But we can't use it here due to circular type inference
|
|
9
|
+
*/
|
|
10
|
+
export declare const diagramActorRef: (system: ActorSystem<any>) => DiagramMachineRef;
|
|
11
|
+
export declare function makeSnapshot(system: ActorSystem<any>): Snapshot;
|
|
12
|
+
type LayoutChanges = t.ViewChange.ResetManualLayout | t.ViewChange.SaveViewSnapshot;
|
|
13
|
+
export declare const isLayoutChange: (change: t.ViewChange) => change is LayoutChanges;
|
|
14
|
+
export declare const withoutSnapshotChanges: (data: t.ViewChange[]) => (t.ViewChange.ChangeElementStyle | t.ViewChange.ChangeAutoLayout | t.ViewChange.ChangeProperty)[];
|
|
15
|
+
export declare const scheduleSync: (delay?: number) => ActionFunction<EditorActorContext, EditorActorEvent, EditorActorEvent, undefined, never, never, never, "500ms" | "wait-after-edit", never>;
|
|
16
|
+
export declare const cancelSync: () => CancelAction<EditorActorContext, EditorActorEvent, undefined, EditorActorEvent>;
|
|
17
|
+
/**
|
|
18
|
+
* Save the state before editing starts
|
|
19
|
+
*/
|
|
20
|
+
export declare const saveBeforeEditing: ActionFunction<EditorActorContext, EditorActorEvent, EditorActorEvent, undefined, {
|
|
21
|
+
src: "hotkey";
|
|
22
|
+
logic: HotkeyActorLogic;
|
|
23
|
+
id: "hotkey";
|
|
24
|
+
} | {
|
|
25
|
+
src: "applyLatest";
|
|
26
|
+
logic: PromiseActorLogic<import("./setup").EditorCalls.ApplyLatestToManual.Output, import("./setup").EditorCalls.ApplyLatestToManual.Input, EventObject>;
|
|
27
|
+
id: string | undefined;
|
|
28
|
+
} | {
|
|
29
|
+
src: "executeChange";
|
|
30
|
+
logic: PromiseActorLogic<NonReducibleUnknown, import("./setup").EditorCalls.ExecuteChange.Input, EventObject>;
|
|
31
|
+
id: string | undefined;
|
|
32
|
+
} | {
|
|
33
|
+
src: "applySemanticLayout";
|
|
34
|
+
logic: PromiseActorLogic<import("./setup").EditorCalls.ApplySemanticLayout.Output, import("./setup").EditorCalls.ApplySemanticLayout.Input, EventObject>;
|
|
35
|
+
id: string | undefined;
|
|
36
|
+
}, never, never, never, never>;
|
|
37
|
+
/**
|
|
38
|
+
* When editing finishes, push the "beforeEditing" state to the history stack
|
|
39
|
+
*/
|
|
40
|
+
export declare const pushHistory: () => ActionFunction<EditorActorContext, EditorActorEvent, EditorActorEvent, undefined, {
|
|
41
|
+
src: "hotkey";
|
|
42
|
+
logic: HotkeyActorLogic;
|
|
43
|
+
id: "hotkey";
|
|
44
|
+
} | {
|
|
45
|
+
src: "applyLatest";
|
|
46
|
+
logic: PromiseActorLogic<import("./setup").EditorCalls.ApplyLatestToManual.Output, import("./setup").EditorCalls.ApplyLatestToManual.Input, EventObject>;
|
|
47
|
+
id: string | undefined;
|
|
48
|
+
} | {
|
|
49
|
+
src: "executeChange";
|
|
50
|
+
logic: PromiseActorLogic<NonReducibleUnknown, import("./setup").EditorCalls.ExecuteChange.Input, EventObject>;
|
|
51
|
+
id: string | undefined;
|
|
52
|
+
} | {
|
|
53
|
+
src: "applySemanticLayout";
|
|
54
|
+
logic: PromiseActorLogic<import("./setup").EditorCalls.ApplySemanticLayout.Output, import("./setup").EditorCalls.ApplySemanticLayout.Input, EventObject>;
|
|
55
|
+
id: string | undefined;
|
|
56
|
+
}, never, never, never, never>;
|
|
57
|
+
export declare const reschedule: (delay?: number) => ActionFunction<EditorActorContext, EditorActorEvent, EditorActorEvent, undefined, never, never, never, "500ms" | "wait-after-edit", never>;
|
|
58
|
+
export declare const undo: () => ActionFunction<EditorActorContext, EditorActorEvent, EditorActorEvent, undefined, {
|
|
59
|
+
src: "hotkey";
|
|
60
|
+
logic: HotkeyActorLogic;
|
|
61
|
+
id: "hotkey";
|
|
62
|
+
} | {
|
|
63
|
+
src: "applyLatest";
|
|
64
|
+
logic: PromiseActorLogic<import("./setup").EditorCalls.ApplyLatestToManual.Output, import("./setup").EditorCalls.ApplyLatestToManual.Input, EventObject>;
|
|
65
|
+
id: string | undefined;
|
|
66
|
+
} | {
|
|
67
|
+
src: "executeChange";
|
|
68
|
+
logic: PromiseActorLogic<NonReducibleUnknown, import("./setup").EditorCalls.ExecuteChange.Input, EventObject>;
|
|
69
|
+
id: string | undefined;
|
|
70
|
+
} | {
|
|
71
|
+
src: "applySemanticLayout";
|
|
72
|
+
logic: PromiseActorLogic<import("./setup").EditorCalls.ApplySemanticLayout.Output, import("./setup").EditorCalls.ApplySemanticLayout.Input, EventObject>;
|
|
73
|
+
id: string | undefined;
|
|
74
|
+
}, never, {
|
|
75
|
+
type: "has pending";
|
|
76
|
+
params: unknown;
|
|
77
|
+
} | {
|
|
78
|
+
type: "can undo";
|
|
79
|
+
params: unknown;
|
|
80
|
+
}, "500ms" | "wait-after-edit", EditorActorEmitedEvent>;
|
|
81
|
+
export declare const pushToSyncQueue: () => ActionFunction<EditorActorContext, EditorActorEvent, EditorActorEvent, undefined, {
|
|
82
|
+
src: "hotkey";
|
|
83
|
+
logic: HotkeyActorLogic;
|
|
84
|
+
id: "hotkey";
|
|
85
|
+
} | {
|
|
86
|
+
src: "applyLatest";
|
|
87
|
+
logic: PromiseActorLogic<import("./setup").EditorCalls.ApplyLatestToManual.Output, import("./setup").EditorCalls.ApplyLatestToManual.Input, EventObject>;
|
|
88
|
+
id: string | undefined;
|
|
89
|
+
} | {
|
|
90
|
+
src: "executeChange";
|
|
91
|
+
logic: PromiseActorLogic<NonReducibleUnknown, import("./setup").EditorCalls.ExecuteChange.Input, EventObject>;
|
|
92
|
+
id: string | undefined;
|
|
93
|
+
} | {
|
|
94
|
+
src: "applySemanticLayout";
|
|
95
|
+
logic: PromiseActorLogic<import("./setup").EditorCalls.ApplySemanticLayout.Output, import("./setup").EditorCalls.ApplySemanticLayout.Input, EventObject>;
|
|
96
|
+
id: string | undefined;
|
|
97
|
+
}, never, never, never, never>;
|
|
98
|
+
export declare const clearQueue: () => ActionFunction<EditorActorContext, EditorActorEvent, EditorActorEvent, undefined, {
|
|
99
|
+
src: "hotkey";
|
|
100
|
+
logic: HotkeyActorLogic;
|
|
101
|
+
id: "hotkey";
|
|
102
|
+
} | {
|
|
103
|
+
src: "applyLatest";
|
|
104
|
+
logic: PromiseActorLogic<import("./setup").EditorCalls.ApplyLatestToManual.Output, import("./setup").EditorCalls.ApplyLatestToManual.Input, EventObject>;
|
|
105
|
+
id: string | undefined;
|
|
106
|
+
} | {
|
|
107
|
+
src: "executeChange";
|
|
108
|
+
logic: PromiseActorLogic<NonReducibleUnknown, import("./setup").EditorCalls.ExecuteChange.Input, EventObject>;
|
|
109
|
+
id: string | undefined;
|
|
110
|
+
} | {
|
|
111
|
+
src: "applySemanticLayout";
|
|
112
|
+
logic: PromiseActorLogic<import("./setup").EditorCalls.ApplySemanticLayout.Output, import("./setup").EditorCalls.ApplySemanticLayout.Input, EventObject>;
|
|
113
|
+
id: string | undefined;
|
|
114
|
+
}, never, never, never, never>;
|
|
115
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import "../../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { machine } from "./setup.js";
|
|
3
|
+
import { createViewChange } from "../../likec4diagram/state/createViewChange.js";
|
|
4
|
+
import { typedSystem } from "../../likec4diagram/state/utils.js";
|
|
5
|
+
import { isViewChange } from "./types.js";
|
|
6
|
+
import { filter, isNot, omit } from "remeda";
|
|
7
|
+
import { assertEvent } from "xstate";
|
|
8
|
+
//#region src/editor/actor/actions.ts
|
|
9
|
+
/**
|
|
10
|
+
* Actually this is DiagramActorRef
|
|
11
|
+
* But we can't use it here due to circular type inference
|
|
12
|
+
*/
|
|
13
|
+
var getDiagramContext = function(system) {
|
|
14
|
+
return system.get("diagram").getSnapshot().context;
|
|
15
|
+
};
|
|
16
|
+
function makeSnapshot(system) {
|
|
17
|
+
const parentContext = getDiagramContext(system);
|
|
18
|
+
return {
|
|
19
|
+
xynodes: parentContext.xynodes.map(({ measured, data, ...n }) => ({
|
|
20
|
+
...omit(n, [
|
|
21
|
+
"selected",
|
|
22
|
+
"dragging",
|
|
23
|
+
"resizing"
|
|
24
|
+
]),
|
|
25
|
+
data: omit(data, ["dimmed", "hovered"]),
|
|
26
|
+
measured,
|
|
27
|
+
initialWidth: measured?.width ?? n.width ?? n.initialWidth,
|
|
28
|
+
initialHeight: measured?.height ?? n.height ?? n.initialHeight
|
|
29
|
+
})),
|
|
30
|
+
xyedges: parentContext.xyedges.map(({ data, ...e }) => ({
|
|
31
|
+
...omit(e, ["selected"]),
|
|
32
|
+
data: omit(data, [
|
|
33
|
+
"active",
|
|
34
|
+
"dimmed",
|
|
35
|
+
"hovered"
|
|
36
|
+
])
|
|
37
|
+
})),
|
|
38
|
+
change: createViewChange(parentContext),
|
|
39
|
+
view: parentContext.view
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
var isLayoutChange = (change) => change.op === "reset-manual-layout" || change.op === "save-view-snapshot";
|
|
43
|
+
filter(isNot(isLayoutChange));
|
|
44
|
+
var scheduleSync = (delay = 50) => {
|
|
45
|
+
return machine.raise({ type: "change.sync-snapshot" }, delay ? {
|
|
46
|
+
delay,
|
|
47
|
+
id: "sync-snapshot"
|
|
48
|
+
} : void 0);
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Save the state before editing starts
|
|
52
|
+
*/
|
|
53
|
+
var saveBeforeEditing = machine.assign(({ system, event }) => {
|
|
54
|
+
assertEvent(event, "edit.move.start");
|
|
55
|
+
return { editing: {
|
|
56
|
+
subject: event.subject,
|
|
57
|
+
before: makeSnapshot(system)
|
|
58
|
+
} };
|
|
59
|
+
});
|
|
60
|
+
/**
|
|
61
|
+
* When editing finishes, push the "beforeEditing" state to the history stack
|
|
62
|
+
*/
|
|
63
|
+
var pushHistory = () => machine.assign(({ context }) => {
|
|
64
|
+
const editing = context.editing;
|
|
65
|
+
if (editing) return {
|
|
66
|
+
editing: null,
|
|
67
|
+
history: {
|
|
68
|
+
head: editing.before,
|
|
69
|
+
tail: context.history
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
return {};
|
|
73
|
+
});
|
|
74
|
+
var reschedule = (delay = 300) => machine.raise(({ event }) => ({ ...event }), { delay });
|
|
75
|
+
var undo = () => machine.enqueueActions(({ context: { history }, enqueue }) => {
|
|
76
|
+
if (!history) return;
|
|
77
|
+
const last = history.head;
|
|
78
|
+
enqueue.assign({ history: history.tail });
|
|
79
|
+
enqueue.sendTo(typedSystem.diagramActor, {
|
|
80
|
+
type: "update.view",
|
|
81
|
+
view: last.view,
|
|
82
|
+
xyedges: last.xyedges,
|
|
83
|
+
xynodes: last.xynodes,
|
|
84
|
+
source: "editor"
|
|
85
|
+
});
|
|
86
|
+
enqueue.cancel("undo-view");
|
|
87
|
+
enqueue.raise({
|
|
88
|
+
type: "change.view",
|
|
89
|
+
change: last.change
|
|
90
|
+
}, {
|
|
91
|
+
delay: 200,
|
|
92
|
+
id: "undo-view"
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
var pushToSyncQueue = () => machine.assign(({ context: { syncQueue }, event }) => {
|
|
96
|
+
let nextOp;
|
|
97
|
+
switch (event.type) {
|
|
98
|
+
case "change.view":
|
|
99
|
+
nextOp = event.change;
|
|
100
|
+
break;
|
|
101
|
+
case "change.semantic-layout":
|
|
102
|
+
nextOp = "apply-semantic-layout";
|
|
103
|
+
break;
|
|
104
|
+
case "change.latest-to-manual":
|
|
105
|
+
nextOp = "apply-semantic-layout";
|
|
106
|
+
break;
|
|
107
|
+
case "change.sync-snapshot":
|
|
108
|
+
nextOp = "sync-snapshot";
|
|
109
|
+
break;
|
|
110
|
+
default: throw new Error(`Invalid event type: ${event.type}`);
|
|
111
|
+
}
|
|
112
|
+
if (syncQueue.length === 0) return { syncQueue: [nextOp] };
|
|
113
|
+
const isNextLayoutChange = isViewChange(nextOp) && isLayoutChange(nextOp);
|
|
114
|
+
let pending = syncQueue.filter((existingOp) => {
|
|
115
|
+
if (existingOp === nextOp) return false;
|
|
116
|
+
if (isNextLayoutChange && isViewChange(existingOp) && isLayoutChange(existingOp)) return false;
|
|
117
|
+
return true;
|
|
118
|
+
});
|
|
119
|
+
return { syncQueue: pending.length > 0 ? [...pending, nextOp] : [nextOp] };
|
|
120
|
+
});
|
|
121
|
+
//#endregion
|
|
122
|
+
export { makeSnapshot, pushHistory, pushToSyncQueue, reschedule, saveBeforeEditing, scheduleSync, undo };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "
|
|
1
|
+
import "../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { getHotkeyHandler } from "@mantine/hooks";
|
|
3
3
|
import { fromCallback } from "xstate";
|
|
4
|
-
//#region src/editor/
|
|
5
|
-
var
|
|
4
|
+
//#region src/editor/actor/hotkey.ts
|
|
5
|
+
var hotkey = fromCallback(({ sendBack }) => {
|
|
6
6
|
const ctrlZHandler = getHotkeyHandler([[
|
|
7
7
|
"mod + z",
|
|
8
8
|
(event) => {
|
|
@@ -17,4 +17,4 @@ var hotkeyActorLogic = fromCallback(({ sendBack }) => {
|
|
|
17
17
|
};
|
|
18
18
|
});
|
|
19
19
|
//#endregion
|
|
20
|
-
export {
|
|
20
|
+
export { hotkey };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ActorRef, SnapshotFrom, StateMachine } from 'xstate';
|
|
2
|
+
import { EditorActorEvent, EditorActorContext, EditorActorEmitedEvent, EditorActorInput, EditorActorStateTag } from './types';
|
|
3
|
+
export interface EditorActorLogic extends StateMachine<EditorActorContext, EditorActorEvent, any, any, any, any, any, {
|
|
4
|
+
editor: 'idle' | 'moving';
|
|
5
|
+
syncQueue: 'idle' | 'pending' | 'suspended' | 'process';
|
|
6
|
+
}, EditorActorStateTag, EditorActorInput, any, EditorActorEmitedEvent, any, any> {
|
|
7
|
+
}
|
|
8
|
+
export declare const editorActorLogic: EditorActorLogic;
|
|
9
|
+
export type EditorActorSnapshot = SnapshotFrom<EditorActorLogic>;
|
|
10
|
+
export interface EditorActorRef extends ActorRef<EditorActorSnapshot, EditorActorEvent, EditorActorEmitedEvent> {
|
|
11
|
+
}
|