@likec4/diagram 1.7.1 → 1.7.3
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 +38 -22
- package/dist/StaticLikeC4Diagram.d.ts +1 -1
- package/dist/globals.css.d.ts +0 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/{state/useDiagramStore.d.ts → hooks/useDiagramState.d.ts} +2 -3
- package/dist/{xyflow/hooks → hooks}/useXYFlow.d.ts +10 -10
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +755 -401
- package/dist/state/DiagramContext.d.ts +74 -30
- package/dist/state/diagram-to-xyflow.d.ts +2 -0
- package/dist/state/diagramStore.d.ts +71 -22
- package/dist/style.css +655 -35
- package/dist/ui/top-left/ChangeAutoLayoutButton.d.ts +3 -0
- package/dist/ui/top-left/TopLeftPanel.d.ts +4 -0
- package/dist/ui/top-left/_shared.d.ts +5 -0
- package/dist/ui/top-left/styles.css.d.ts +3 -0
- package/dist/xyflow/XYFlowInner.d.ts +0 -1
- package/dist/xyflow/edges/edges.css.d.ts +1 -1
- package/dist/xyflow/{hooks/useLayoutConstraints.d.ts → useLayoutConstraints.d.ts} +1 -1
- package/dist/xyflow/utils.d.ts +11 -1
- package/package.json +6 -6
- package/src/LikeC4Diagram.props.ts +66 -32
- package/src/LikeC4Diagram.tsx +19 -12
- package/src/StaticLikeC4Diagram.tsx +2 -0
- package/src/globals.css.ts +0 -2
- package/src/hooks/index.ts +2 -0
- package/src/{state/useDiagramStore.ts → hooks/useDiagramState.ts} +3 -4
- package/src/{xyflow/hooks → hooks}/useXYFlow.ts +1 -1
- package/src/index.ts +4 -2
- package/src/state/DiagramContext.tsx +15 -7
- package/src/state/diagram-to-xyflow.ts +17 -3
- package/src/state/diagramStore.ts +73 -38
- package/src/ui/DiagramTitlePanel.tsx +1 -1
- package/src/ui/DynamicViewWalkthrough.tsx +1 -2
- package/src/ui/OptionsPanel.tsx +1 -1
- package/src/ui/options/EdgeOptions.tsx +1 -16
- package/src/ui/options/NodeOptions.tsx +38 -13
- package/src/ui/top-left/ChangeAutoLayoutButton.tsx +131 -0
- package/src/ui/top-left/TopLeftPanel.tsx +213 -0
- package/src/ui/top-left/_shared.ts +19 -0
- package/src/ui/top-left/styles.css.ts +38 -0
- package/src/xyflow/FitviewOnDiagramChange.tsx +2 -2
- package/src/xyflow/SelectEdgesOnNodeFocus.tsx +87 -59
- package/src/xyflow/XYFlow.tsx +7 -8
- package/src/xyflow/XYFlowEvents.tsx +39 -19
- package/src/xyflow/XYFlowInner.tsx +5 -7
- package/src/xyflow/edges/RelationshipEdge.tsx +60 -27
- package/src/xyflow/edges/edges.css.ts +29 -25
- package/src/xyflow/nodes/compound/CompoundNode.tsx +1 -1
- package/src/xyflow/nodes/element/ElementLink.tsx +1 -2
- package/src/xyflow/nodes/element/ElementNode.tsx +7 -5
- package/src/xyflow/nodes/shared/NavigateToBtn.tsx +1 -1
- package/src/xyflow/{hooks/useLayoutConstraints.ts → useLayoutConstraints.ts} +3 -3
- package/src/xyflow/utils.ts +25 -1
- package/dist/state/hooks.d.ts +0 -4
- package/dist/state/index.d.ts +0 -2
- package/dist/state/useNavigationHistory.d.ts +0 -5
- package/dist/types.d.ts +0 -20
- package/dist/ui/BackwardForwardPanel.css.d.ts +0 -1
- package/dist/ui/BackwardForwardPanel.d.ts +0 -1
- package/dist/xyflow/hooks/index.d.ts +0 -2
- package/src/state/hooks.ts +0 -5
- package/src/state/index.ts +0 -2
- package/src/state/useNavigationHistory.ts +0 -39
- package/src/types.ts +0 -22
- package/src/ui/BackwardForwardPanel.css.ts +0 -22
- package/src/ui/BackwardForwardPanel.tsx +0 -76
- package/src/xyflow/hooks/index.ts +0 -3
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const Tooltip: import('react').ForwardRefExoticComponent<import('@mantine/core').TooltipProps & import('react').RefAttributes<HTMLDivElement> & {
|
|
2
|
+
component?: any;
|
|
3
|
+
renderRoot?: (props: Record<string, any>) => React.ReactNode;
|
|
4
|
+
}>;
|
|
5
|
+
export declare const ActionIcon: <L = "button">(props: import('@mantine/core').PolymorphicComponentProps<L, import('@mantine/core').ActionIconProps>) => React.ReactElement;
|
|
@@ -5,7 +5,6 @@ type XYFlowInnerProps = PropsWithChildren<{
|
|
|
5
5
|
background: NonNullable<LikeC4DiagramProperties['background']>;
|
|
6
6
|
controls: boolean;
|
|
7
7
|
showDiagramTitle: boolean;
|
|
8
|
-
showNavigationButtons: boolean;
|
|
9
8
|
}>;
|
|
10
9
|
export declare const XYFlowInner: import('react').NamedExoticComponent<XYFlowInnerProps>;
|
|
11
10
|
export {};
|
|
@@ -5,8 +5,8 @@ export declare const markerContext: string;
|
|
|
5
5
|
export declare const controlPoint: string;
|
|
6
6
|
export declare const controlDragging: string;
|
|
7
7
|
export declare const cssEdgePath: string;
|
|
8
|
+
export declare const stepEdgeNumber: string;
|
|
8
9
|
export declare const varLabelX: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
|
|
9
10
|
export declare const varLabelY: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
|
|
10
11
|
export declare const edgeLabel: string;
|
|
11
|
-
export declare const stepEdgeNumber: string;
|
|
12
12
|
export declare const edgeLabelText: string;
|
package/dist/xyflow/utils.d.ts
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import { DiagramEdge, Point } from '@likec4/core/types';
|
|
2
|
-
import { XYPosition } from '@xyflow/react';
|
|
2
|
+
import { Rect, XYPosition } from '@xyflow/react';
|
|
3
|
+
import { InternalXYFlowNode } from './types';
|
|
3
4
|
|
|
4
5
|
export declare function toDomPrecision(v: number | null): number;
|
|
5
6
|
export declare function distance(a: XYPosition, b: XYPosition): number;
|
|
7
|
+
export declare const nodeToRect: (nd: InternalXYFlowNode) => Rect;
|
|
8
|
+
/**
|
|
9
|
+
* Checks if a rectangle is completely inside another rectangle.
|
|
10
|
+
*
|
|
11
|
+
* @param test - The rectangle to test.
|
|
12
|
+
* @param target - The target rectangle.
|
|
13
|
+
* @returns `true` if the `test` rectangle is completely inside the `target` rectangle, otherwise `false`.
|
|
14
|
+
*/
|
|
15
|
+
export declare const isInside: (test: Rect, target: Rect) => boolean;
|
|
6
16
|
export declare function bezierControlPoints(diagramEdge: DiagramEdge): XYPosition[];
|
|
7
17
|
export declare function isSamePoint(a: XYPosition | Point, b: XYPosition | Point): boolean;
|
|
8
18
|
export declare function distanceBetweenPoints(a: XYPosition, b: XYPosition): number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@likec4/diagram",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"bugs": "https://github.com/likec4/likec4/issues",
|
|
6
6
|
"homepage": "https://likec4.dev",
|
|
@@ -54,27 +54,27 @@
|
|
|
54
54
|
"@vanilla-extract/css": "^1.15.3",
|
|
55
55
|
"@vanilla-extract/css-utils": "^0.1.4",
|
|
56
56
|
"@vanilla-extract/dynamic": "^2.1.1",
|
|
57
|
-
"@xyflow/react": "12.0.
|
|
57
|
+
"@xyflow/react": "12.0.4",
|
|
58
58
|
"@xyflow/system": "0.0.37",
|
|
59
59
|
"bezier-js": "^6.1.4",
|
|
60
60
|
"clsx": "^2.1.1",
|
|
61
61
|
"d3-shape": "^3.2.0",
|
|
62
62
|
"esm-env": "^1.0.0",
|
|
63
63
|
"fast-equals": "^5.0.1",
|
|
64
|
-
"framer-motion": "^11.3.
|
|
64
|
+
"framer-motion": "^11.3.24",
|
|
65
65
|
"remeda": "^2.3.0",
|
|
66
66
|
"zustand": "^4.5.4"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@likec4/core": "1.7.
|
|
69
|
+
"@likec4/core": "1.7.3",
|
|
70
70
|
"@mantine/core": "^7.11.2",
|
|
71
71
|
"@mantine/hooks": "^7.11.2",
|
|
72
72
|
"react": "^18.3.1",
|
|
73
73
|
"react-dom": "^18.3.1"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@likec4/core": "1.7.
|
|
77
|
-
"@likec4/tsconfig": "1.7.
|
|
76
|
+
"@likec4/core": "1.7.3",
|
|
77
|
+
"@likec4/tsconfig": "1.7.3",
|
|
78
78
|
"@mantine/core": "7.11.2",
|
|
79
79
|
"@mantine/hooks": "7.11.2",
|
|
80
80
|
"@mantine/vanilla-extract": "7.11.2",
|
|
@@ -1,20 +1,73 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
BorderStyle,
|
|
3
2
|
DiagramEdge,
|
|
4
3
|
DiagramNode,
|
|
5
4
|
DiagramView,
|
|
6
|
-
ElementShape,
|
|
7
5
|
Fqn,
|
|
8
6
|
NonEmptyArray,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
RelationID,
|
|
8
|
+
ViewChange,
|
|
9
|
+
ViewID
|
|
12
10
|
} from '@likec4/core'
|
|
13
11
|
import type { MouseEvent as ReactMouseEvent, ReactNode } from 'react'
|
|
14
|
-
import type { DiagramEditorCommand } from './types'
|
|
15
12
|
import type { XYFlowEdge, XYFlowNode } from './xyflow/types'
|
|
16
13
|
import type { XYBackground } from './xyflow/XYFlowBackground'
|
|
17
14
|
|
|
15
|
+
type EqualOperator<V> = {
|
|
16
|
+
eq: V
|
|
17
|
+
neq?: never
|
|
18
|
+
} | {
|
|
19
|
+
eq?: never
|
|
20
|
+
neq: V
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type AllNever = {
|
|
24
|
+
not?: never
|
|
25
|
+
and?: never
|
|
26
|
+
or?: never
|
|
27
|
+
tag?: never
|
|
28
|
+
kind?: never
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type TagKindOperator<Tag, Kind> =
|
|
32
|
+
& Omit<AllNever, 'tag' | 'kind'>
|
|
33
|
+
& ({
|
|
34
|
+
tag: EqualOperator<Tag>
|
|
35
|
+
kind?: never
|
|
36
|
+
} | {
|
|
37
|
+
tag?: never
|
|
38
|
+
kind: EqualOperator<Kind>
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
type NotOperator<Tag, Kind> = Omit<AllNever, 'not'> & {
|
|
42
|
+
not: TagKindOperator<Tag, Kind> | AndOperator<Tag, Kind> | OrOperator<Tag, Kind>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
type AndOperator<Tag, Kind> = Omit<AllNever, 'and'> & {
|
|
46
|
+
and: NonEmptyArray<
|
|
47
|
+
| TagKindOperator<Tag, Kind>
|
|
48
|
+
| OrOperator<Tag, Kind>
|
|
49
|
+
| NotOperator<Tag, Kind>
|
|
50
|
+
>
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
type OrOperator<Tag, Kind> = Omit<AllNever, 'or'> & {
|
|
54
|
+
or: NonEmptyArray<
|
|
55
|
+
| TagKindOperator<Tag, Kind>
|
|
56
|
+
| AndOperator<Tag, Kind>
|
|
57
|
+
| NotOperator<Tag, Kind>
|
|
58
|
+
>
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// export const isOrOperator = (operator: WhereOperator): operator is OrOperator<WhereOperator> => {
|
|
62
|
+
// return 'or' in operator
|
|
63
|
+
// }
|
|
64
|
+
|
|
65
|
+
export type WhereOperator<Tag extends string, Kind extends string> =
|
|
66
|
+
| TagKindOperator<Tag, Kind>
|
|
67
|
+
| NotOperator<Tag, Kind>
|
|
68
|
+
| AndOperator<Tag, Kind>
|
|
69
|
+
| OrOperator<Tag, Kind>
|
|
70
|
+
|
|
18
71
|
export type DiagramNodeWithNavigate = Omit<DiagramNode, 'navigateTo'> & {
|
|
19
72
|
navigateTo: ViewID
|
|
20
73
|
}
|
|
@@ -53,37 +106,13 @@ export type OnEdgeClick = (
|
|
|
53
106
|
}
|
|
54
107
|
) => void
|
|
55
108
|
|
|
56
|
-
export type OnEditorCommand = (
|
|
57
|
-
cmd: DiagramEditorCommand
|
|
58
|
-
) => void
|
|
59
|
-
|
|
60
109
|
/**
|
|
61
110
|
* On pane/canvas click (not on any node or edge)
|
|
62
111
|
*/
|
|
63
112
|
export type OnCanvasClick = (event: ReactMouseEvent) => void
|
|
64
113
|
|
|
65
|
-
export namespace Changes {
|
|
66
|
-
export interface ChangeElementStyle {
|
|
67
|
-
op: 'change-element-style'
|
|
68
|
-
style: {
|
|
69
|
-
border?: BorderStyle
|
|
70
|
-
opacity?: number
|
|
71
|
-
shape?: ElementShape
|
|
72
|
-
color?: ThemeColor
|
|
73
|
-
}
|
|
74
|
-
targets: NonEmptyArray<Fqn>
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export interface SaveManualLayout {
|
|
78
|
-
op: 'save-manual-layout'
|
|
79
|
-
layout: ViewManualLayout
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export type Change = Changes.ChangeElementStyle | Changes.SaveManualLayout
|
|
84
|
-
|
|
85
114
|
export type ChangeEvent = {
|
|
86
|
-
change:
|
|
115
|
+
change: ViewChange
|
|
87
116
|
}
|
|
88
117
|
export type OnChange = {
|
|
89
118
|
(event: ChangeEvent): void
|
|
@@ -197,6 +226,8 @@ export interface LikeC4DiagramProperties {
|
|
|
197
226
|
* By default, if icon is http:// or https://, it will be rendered as an image
|
|
198
227
|
*/
|
|
199
228
|
renderIcon?: ElementIconRenderer | undefined
|
|
229
|
+
|
|
230
|
+
where?: WhereOperator<string, string> | undefined
|
|
200
231
|
}
|
|
201
232
|
|
|
202
233
|
export interface LikeC4DiagramEventHandlers {
|
|
@@ -210,5 +241,8 @@ export interface LikeC4DiagramEventHandlers {
|
|
|
210
241
|
onCanvasClick?: OnCanvasClick | null | undefined
|
|
211
242
|
onCanvasDblClick?: OnCanvasClick | null | undefined
|
|
212
243
|
|
|
213
|
-
|
|
244
|
+
onBurgerMenuClick?: null | undefined | (() => void)
|
|
245
|
+
onOpenSourceView?: null | undefined | (() => void)
|
|
246
|
+
onOpenSourceElement?: null | undefined | ((fqn: Fqn) => void)
|
|
247
|
+
onOpenSourceRelation?: null | undefined | ((id: RelationID) => void)
|
|
214
248
|
}
|
package/src/LikeC4Diagram.tsx
CHANGED
|
@@ -4,11 +4,11 @@ import { shallowEqual } from 'fast-equals'
|
|
|
4
4
|
import { domAnimation, LazyMotion } from 'framer-motion'
|
|
5
5
|
import { memo, useRef } from 'react'
|
|
6
6
|
import { rootClassName } from './globals.css'
|
|
7
|
+
import { useDiagramState } from './hooks/useDiagramState'
|
|
7
8
|
import * as css from './LikeC4Diagram.css'
|
|
8
9
|
import { type LikeC4DiagramEventHandlers, type LikeC4DiagramProperties } from './LikeC4Diagram.props'
|
|
9
10
|
import { EnsureMantine } from './mantine/EnsureMantine'
|
|
10
11
|
import { DiagramContextProvider } from './state/DiagramContext'
|
|
11
|
-
import { useDiagramState } from './state/useDiagramStore'
|
|
12
12
|
import { FitViewOnDiagramChange } from './xyflow/FitviewOnDiagramChange'
|
|
13
13
|
import { SelectEdgesOnNodeFocus } from './xyflow/SelectEdgesOnNodeFocus'
|
|
14
14
|
import type { XYFlowEdge, XYFlowNode } from './xyflow/types'
|
|
@@ -30,9 +30,8 @@ export function LikeC4Diagram({
|
|
|
30
30
|
controls = false,
|
|
31
31
|
showElementLinks = true,
|
|
32
32
|
showDiagramTitle = true,
|
|
33
|
-
showNavigationButtons = false,
|
|
34
33
|
enableDynamicViewWalkthrough = false,
|
|
35
|
-
enableFocusMode =
|
|
34
|
+
enableFocusMode = false,
|
|
36
35
|
initialWidth,
|
|
37
36
|
initialHeight,
|
|
38
37
|
keepAspectRatio = false,
|
|
@@ -46,8 +45,13 @@ export function LikeC4Diagram({
|
|
|
46
45
|
onNavigateTo,
|
|
47
46
|
onNodeClick,
|
|
48
47
|
onNodeContextMenu,
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
onOpenSourceElement,
|
|
49
|
+
onOpenSourceView,
|
|
50
|
+
onOpenSourceRelation,
|
|
51
|
+
onBurgerMenuClick,
|
|
52
|
+
renderIcon,
|
|
53
|
+
where,
|
|
54
|
+
showNavigationButtons = !!onNavigateTo
|
|
51
55
|
}: LikeC4DiagramProps) {
|
|
52
56
|
const initialRef = useRef({
|
|
53
57
|
defaultNodes: [] as XYFlowNode[],
|
|
@@ -55,7 +59,9 @@ export function LikeC4Diagram({
|
|
|
55
59
|
initialWidth: initialWidth ?? view.bounds.width,
|
|
56
60
|
initialHeight: initialHeight ?? view.bounds.height
|
|
57
61
|
})
|
|
58
|
-
|
|
62
|
+
if (readonly !== true && !!where) {
|
|
63
|
+
console.warn('where filter is only supported in readonly mode')
|
|
64
|
+
}
|
|
59
65
|
return (
|
|
60
66
|
<EnsureMantine>
|
|
61
67
|
<LazyMotion features={domAnimation} strict>
|
|
@@ -73,11 +79,13 @@ export function LikeC4Diagram({
|
|
|
73
79
|
fitViewEnabled={fitView}
|
|
74
80
|
fitViewPadding={fitViewPadding}
|
|
75
81
|
showElementLinks={showElementLinks}
|
|
82
|
+
showNavigationButtons={showNavigationButtons}
|
|
76
83
|
nodesDraggable={nodesDraggable}
|
|
77
84
|
nodesSelectable={nodesSelectable}
|
|
78
85
|
experimentalEdgeEditing={experimentalEdgeEditing}
|
|
79
86
|
enableDynamicViewWalkthrough={enableDynamicViewWalkthrough}
|
|
80
87
|
enableFocusMode={enableFocusMode}
|
|
88
|
+
whereFilter={where ?? null}
|
|
81
89
|
renderIcon={renderIcon ?? null}
|
|
82
90
|
onCanvasClick={onCanvasClick ?? null}
|
|
83
91
|
onCanvasContextMenu={onCanvasContextMenu ?? null}
|
|
@@ -88,13 +96,15 @@ export function LikeC4Diagram({
|
|
|
88
96
|
onChange={onChange ?? null}
|
|
89
97
|
onNavigateTo={onNavigateTo ?? null}
|
|
90
98
|
onCanvasDblClick={onCanvasDblClick ?? null}
|
|
91
|
-
|
|
99
|
+
onOpenSourceView={onOpenSourceView ?? null}
|
|
100
|
+
onOpenSourceElement={onOpenSourceElement ?? null}
|
|
101
|
+
onOpenSourceRelation={onOpenSourceRelation ?? null}
|
|
102
|
+
onBurgerMenuClick={onBurgerMenuClick ?? null}
|
|
92
103
|
>
|
|
93
104
|
<LikeC4DiagramInnerMemo
|
|
94
105
|
controls={controls}
|
|
95
106
|
background={background}
|
|
96
107
|
showDiagramTitle={showDiagramTitle}
|
|
97
|
-
showNavigationButtons={showNavigationButtons}
|
|
98
108
|
/>
|
|
99
109
|
</DiagramContextProvider>
|
|
100
110
|
</XYFlowProvider>
|
|
@@ -107,13 +117,11 @@ type LikeC4DiagramInnerProps = {
|
|
|
107
117
|
background: NonNullable<LikeC4DiagramProperties['background']>
|
|
108
118
|
controls: boolean
|
|
109
119
|
showDiagramTitle: boolean
|
|
110
|
-
showNavigationButtons: boolean
|
|
111
120
|
}
|
|
112
121
|
const LikeC4DiagramInnerMemo = memo<LikeC4DiagramInnerProps>(function LikeC4DiagramInner({
|
|
113
122
|
background,
|
|
114
123
|
controls,
|
|
115
|
-
showDiagramTitle
|
|
116
|
-
showNavigationButtons
|
|
124
|
+
showDiagramTitle
|
|
117
125
|
}) {
|
|
118
126
|
const {
|
|
119
127
|
isInitialized,
|
|
@@ -140,7 +148,6 @@ const LikeC4DiagramInnerMemo = memo<LikeC4DiagramInnerProps>(function LikeC4Diag
|
|
|
140
148
|
)}
|
|
141
149
|
>
|
|
142
150
|
<XYFlowInner
|
|
143
|
-
showNavigationButtons={showNavigationButtons}
|
|
144
151
|
showDiagramTitle={showDiagramTitle}
|
|
145
152
|
background={background}
|
|
146
153
|
controls={controls}
|
|
@@ -12,6 +12,7 @@ export type StaticLikeC4DiagramProps = Pick<
|
|
|
12
12
|
| 'initialWidth'
|
|
13
13
|
| 'initialHeight'
|
|
14
14
|
| 'renderIcon'
|
|
15
|
+
| 'where'
|
|
15
16
|
>
|
|
16
17
|
|
|
17
18
|
export function StaticLikeC4Diagram({
|
|
@@ -34,6 +35,7 @@ export function StaticLikeC4Diagram({
|
|
|
34
35
|
showElementLinks
|
|
35
36
|
showDiagramTitle={false}
|
|
36
37
|
enableDynamicViewWalkthrough={false}
|
|
38
|
+
enableFocusMode={false}
|
|
37
39
|
nodesSelectable={false}
|
|
38
40
|
nodesDraggable={false}
|
|
39
41
|
{...rest}
|
package/src/globals.css.ts
CHANGED
package/src/hooks/index.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { shallowEqual } from 'fast-equals'
|
|
|
2
2
|
import { useContext } from 'react'
|
|
3
3
|
import { useStoreWithEqualityFn as useZustandStore } from 'zustand/traditional'
|
|
4
4
|
|
|
5
|
-
import { DiagramContext
|
|
6
|
-
import type { DiagramState } from '
|
|
5
|
+
import { DiagramContext } from '../state/DiagramContext'
|
|
6
|
+
import type { DiagramState, DiagramStoreApi } from '../state/diagramStore'
|
|
7
7
|
|
|
8
8
|
function useDiagramState<StateSlice = unknown>(
|
|
9
9
|
selector: (state: DiagramState) => StateSlice,
|
|
@@ -18,7 +18,6 @@ function useDiagramState<StateSlice = unknown>(
|
|
|
18
18
|
return useZustandStore(store, selector, equalityFn ?? shallowEqual)
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export type DiagramStoreApi = Readonly<Pick<DiagramZustandStore, 'getState' | 'setState' | 'subscribe'>>
|
|
22
21
|
function useDiagramStoreApi(): DiagramStoreApi {
|
|
23
22
|
const store = useContext(DiagramContext)
|
|
24
23
|
|
|
@@ -28,5 +27,5 @@ function useDiagramStoreApi(): DiagramStoreApi {
|
|
|
28
27
|
|
|
29
28
|
return store
|
|
30
29
|
}
|
|
31
|
-
|
|
30
|
+
export type { DiagramState, DiagramStoreApi }
|
|
32
31
|
export { useDiagramState, useDiagramStoreApi }
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useNodesData, useReactFlow, useStore, useStoreApi } from '@xyflow/react'
|
|
2
2
|
import { deepEqual, shallowEqual } from 'fast-equals'
|
|
3
3
|
import { useCallback } from 'react'
|
|
4
|
-
import type { XYFlowEdge, XYFlowNode, XYFlowState } from '../types'
|
|
4
|
+
import type { XYFlowEdge, XYFlowNode, XYFlowState } from '../xyflow/types'
|
|
5
5
|
|
|
6
6
|
export const useXYFlow = useReactFlow<XYFlowNode, XYFlowEdge>
|
|
7
7
|
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import '@xyflow/react/dist/style.css'
|
|
2
|
+
|
|
1
3
|
export { LikeC4Diagram } from './LikeC4Diagram'
|
|
2
4
|
export { StaticLikeC4Diagram } from './StaticLikeC4Diagram'
|
|
3
5
|
|
|
4
|
-
export { useSetState
|
|
6
|
+
export { useSetState } from './hooks/useSetState'
|
|
7
|
+
export { useUpdateEffect } from './hooks/useUpdateEffect'
|
|
5
8
|
export type * from './LikeC4Diagram'
|
|
6
9
|
export type * from './LikeC4Diagram.props'
|
|
7
10
|
export type * from './StaticLikeC4Diagram'
|
|
8
|
-
export type * from './types'
|
|
9
11
|
export type * from './xyflow/types'
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { invariant } from '@likec4/core'
|
|
1
2
|
import { deepEqual, shallowEqual } from 'fast-equals'
|
|
2
|
-
import { createContext, type PropsWithChildren, useCallback,
|
|
3
|
-
import { useUpdateEffect } from '../hooks'
|
|
4
|
-
import { useXYFlow, useXYStoreApi } from '../
|
|
5
|
-
import { createDiagramStore, type DiagramInitialState } from './diagramStore'
|
|
3
|
+
import { createContext, type PropsWithChildren, useCallback, useRef } from 'react'
|
|
4
|
+
import { useUpdateEffect } from '../hooks/useUpdateEffect'
|
|
5
|
+
import { useXYFlow, useXYStoreApi } from '../hooks/useXYFlow'
|
|
6
|
+
import { createDiagramStore, type DiagramInitialState, type DiagramZustandStore } from './diagramStore'
|
|
6
7
|
|
|
7
|
-
export type DiagramZustandStore = ReturnType<typeof createDiagramStore>
|
|
8
8
|
export const DiagramContext = createContext<DiagramZustandStore | null>(null)
|
|
9
9
|
|
|
10
10
|
export type DiagramContextProviderProps = PropsWithChildren<
|
|
@@ -19,6 +19,7 @@ export function DiagramContextProvider({
|
|
|
19
19
|
view,
|
|
20
20
|
className,
|
|
21
21
|
keepAspectRatio,
|
|
22
|
+
whereFilter,
|
|
22
23
|
...props
|
|
23
24
|
}: DiagramContextProviderProps) {
|
|
24
25
|
const containerRef = useRef<HTMLDivElement>(null)
|
|
@@ -34,6 +35,7 @@ export function DiagramContextProvider({
|
|
|
34
35
|
xyflow,
|
|
35
36
|
view,
|
|
36
37
|
getContainer,
|
|
38
|
+
whereFilter: structuredClone(whereFilter),
|
|
37
39
|
...props
|
|
38
40
|
})
|
|
39
41
|
}
|
|
@@ -50,9 +52,15 @@ export function DiagramContextProvider({
|
|
|
50
52
|
|
|
51
53
|
useUpdateEffect(
|
|
52
54
|
() => {
|
|
53
|
-
store.current
|
|
55
|
+
const current = store.current
|
|
56
|
+
invariant(current, 'DiagramContext.store.current is not defined')
|
|
57
|
+
if (!deepEqual(whereFilter, current.getState().whereFilter)) {
|
|
58
|
+
current.setState({ whereFilter: structuredClone(whereFilter) }, false, 'update where filter')
|
|
59
|
+
}
|
|
60
|
+
current.getState().updateView(view)
|
|
54
61
|
},
|
|
55
|
-
[view]
|
|
62
|
+
[view, whereFilter] as const,
|
|
63
|
+
(a, b) => shallowEqual(a[0], b[0]) && deepEqual(a[1], b[1])
|
|
56
64
|
)
|
|
57
65
|
|
|
58
66
|
return (
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { extractStep, invariant, nonNullable } from '@likec4/core'
|
|
2
|
-
import type { DiagramNode, DiagramView, Fqn } from '@likec4/core/types'
|
|
1
|
+
import { extractStep, invariant, nonNullable, whereOperatorAsPredicate } from '@likec4/core'
|
|
2
|
+
import type { DiagramEdge, DiagramNode, DiagramView, Fqn } from '@likec4/core/types'
|
|
3
3
|
import { hasAtLeast } from 'remeda'
|
|
4
|
+
import type { WhereOperator } from '../LikeC4Diagram.props'
|
|
4
5
|
import { ZIndexes } from '../xyflow/const'
|
|
5
6
|
import type { XYFlowEdge, XYFlowNode } from '../xyflow/types'
|
|
6
7
|
|
|
@@ -9,6 +10,7 @@ import type { XYFlowEdge, XYFlowNode } from '../xyflow/types'
|
|
|
9
10
|
export function diagramViewToXYFlowData(
|
|
10
11
|
view: Pick<DiagramView, 'id' | 'nodes' | 'edges' | '__'>,
|
|
11
12
|
opts: {
|
|
13
|
+
where: WhereOperator<string, string> | null
|
|
12
14
|
draggable: boolean
|
|
13
15
|
selectable: boolean
|
|
14
16
|
}
|
|
@@ -35,6 +37,17 @@ export function diagramViewToXYFlowData(
|
|
|
35
37
|
}>()
|
|
36
38
|
)
|
|
37
39
|
|
|
40
|
+
let visiblePredicate = (_nodeOrEdge: DiagramNode | DiagramEdge): boolean => true
|
|
41
|
+
if (opts.where) {
|
|
42
|
+
try {
|
|
43
|
+
visiblePredicate = whereOperatorAsPredicate(opts.where)
|
|
44
|
+
} catch (e) {
|
|
45
|
+
console.error('Error in where filter:', e)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// const visiblePredicate = opts.where ? whereOperatorAsPredicate(opts.where) : () => true
|
|
50
|
+
|
|
38
51
|
// namespace to force unique ids
|
|
39
52
|
const ns = ''
|
|
40
53
|
const nodeById = (id: Fqn) => nonNullable(nodeLookup.get(id), `Node not found: ${id}`)
|
|
@@ -72,9 +85,9 @@ export function diagramViewToXYFlowData(
|
|
|
72
85
|
deletable: false,
|
|
73
86
|
position,
|
|
74
87
|
zIndex: isCompound ? ZIndexes.Compound : ZIndexes.Element,
|
|
75
|
-
hidden: false,
|
|
76
88
|
width: node.width,
|
|
77
89
|
height: node.height,
|
|
90
|
+
hidden: !visiblePredicate(node),
|
|
78
91
|
// parentId: parent ? ns + parent.id : null,
|
|
79
92
|
...(parent && {
|
|
80
93
|
parentId: ns + parent.id
|
|
@@ -109,6 +122,7 @@ export function diagramViewToXYFlowData(
|
|
|
109
122
|
target: ns + target,
|
|
110
123
|
zIndex: ZIndexes.Edge,
|
|
111
124
|
selectable: opts.selectable,
|
|
125
|
+
hidden: !visiblePredicate(edge),
|
|
112
126
|
deletable: false,
|
|
113
127
|
data: {
|
|
114
128
|
edge,
|