@likec4/diagram 1.9.0 → 1.12.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/package.json +20 -43
- package/src/LikeC4CustomColors.tsx +5 -2
- package/src/LikeC4Diagram.css.ts +1 -1
- package/src/LikeC4Diagram.props.ts +40 -94
- package/src/LikeC4Diagram.tsx +14 -4
- package/src/LikeC4ModelProvider.tsx +21 -0
- package/src/StaticLikeC4Diagram.tsx +1 -0
- package/src/globals.css.ts +2 -3
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useMantinePortalProps.ts +8 -0
- package/src/hooks/useXYFlow.ts +1 -2
- package/src/index.ts +9 -0
- package/src/likec4model/LikeC4ModelContext.ts +4 -0
- package/src/likec4model/index.ts +1 -0
- package/src/likec4model/useLikeC4Model.ts +58 -0
- package/src/state/diagram-to-xyflow.ts +1 -2
- package/src/state/diagramStore.ts +185 -66
- package/src/{theme.css.ts → theme-vars.ts} +11 -4
- package/src/ui/DiagramTitlePanel.css.ts +2 -3
- package/src/ui/DiagramTitlePanel.tsx +25 -3
- package/src/ui/DynamicViewWalkthrough.css.ts +28 -2
- package/src/ui/DynamicViewWalkthrough.tsx +97 -52
- package/src/ui/OptionsPanel.css.ts +1 -2
- package/src/ui/OptionsPanel.tsx +5 -2
- package/src/ui/notation/NotationPanel.css.ts +2 -3
- package/src/ui/notation/NotationPanel.tsx +10 -11
- package/src/ui/options/NodeOptions.tsx +4 -1
- package/src/ui/top-left/ChangeAutoLayoutButton.tsx +122 -71
- package/src/ui/top-left/TopLeftPanel.tsx +128 -117
- package/src/ui/top-left/_shared.ts +7 -6
- package/src/ui/top-left/styles.css.ts +48 -8
- package/src/utils/vector.ts +57 -0
- package/src/xyflow/FitviewOnDiagramChange.tsx +5 -4
- package/src/xyflow/SelectEdgesOnNodeFocus.tsx +7 -5
- package/src/xyflow/XYFlow.tsx +13 -17
- package/src/xyflow/XYFlowEvents.tsx +58 -58
- package/src/xyflow/XYFlowInner.tsx +4 -8
- package/src/xyflow/edges/EdgeLabel.tsx +185 -0
- package/src/xyflow/edges/RelationshipEdge.tsx +170 -137
- package/src/xyflow/edges/RelationshipsDropdownMenu.css.ts +60 -0
- package/src/xyflow/edges/RelationshipsDropdownMenu.tsx +214 -0
- package/src/xyflow/edges/edges.css.ts +75 -7
- package/src/xyflow/nodes/compound/CompoundNode.css.ts +1 -2
- package/src/xyflow/nodes/compound/CompoundNode.tsx +25 -8
- package/src/xyflow/nodes/element/ElementLink.css.ts +1 -1
- package/src/xyflow/nodes/element/ElementLink.tsx +4 -8
- package/src/xyflow/nodes/element/ElementNode.tsx +47 -8
- package/src/xyflow/nodes/element/element.css.ts +1 -2
- package/src/xyflow/nodes/shared/Toolbar.tsx +426 -0
- package/src/xyflow/types.ts +1 -24
- package/src/xyflow/useLayoutConstraints.ts +10 -6
- package/dist/LikeC4CustomColors.d.ts +0 -3
- package/dist/LikeC4CustomColors.props.d.ts +0 -5
- package/dist/LikeC4Diagram.css.d.ts +0 -4
- package/dist/LikeC4Diagram.d.ts +0 -7
- package/dist/LikeC4Diagram.props.d.ts +0 -154
- package/dist/StaticLikeC4Diagram.d.ts +0 -4
- package/dist/globals.css.d.ts +0 -1
- package/dist/hooks/index.d.ts +0 -4
- package/dist/hooks/useDiagramState.d.ts +0 -6
- package/dist/hooks/useSetState.d.ts +0 -3
- package/dist/hooks/useUpdateEffect.d.ts +0 -5
- package/dist/hooks/useXYFlow.d.ts +0 -267
- package/dist/index.d.ts +0 -9
- package/dist/index.mjs +0 -3684
- package/dist/mantine/EnsureMantine.d.ts +0 -8
- package/dist/mantine.css.d.ts +0 -3
- package/dist/state/DiagramContext.d.ts +0 -1192
- package/dist/state/diagram-to-xyflow.d.ts +0 -12
- package/dist/state/diagramStore.d.ts +0 -1268
- package/dist/style.css +0 -2139
- package/dist/theme.css.d.ts +0 -63
- package/dist/ui/DiagramTitlePanel.css.d.ts +0 -4
- package/dist/ui/DiagramTitlePanel.d.ts +0 -1
- package/dist/ui/DynamicViewWalkthrough.css.d.ts +0 -3
- package/dist/ui/DynamicViewWalkthrough.d.ts +0 -1
- package/dist/ui/OptionsPanel.css.d.ts +0 -1
- package/dist/ui/OptionsPanel.d.ts +0 -1
- package/dist/ui/notation/NotationPanel.css.d.ts +0 -6
- package/dist/ui/notation/NotationPanel.d.ts +0 -1
- package/dist/ui/notation/index.d.ts +0 -1
- package/dist/ui/options/EdgeOptions.d.ts +0 -19
- package/dist/ui/options/NodeOptions.d.ts +0 -19
- package/dist/ui/top-left/ChangeAutoLayoutButton.d.ts +0 -3
- package/dist/ui/top-left/TopLeftPanel.d.ts +0 -4
- package/dist/ui/top-left/_shared.d.ts +0 -5
- package/dist/ui/top-left/styles.css.d.ts +0 -3
- package/dist/xyflow/EdgeMarkers.d.ts +0 -12
- package/dist/xyflow/FitviewOnDiagramChange.d.ts +0 -4
- package/dist/xyflow/SelectEdgesOnNodeFocus.d.ts +0 -1
- package/dist/xyflow/XYFlow.d.ts +0 -12
- package/dist/xyflow/XYFlowBackground.d.ts +0 -11
- package/dist/xyflow/XYFlowEvents.d.ts +0 -161
- package/dist/xyflow/XYFlowInner.d.ts +0 -10
- package/dist/xyflow/const.d.ts +0 -7
- package/dist/xyflow/edges/RelationshipEdge.d.ts +0 -32
- package/dist/xyflow/edges/edges.css.d.ts +0 -12
- package/dist/xyflow/edges/utils.d.ts +0 -17
- package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +0 -11
- package/dist/xyflow/nodes/compound/CompoundNode.d.ts +0 -6
- package/dist/xyflow/nodes/compound/index.d.ts +0 -1
- package/dist/xyflow/nodes/element/ElementLink.css.d.ts +0 -3
- package/dist/xyflow/nodes/element/ElementLink.d.ts +0 -7
- package/dist/xyflow/nodes/element/ElementNode.d.ts +0 -6
- package/dist/xyflow/nodes/element/ElementShapeSvg.d.ts +0 -18
- package/dist/xyflow/nodes/element/element.css.d.ts +0 -19
- package/dist/xyflow/nodes/element/index.d.ts +0 -1
- package/dist/xyflow/nodes/shared/NavigateToBtn.d.ts +0 -5
- package/dist/xyflow/types.d.ts +0 -50
- package/dist/xyflow/useLayoutConstraints.d.ts +0 -9
- package/dist/xyflow/utils.d.ts +0 -18
- package/src/mantine.css.ts +0 -7
- package/src/reset.d.ts +0 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@likec4/diagram",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"bugs": "https://github.com/likec4/likec4/issues",
|
|
6
6
|
"homepage": "https://likec4.dev",
|
|
@@ -14,83 +14,60 @@
|
|
|
14
14
|
"package.json",
|
|
15
15
|
"LICENSE",
|
|
16
16
|
"README.md",
|
|
17
|
-
"dist",
|
|
18
17
|
"src",
|
|
19
|
-
"!dist/src",
|
|
20
18
|
"!**/*.spec.*",
|
|
21
19
|
"!**/*.d.ts.map"
|
|
22
20
|
],
|
|
23
21
|
"sideEffects": false,
|
|
24
22
|
"type": "module",
|
|
25
23
|
"exports": {
|
|
26
|
-
".":
|
|
27
|
-
"types": "./dist/index.d.ts",
|
|
28
|
-
"default": "./dist/index.mjs"
|
|
29
|
-
},
|
|
30
|
-
"./style.css": "./dist/style.css"
|
|
24
|
+
".": "./src/index.ts"
|
|
31
25
|
},
|
|
32
|
-
"
|
|
33
|
-
"registry": "https://registry.npmjs.org",
|
|
34
|
-
"access": "public",
|
|
35
|
-
"exports": {
|
|
36
|
-
".": {
|
|
37
|
-
"types": "./dist/index.d.ts",
|
|
38
|
-
"default": "./dist/index.mjs"
|
|
39
|
-
},
|
|
40
|
-
"./style.css": "./dist/style.css"
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
"packageManager": "yarn@4.3.1",
|
|
26
|
+
"packageManager": "yarn@4.5.0",
|
|
44
27
|
"scripts": {
|
|
45
28
|
"typecheck": "tsc --noEmit",
|
|
46
|
-
"prepack": "vite build --mode production",
|
|
47
29
|
"lint": "run -T eslint src/ --fix",
|
|
48
|
-
"clean": "
|
|
30
|
+
"clean": "rm -r -f -g 'dist/*' .tsbuildinfo"
|
|
49
31
|
},
|
|
50
32
|
"dependencies": {
|
|
51
|
-
"@likec4/core": "1.
|
|
52
|
-
"@lume/kiwi": "^0.4.
|
|
33
|
+
"@likec4/core": "1.12.1",
|
|
34
|
+
"@lume/kiwi": "^0.4.4",
|
|
35
|
+
"@mantine/vanilla-extract": "7.13.2",
|
|
53
36
|
"@react-hookz/web": "^24.0.4",
|
|
54
|
-
"@tabler/icons-react": "^3.
|
|
55
|
-
"@vanilla-extract/css": "^1.
|
|
37
|
+
"@tabler/icons-react": "^3.19.0",
|
|
38
|
+
"@vanilla-extract/css": "^1.16.0",
|
|
56
39
|
"@vanilla-extract/css-utils": "^0.1.4",
|
|
57
40
|
"@vanilla-extract/dynamic": "^2.1.2",
|
|
58
|
-
"@xyflow/react": "12.
|
|
59
|
-
"@xyflow/system": "0.0.
|
|
41
|
+
"@xyflow/react": "12.3.1",
|
|
42
|
+
"@xyflow/system": "0.0.43",
|
|
60
43
|
"bezier-js": "^6.1.4",
|
|
61
44
|
"clsx": "^2.1.1",
|
|
62
45
|
"d3-shape": "^3.2.0",
|
|
63
46
|
"esm-env": "^1.0.0",
|
|
64
47
|
"fast-equals": "^5.0.1",
|
|
65
|
-
"framer-motion": "^11.
|
|
48
|
+
"framer-motion": "^11.11.1",
|
|
66
49
|
"khroma": "^2.1.0",
|
|
67
|
-
"remeda": "^2.
|
|
68
|
-
"type-fest": "
|
|
50
|
+
"remeda": "^2.14.0",
|
|
51
|
+
"type-fest": "4.26.1",
|
|
69
52
|
"zustand": "^4.5.5"
|
|
70
53
|
},
|
|
71
54
|
"peerDependencies": {
|
|
72
|
-
"@mantine/core": "^7.
|
|
73
|
-
"@mantine/hooks": "^7.
|
|
55
|
+
"@mantine/core": "^7.13.2",
|
|
56
|
+
"@mantine/hooks": "^7.13.2",
|
|
74
57
|
"react": "^18.3.1",
|
|
75
58
|
"react-dom": "^18.3.1"
|
|
76
59
|
},
|
|
77
60
|
"devDependencies": {
|
|
78
|
-
"@likec4/tsconfig": "1.
|
|
79
|
-
"@mantine/core": "7.
|
|
80
|
-
"@mantine/hooks": "7.
|
|
81
|
-
"@mantine/vanilla-extract": "7.12.2",
|
|
82
|
-
"@total-typescript/ts-reset": "^0.5.1",
|
|
61
|
+
"@likec4/tsconfig": "1.12.1",
|
|
62
|
+
"@mantine/core": "7.13.2",
|
|
63
|
+
"@mantine/hooks": "7.13.2",
|
|
83
64
|
"@types/bezier-js": "^4.1.3",
|
|
84
65
|
"@types/d3-shape": "^3.1.6",
|
|
85
66
|
"@types/react": "^18.3.4",
|
|
86
67
|
"@types/react-dom": "^18.3.0",
|
|
87
|
-
"@vanilla-extract/esbuild-plugin": "^2.3.10",
|
|
88
|
-
"@vitejs/plugin-react": "^4.3.1",
|
|
89
68
|
"execa": "^9.3.1",
|
|
90
69
|
"react": "^18.3.1",
|
|
91
70
|
"react-dom": "^18.3.1",
|
|
92
|
-
"typescript": "^5.
|
|
93
|
-
"vite": "5.3.4",
|
|
94
|
-
"vite-plugin-dts": "^3.9.1"
|
|
71
|
+
"typescript": "^5.6.2"
|
|
95
72
|
}
|
|
96
73
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type ThemeColorValues } from '@likec4/core'
|
|
2
2
|
import { entries } from 'remeda'
|
|
3
3
|
import type { LikeC4CustomColorsProperties } from './LikeC4CustomColors.props'
|
|
4
|
-
import { vars } from './theme
|
|
4
|
+
import { vars } from './theme-vars'
|
|
5
|
+
import { useMantineStyleNonce } from '@mantine/core'
|
|
5
6
|
|
|
6
7
|
type CSSVarFunction = `var(--${string})` | `var(--${string}, ${string | number} )`
|
|
7
8
|
|
|
@@ -28,10 +29,12 @@ export function LikeC4CustomColors({ customColors }: LikeC4CustomColorsPropertie
|
|
|
28
29
|
const styles = entries(customColors)
|
|
29
30
|
.map(([name, color]) => toStyle(name, color))
|
|
30
31
|
.join('\n')
|
|
32
|
+
|
|
33
|
+
const nonce = useMantineStyleNonce()?.()
|
|
31
34
|
|
|
32
35
|
return (
|
|
33
36
|
<>
|
|
34
|
-
<style type="text/css" dangerouslySetInnerHTML={{ __html: styles }} />
|
|
37
|
+
<style type="text/css" dangerouslySetInnerHTML={{ __html: styles }} {...(nonce && { nonce })} />
|
|
35
38
|
</>
|
|
36
39
|
)
|
|
37
40
|
}
|
package/src/LikeC4Diagram.css.ts
CHANGED
|
@@ -9,69 +9,12 @@ import type {
|
|
|
9
9
|
WhereOperator
|
|
10
10
|
} from '@likec4/core'
|
|
11
11
|
import type { MouseEvent as ReactMouseEvent, ReactNode } from 'react'
|
|
12
|
-
import type { XYFlowEdge, XYFlowNode } from './xyflow/types'
|
|
13
12
|
import type { XYBackground } from './xyflow/XYFlowBackground'
|
|
14
13
|
|
|
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
|
-
|
|
71
14
|
export type { WhereOperator }
|
|
72
15
|
|
|
73
|
-
export type DiagramNodeWithNavigate = Omit<DiagramNode, 'navigateTo'> & {
|
|
74
|
-
navigateTo:
|
|
16
|
+
export type DiagramNodeWithNavigate<ID extends string = ViewID> = Omit<DiagramNode, 'navigateTo'> & {
|
|
17
|
+
navigateTo: ID
|
|
75
18
|
}
|
|
76
19
|
|
|
77
20
|
type ElementIconNodeProps = {
|
|
@@ -84,28 +27,21 @@ export type ElementIconRenderer = (props: {
|
|
|
84
27
|
node: ElementIconNodeProps
|
|
85
28
|
}) => ReactNode
|
|
86
29
|
|
|
87
|
-
export type OnNavigateTo =
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
): void
|
|
95
|
-
}
|
|
30
|
+
export type OnNavigateTo<ID extends string = ViewID> = (
|
|
31
|
+
to: ID,
|
|
32
|
+
// These fields present if navigateTo triggered by a node click
|
|
33
|
+
event?: ReactMouseEvent,
|
|
34
|
+
element?: DiagramNodeWithNavigate<ID>
|
|
35
|
+
) => void
|
|
36
|
+
|
|
96
37
|
export type OnNodeClick = (
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
xynode: XYFlowNode
|
|
100
|
-
event: ReactMouseEvent
|
|
101
|
-
}
|
|
38
|
+
node: DiagramNode,
|
|
39
|
+
event: ReactMouseEvent
|
|
102
40
|
) => void
|
|
41
|
+
|
|
103
42
|
export type OnEdgeClick = (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
xyedge: XYFlowEdge
|
|
107
|
-
event: ReactMouseEvent
|
|
108
|
-
}
|
|
43
|
+
edge: DiagramEdge,
|
|
44
|
+
event: ReactMouseEvent
|
|
109
45
|
) => void
|
|
110
46
|
|
|
111
47
|
/**
|
|
@@ -116,9 +52,8 @@ export type OnCanvasClick = (event: ReactMouseEvent) => void
|
|
|
116
52
|
export type ChangeEvent = {
|
|
117
53
|
change: ViewChange
|
|
118
54
|
}
|
|
119
|
-
export type OnChange =
|
|
120
|
-
|
|
121
|
-
}
|
|
55
|
+
export type OnChange = (event: ChangeEvent) => void
|
|
56
|
+
|
|
122
57
|
export type LikeC4ColorScheme = 'light' | 'dark'
|
|
123
58
|
|
|
124
59
|
export interface LikeC4DiagramProperties {
|
|
@@ -127,15 +62,7 @@ export interface LikeC4DiagramProperties {
|
|
|
127
62
|
className?: string | undefined
|
|
128
63
|
|
|
129
64
|
/**
|
|
130
|
-
*
|
|
131
|
-
* By default inherits from system or surrounding MantineProvider
|
|
132
|
-
*
|
|
133
|
-
* @example 'light' | 'dark'
|
|
134
|
-
*/
|
|
135
|
-
// colorScheme?: LikeC4ColorScheme | undefined
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Show/hide controls menu
|
|
65
|
+
* Show/hide ReactFlow controls menu
|
|
139
66
|
* @default false
|
|
140
67
|
*/
|
|
141
68
|
controls?: boolean | undefined
|
|
@@ -165,10 +92,13 @@ export interface LikeC4DiagramProperties {
|
|
|
165
92
|
*/
|
|
166
93
|
fitViewPadding?: number | undefined
|
|
167
94
|
|
|
95
|
+
/**
|
|
96
|
+
* @default false if readonly
|
|
97
|
+
*/
|
|
168
98
|
nodesSelectable?: boolean | undefined
|
|
169
99
|
|
|
170
100
|
/**
|
|
171
|
-
* @default false
|
|
101
|
+
* @default false if readonly
|
|
172
102
|
*/
|
|
173
103
|
nodesDraggable?: boolean | undefined
|
|
174
104
|
|
|
@@ -194,14 +124,14 @@ export interface LikeC4DiagramProperties {
|
|
|
194
124
|
showElementLinks?: boolean | undefined
|
|
195
125
|
|
|
196
126
|
/**
|
|
197
|
-
* Display
|
|
127
|
+
* Display webview with diagram title / description
|
|
198
128
|
* @default true
|
|
199
129
|
*/
|
|
200
130
|
showDiagramTitle?: boolean | undefined
|
|
201
131
|
|
|
202
132
|
/**
|
|
203
133
|
* Show back/forward navigation buttons
|
|
204
|
-
* @default
|
|
134
|
+
* @default true if `onNavigateTo` is set
|
|
205
135
|
*/
|
|
206
136
|
showNavigationButtons?: undefined | boolean
|
|
207
137
|
|
|
@@ -211,6 +141,12 @@ export interface LikeC4DiagramProperties {
|
|
|
211
141
|
*/
|
|
212
142
|
showNotations?: boolean | undefined
|
|
213
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Display dropdown with details on relationship's label click
|
|
146
|
+
* @default true
|
|
147
|
+
*/
|
|
148
|
+
showRelationshipDetails?: boolean | undefined
|
|
149
|
+
|
|
214
150
|
/**
|
|
215
151
|
* If double click on a node should enable focus mode, i.e. highlight incoming/outgoing edges
|
|
216
152
|
* @default true
|
|
@@ -230,11 +166,14 @@ export interface LikeC4DiagramProperties {
|
|
|
230
166
|
experimentalEdgeEditing?: boolean | undefined
|
|
231
167
|
|
|
232
168
|
/**
|
|
233
|
-
* Render
|
|
169
|
+
* Render icon for an element, bundled or remote
|
|
234
170
|
* By default, if icon is http:// or https://, it will be rendered as an image
|
|
235
171
|
*/
|
|
236
172
|
renderIcon?: ElementIconRenderer | undefined
|
|
237
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Dynamic filter, applies both to nodes and edges
|
|
176
|
+
*/
|
|
238
177
|
where?: WhereOperator<string, string> | undefined
|
|
239
178
|
}
|
|
240
179
|
|
|
@@ -249,8 +188,15 @@ export interface LikeC4DiagramEventHandlers {
|
|
|
249
188
|
onCanvasClick?: OnCanvasClick | null | undefined
|
|
250
189
|
onCanvasDblClick?: OnCanvasClick | null | undefined
|
|
251
190
|
|
|
191
|
+
// if set, will render a burger menu icon in the top left corner
|
|
252
192
|
onBurgerMenuClick?: null | undefined | (() => void)
|
|
193
|
+
|
|
194
|
+
// if set, will render a source code icon in the top left corner
|
|
253
195
|
onOpenSourceView?: null | undefined | (() => void)
|
|
196
|
+
|
|
197
|
+
// if set, will render an icon in properties webview for each element
|
|
254
198
|
onOpenSourceElement?: null | undefined | ((fqn: Fqn) => void)
|
|
199
|
+
|
|
200
|
+
// if set, will be called on edge click
|
|
255
201
|
onOpenSourceRelation?: null | undefined | ((id: RelationID) => void)
|
|
256
202
|
}
|
package/src/LikeC4Diagram.tsx
CHANGED
|
@@ -2,13 +2,14 @@ import type { DiagramView } from '@likec4/core'
|
|
|
2
2
|
import { ReactFlowProvider as XYFlowProvider } from '@xyflow/react'
|
|
3
3
|
import clsx from 'clsx'
|
|
4
4
|
import { shallowEqual } from 'fast-equals'
|
|
5
|
-
import {
|
|
6
|
-
import { memo, useRef } from 'react'
|
|
5
|
+
import { domMax, LazyMotion } from 'framer-motion'
|
|
6
|
+
import { memo, useEffect, useRef } from 'react'
|
|
7
7
|
import { rootClassName } from './globals.css'
|
|
8
8
|
import { useDiagramState } from './hooks/useDiagramState'
|
|
9
9
|
import { LikeC4CustomColors } from './LikeC4CustomColors'
|
|
10
10
|
import * as css from './LikeC4Diagram.css'
|
|
11
11
|
import { type LikeC4DiagramEventHandlers, type LikeC4DiagramProperties } from './LikeC4Diagram.props'
|
|
12
|
+
import { useLikeC4Model } from './likec4model'
|
|
12
13
|
import { EnsureMantine } from './mantine/EnsureMantine'
|
|
13
14
|
import { DiagramContextProvider } from './state/DiagramContext'
|
|
14
15
|
import { FitViewOnDiagramChange } from './xyflow/FitviewOnDiagramChange'
|
|
@@ -33,6 +34,7 @@ export function LikeC4Diagram({
|
|
|
33
34
|
showElementLinks = true,
|
|
34
35
|
showDiagramTitle = true,
|
|
35
36
|
showNotations = true,
|
|
37
|
+
showRelationshipDetails = true,
|
|
36
38
|
enableDynamicViewWalkthrough = false,
|
|
37
39
|
enableFocusMode = false,
|
|
38
40
|
initialWidth,
|
|
@@ -56,6 +58,7 @@ export function LikeC4Diagram({
|
|
|
56
58
|
where,
|
|
57
59
|
showNavigationButtons = !!onNavigateTo
|
|
58
60
|
}: LikeC4DiagramProps) {
|
|
61
|
+
const hasLikec4model = !!useLikeC4Model()
|
|
59
62
|
const initialRef = useRef({
|
|
60
63
|
defaultNodes: [] as XYFlowNode[],
|
|
61
64
|
defaultEdges: [] as XYFlowEdge[],
|
|
@@ -65,9 +68,15 @@ export function LikeC4Diagram({
|
|
|
65
68
|
if (readonly !== true && !!where) {
|
|
66
69
|
console.warn('where filter is only supported in readonly mode')
|
|
67
70
|
}
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (showRelationshipDetails && !hasLikec4model) {
|
|
73
|
+
console.warn('Relationship details require LikeC4ModelProvider')
|
|
74
|
+
}
|
|
75
|
+
}, [showRelationshipDetails, hasLikec4model])
|
|
76
|
+
|
|
68
77
|
return (
|
|
69
78
|
<EnsureMantine>
|
|
70
|
-
<LazyMotion features={
|
|
79
|
+
<LazyMotion features={domMax} strict>
|
|
71
80
|
<XYFlowProvider
|
|
72
81
|
fitView={fitView}
|
|
73
82
|
{...initialRef.current}
|
|
@@ -85,6 +94,7 @@ export function LikeC4Diagram({
|
|
|
85
94
|
showElementLinks={showElementLinks}
|
|
86
95
|
showNavigationButtons={showNavigationButtons}
|
|
87
96
|
showNotations={showNotations}
|
|
97
|
+
showRelationshipDetails={showRelationshipDetails && hasLikec4model}
|
|
88
98
|
nodesDraggable={nodesDraggable}
|
|
89
99
|
nodesSelectable={nodesSelectable}
|
|
90
100
|
experimentalEdgeEditing={experimentalEdgeEditing}
|
|
@@ -124,7 +134,7 @@ type LikeC4DiagramInnerProps = {
|
|
|
124
134
|
controls: boolean
|
|
125
135
|
showDiagramTitle: boolean
|
|
126
136
|
}
|
|
127
|
-
const LikeC4DiagramInnerMemo = memo<LikeC4DiagramInnerProps>(function LikeC4DiagramInner({
|
|
137
|
+
const LikeC4DiagramInnerMemo = /* @__PURE__ */ memo<LikeC4DiagramInnerProps>(function LikeC4DiagramInner({
|
|
128
138
|
background,
|
|
129
139
|
controls,
|
|
130
140
|
showDiagramTitle
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { LikeC4Model } from '@likec4/core'
|
|
2
|
+
import { type PropsWithChildren } from 'react'
|
|
3
|
+
import { LikeC4ModelContext } from './likec4model/LikeC4ModelContext'
|
|
4
|
+
|
|
5
|
+
export type LikeC4ModelProviderProps = PropsWithChildren<{
|
|
6
|
+
likec4model: LikeC4Model
|
|
7
|
+
}>
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Ensures LikeC4Model context
|
|
11
|
+
*/
|
|
12
|
+
export function LikeC4ModelProvider({
|
|
13
|
+
children,
|
|
14
|
+
likec4model
|
|
15
|
+
}: LikeC4ModelProviderProps) {
|
|
16
|
+
return (
|
|
17
|
+
<LikeC4ModelContext.Provider value={likec4model}>
|
|
18
|
+
{children}
|
|
19
|
+
</LikeC4ModelContext.Provider>
|
|
20
|
+
)
|
|
21
|
+
}
|
package/src/globals.css.ts
CHANGED
|
@@ -2,8 +2,7 @@ import { defaultTheme } from '@likec4/core'
|
|
|
2
2
|
import { createGlobalTheme, globalStyle } from '@vanilla-extract/css'
|
|
3
3
|
import { scale, toHex } from 'khroma'
|
|
4
4
|
import { keys, omit } from 'remeda'
|
|
5
|
-
import { mantine, whereDark } from './
|
|
6
|
-
import { vars } from './theme.css'
|
|
5
|
+
import { mantine, vars, whereDark } from './theme-vars'
|
|
7
6
|
|
|
8
7
|
export const rootClassName = 'likec4-diagram-root'
|
|
9
8
|
|
|
@@ -18,7 +17,7 @@ globalStyle(`.${rootClassName}`, {
|
|
|
18
17
|
WebkitFontSmoothing: mantine.webkitFontSmoothing,
|
|
19
18
|
MozOsxFontSmoothing: mantine.mozFontSmoothing
|
|
20
19
|
})
|
|
21
|
-
globalStyle(
|
|
20
|
+
globalStyle(`:where(.${rootClassName}) .mantine-ActionIcon-icon .tabler-icon`, {
|
|
22
21
|
width: '75%',
|
|
23
22
|
height: '75%'
|
|
24
23
|
})
|
package/src/hooks/index.ts
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { useMemo } from 'react'
|
|
2
|
+
|
|
3
|
+
import { useDiagramState } from './useDiagramState'
|
|
4
|
+
|
|
5
|
+
export function useMantinePortalProps() {
|
|
6
|
+
const target = useDiagramState(s => s.getContainer())
|
|
7
|
+
return useMemo(() => target ? { portalProps: { target }, withinPortal: true } : { withinPortal: false }, [target])
|
|
8
|
+
}
|
package/src/hooks/useXYFlow.ts
CHANGED
|
@@ -12,8 +12,7 @@ export function useXYStore<StateSlice = unknown>(
|
|
|
12
12
|
equalityFn?: (a: StateSlice, b: StateSlice) => boolean
|
|
13
13
|
): StateSlice {
|
|
14
14
|
return useStore(
|
|
15
|
-
|
|
16
|
-
selector,
|
|
15
|
+
selector as any,
|
|
17
16
|
equalityFn ?? shallowEqual
|
|
18
17
|
)
|
|
19
18
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import '@xyflow/react/dist/style.css'
|
|
2
2
|
|
|
3
3
|
export { LikeC4Diagram } from './LikeC4Diagram'
|
|
4
|
+
export {
|
|
5
|
+
useLikeC4DiagramView,
|
|
6
|
+
useLikeC4Model,
|
|
7
|
+
useLikeC4View,
|
|
8
|
+
useLikeC4ViewModel,
|
|
9
|
+
useLikeC4Views
|
|
10
|
+
} from './likec4model/useLikeC4Model'
|
|
11
|
+
export { LikeC4ModelProvider } from './LikeC4ModelProvider'
|
|
4
12
|
export { StaticLikeC4Diagram } from './StaticLikeC4Diagram'
|
|
5
13
|
|
|
6
14
|
export { useSetState } from './hooks/useSetState'
|
|
7
15
|
export { useUpdateEffect } from './hooks/useUpdateEffect'
|
|
8
16
|
export type * from './LikeC4Diagram'
|
|
9
17
|
export type * from './LikeC4Diagram.props'
|
|
18
|
+
export type * from './LikeC4ModelProvider'
|
|
10
19
|
export type * from './StaticLikeC4Diagram'
|
|
11
20
|
export type * from './xyflow/types'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useLikeC4Model'
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { type ComputedView, type DiagramView, type LikeC4Model, type ViewID } from '@likec4/core'
|
|
2
|
+
import { useContext } from 'react'
|
|
3
|
+
import { isDefined, isNonNullish, isString } from 'remeda'
|
|
4
|
+
import type { LiteralUnion } from 'type-fest'
|
|
5
|
+
import { LikeC4ModelContext } from './LikeC4ModelContext'
|
|
6
|
+
|
|
7
|
+
export function useLikeC4Model(): LikeC4Model | null
|
|
8
|
+
export function useLikeC4Model(strict: true): LikeC4Model
|
|
9
|
+
export function useLikeC4Model(strict: boolean): LikeC4Model | null
|
|
10
|
+
export function useLikeC4Model(strict: true, type: 'layouted'): LikeC4Model.Layouted
|
|
11
|
+
export function useLikeC4Model(strict: true, type: 'computed'): LikeC4Model.Computed
|
|
12
|
+
export function useLikeC4Model(strict: true, type: LikeC4Model['type'] | undefined): LikeC4Model
|
|
13
|
+
export function useLikeC4Model(strict: boolean, type: 'layouted'): LikeC4Model.Layouted | null
|
|
14
|
+
export function useLikeC4Model(strict: boolean, type: 'computed'): LikeC4Model.Computed | null
|
|
15
|
+
export function useLikeC4Model(strict: boolean, type: LikeC4Model['type'] | undefined): LikeC4Model | null
|
|
16
|
+
export function useLikeC4Model(strict?: boolean, type?: LikeC4Model['type']) {
|
|
17
|
+
const model = useContext(LikeC4ModelContext)
|
|
18
|
+
|
|
19
|
+
if (isString(type) && isNonNullish(model) && model.type !== type) {
|
|
20
|
+
throw new Error(`Invalid LikeC4ModelContext, expected "${type}" but got "${model.type}" in context`)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (isDefined(strict) && strict === true && !model) {
|
|
24
|
+
throw new Error('No LikeC4Model found in context')
|
|
25
|
+
}
|
|
26
|
+
return model
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function useLikeC4Views(): LikeC4Model.SourceModel['views'] {
|
|
30
|
+
return useLikeC4Model(true).sourcemodel.views
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function useLikeC4ViewModel(viewId: LiteralUnion<ViewID, string>): LikeC4Model.ViewModel {
|
|
34
|
+
return useLikeC4Model(true).view(viewId)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Parsed view, computed or layouted
|
|
39
|
+
*/
|
|
40
|
+
export function useLikeC4View(viewId: LiteralUnion<ViewID, string>): ComputedView | DiagramView | null {
|
|
41
|
+
const model = useLikeC4Model(true)
|
|
42
|
+
try {
|
|
43
|
+
return model.view(viewId).view
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.warn(error)
|
|
46
|
+
return null
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function useLikeC4DiagramView(viewId: LiteralUnion<ViewID, string>): DiagramView | null {
|
|
51
|
+
const model = useLikeC4Model(true, 'layouted')
|
|
52
|
+
try {
|
|
53
|
+
return model.view(viewId).view
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.warn(error)
|
|
56
|
+
return null
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { extractStep, invariant, nonNullable, whereOperatorAsPredicate } from '@likec4/core'
|
|
2
1
|
import type { DiagramEdge, DiagramNode, DiagramView, Fqn } from '@likec4/core'
|
|
2
|
+
import { nonNullable, whereOperatorAsPredicate } from '@likec4/core'
|
|
3
3
|
import { hasAtLeast } from 'remeda'
|
|
4
4
|
import type { WhereOperator } from '../LikeC4Diagram.props'
|
|
5
5
|
import { ZIndexes } from '../xyflow/const'
|
|
@@ -122,7 +122,6 @@ export function diagramViewToXYFlowData(
|
|
|
122
122
|
data: {
|
|
123
123
|
edge,
|
|
124
124
|
controlPoints: edge.controlPoints || null,
|
|
125
|
-
stepNum: isDynamicView ? extractStep(edge.id) : null,
|
|
126
125
|
label: !!edge.labelBBox
|
|
127
126
|
? {
|
|
128
127
|
bbox: edge.labelBBox,
|