@likec4/diagram 1.1.0 → 1.2.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.
Files changed (76) hide show
  1. package/dist/KeepAspectRatioContainer.d.ts +1 -1
  2. package/dist/LikeC4Diagram.d.ts +1 -1
  3. package/dist/LikeC4Diagram.props.d.ts +22 -12
  4. package/dist/StaticLikeC4Diagram.d.ts +1 -1
  5. package/dist/index.d.ts +0 -1
  6. package/dist/index.mjs +2209 -706
  7. package/dist/mantine/EnsureMantine.d.ts +1 -1
  8. package/dist/state/DiagramContext.d.ts +2143 -19
  9. package/dist/state/WhenInitialized.d.ts +1 -1
  10. package/dist/state/diagramStore.d.ts +2152 -19
  11. package/dist/state/useDiagramStore.d.ts +2142 -18
  12. package/dist/style.css +256 -118
  13. package/dist/theme.css.d.ts +1 -0
  14. package/dist/ui/DiagramTitlePanel.css.d.ts +4 -0
  15. package/dist/ui/DiagramTitlePanel.d.ts +1 -0
  16. package/dist/ui/DynamicViewWalkthrough.css.d.ts +3 -0
  17. package/dist/ui/DynamicViewWalkthrough.d.ts +1 -0
  18. package/dist/ui/OptionsPanel.d.ts +1 -3
  19. package/dist/ui/index.d.ts +1 -0
  20. package/dist/ui/options/NodeOptions.d.ts +1 -2
  21. package/dist/xyflow/FitviewOnDiagramChange.d.ts +4 -2
  22. package/dist/xyflow/SelectEdgesOnNodeFocus.d.ts +1 -0
  23. package/dist/xyflow/SyncWithDiagram.d.ts +1 -2
  24. package/dist/xyflow/XYFlow.d.ts +4 -7
  25. package/dist/xyflow/XYFlowBackground.d.ts +5 -4
  26. package/dist/xyflow/XYFlowEvents.d.ts +84 -84
  27. package/dist/xyflow/XYFlowInner.d.ts +11 -0
  28. package/dist/xyflow/diagram-to-xyflow.d.ts +1 -1
  29. package/dist/xyflow/edges/RelationshipEdge.d.ts +14 -14
  30. package/dist/xyflow/edges/edges.css.d.ts +5 -2
  31. package/dist/xyflow/edges/utils.d.ts +2 -0
  32. package/dist/xyflow/hooks/useXYFlow.d.ts +126 -126
  33. package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +1 -0
  34. package/dist/xyflow/nodes/element/ElementIcon.d.ts +1 -1
  35. package/dist/xyflow/nodes/element/ElementLink.d.ts +1 -1
  36. package/dist/xyflow/nodes/element/ElementNode.d.ts +1 -1
  37. package/dist/xyflow/nodes/element/ElementShapeSvg.d.ts +2 -2
  38. package/dist/xyflow/nodes/element/element.css.d.ts +2 -1
  39. package/dist/xyflow/nodes/shared/NavigateToBtn.d.ts +1 -2
  40. package/dist/xyflow/types.d.ts +18 -18
  41. package/package.json +21 -16
  42. package/src/KeepAspectRatioContainer.tsx +1 -1
  43. package/src/LikeC4Diagram.css.ts +4 -1
  44. package/src/LikeC4Diagram.props.ts +24 -14
  45. package/src/LikeC4Diagram.tsx +18 -9
  46. package/src/StaticLikeC4Diagram.tsx +2 -0
  47. package/src/globals.css.ts +7 -1
  48. package/src/index.ts +0 -3
  49. package/src/state/DiagramContext.tsx +21 -12
  50. package/src/state/diagramStore.ts +275 -98
  51. package/src/theme.css.ts +1 -0
  52. package/src/ui/DiagramTitlePanel.css.ts +33 -0
  53. package/src/ui/DiagramTitlePanel.tsx +138 -0
  54. package/src/ui/DynamicViewWalkthrough.css.ts +46 -0
  55. package/src/ui/DynamicViewWalkthrough.tsx +86 -0
  56. package/src/ui/OptionsPanel.tsx +7 -24
  57. package/src/ui/index.ts +1 -0
  58. package/src/ui/options/NodeOptions.tsx +103 -27
  59. package/src/xyflow/FitviewOnDiagramChange.tsx +89 -69
  60. package/src/xyflow/SelectEdgesOnNodeFocus.tsx +75 -0
  61. package/src/xyflow/SyncWithDiagram.tsx +55 -101
  62. package/src/xyflow/XYFlow.tsx +52 -32
  63. package/src/xyflow/XYFlowBackground.tsx +7 -5
  64. package/src/xyflow/XYFlowEvents.tsx +150 -104
  65. package/src/xyflow/XYFlowInner.tsx +50 -0
  66. package/src/xyflow/diagram-to-xyflow.ts +16 -21
  67. package/src/xyflow/edges/RelationshipEdge.tsx +102 -70
  68. package/src/xyflow/edges/edges.css.ts +128 -53
  69. package/src/xyflow/edges/utils.ts +31 -0
  70. package/src/xyflow/nodes/compound/CompoundNode.css.ts +20 -12
  71. package/src/xyflow/nodes/compound/CompoundNode.tsx +6 -3
  72. package/src/xyflow/nodes/element/ElementLink.tsx +13 -3
  73. package/src/xyflow/nodes/element/ElementNode.tsx +24 -19
  74. package/src/xyflow/nodes/element/element.css.ts +10 -2
  75. package/src/xyflow/nodes/shared/NavigateToBtn.tsx +1 -0
  76. package/src/xyflow/types.ts +7 -8
@@ -1,4 +1,5 @@
1
1
  import type {
2
+ BorderStyle,
2
3
  DiagramEdge,
3
4
  DiagramNode,
4
5
  DiagramView,
@@ -11,7 +12,7 @@ import type {
11
12
  import type { MouseEvent as ReactMouseEvent } from 'react'
12
13
  import type { SetRequired, Simplify } from 'type-fest'
13
14
  import type { XYFlowEdge, XYFlowNode } from './xyflow/types'
14
- import type { XYBackgroundProps } from './xyflow/XYFlowBackground'
15
+ import type { XYBackground, XYBackgroundProps } from './xyflow/XYFlowBackground'
15
16
 
16
17
  export type DiagramNodeWithNavigate = Simplify<SetRequired<DiagramNode, 'navigateTo'>>
17
18
 
@@ -44,22 +45,19 @@ export type OnEdgeClick = (
44
45
  export type OnCanvasClick = (event: ReactMouseEvent) => void
45
46
 
46
47
  export namespace Changes {
47
- export interface ChangeColor {
48
- op: 'change-color'
49
- color: ThemeColor
50
- targets: NonEmptyArray<Fqn>
51
- }
52
-
53
- export interface ChangeShape {
54
- op: 'change-shape'
55
- shape: ElementShape
48
+ export interface ChangeElementStyle {
49
+ op: 'change-element-style'
50
+ style: {
51
+ border?: BorderStyle
52
+ opacity?: number
53
+ shape?: ElementShape
54
+ color?: ThemeColor
55
+ }
56
56
  targets: NonEmptyArray<Fqn>
57
57
  }
58
58
  }
59
59
 
60
- export type Change =
61
- | Changes.ChangeColor
62
- | Changes.ChangeShape
60
+ export type Change = Changes.ChangeElementStyle
63
61
 
64
62
  export type ChangeEvent = {
65
63
  changes: NonEmptyArray<Change>
@@ -132,13 +130,25 @@ export interface LikeC4DiagramProperties {
132
130
  * Background pattern
133
131
  * @default 'dots'
134
132
  */
135
- background?: 'transparent' | 'solid' | XYBackgroundProps | undefined
133
+ background?: 'transparent' | 'solid' | XYBackground | undefined
136
134
 
137
135
  /**
138
136
  * Display hovercards with element links
139
137
  * @default true
140
138
  */
141
139
  showElementLinks?: boolean | undefined
140
+
141
+ /**
142
+ * Display panel with diagram title / description
143
+ * @default true
144
+ */
145
+ showDiagramTitle?: boolean | undefined
146
+
147
+ /**
148
+ * If Walkthrough for dynamic views should be enabled
149
+ * @default false
150
+ */
151
+ enableDynamicViewWalkthrough?: boolean | undefined
142
152
  }
143
153
 
144
154
  export interface LikeC4DiagramEventHandlers {
@@ -1,3 +1,4 @@
1
+ import '@xyflow/react/dist/style.css'
1
2
  import { ReactFlowProvider as XYFlowProvider } from '@xyflow/react'
2
3
  import clsx from 'clsx'
3
4
  import { useRef } from 'react'
@@ -8,12 +9,13 @@ import { type LikeC4DiagramEventHandlers, type LikeC4DiagramProperties } from '.
8
9
  import { EnsureMantine } from './mantine/EnsureMantine'
9
10
  import { DiagramContextProvider } from './state/DiagramContext'
10
11
  import { WhenInitialized } from './state/WhenInitialized'
11
- import OptionsPanel from './ui/OptionsPanel'
12
12
  import { diagramViewToXYFlowData } from './xyflow/diagram-to-xyflow'
13
13
  import { FitViewOnDiagramChange } from './xyflow/FitviewOnDiagramChange'
14
+ import { SelectEdgesOnNodeFocus } from './xyflow/SelectEdgesOnNodeFocus'
14
15
  import { SyncWithDiagram } from './xyflow/SyncWithDiagram'
15
16
  import type { XYFlowData } from './xyflow/types'
16
17
  import { XYFlow } from './xyflow/XYFlow'
18
+ import { XYFlowInner } from './xyflow/XYFlowInner'
17
19
 
18
20
  export type LikeC4DiagramProps = LikeC4DiagramProperties & LikeC4DiagramEventHandlers
19
21
  export function LikeC4Diagram({
@@ -27,8 +29,10 @@ export function LikeC4Diagram({
27
29
  nodesSelectable = !readonly,
28
30
  nodesDraggable = !readonly,
29
31
  background = 'dots',
30
- controls = false,
32
+ controls = !readonly,
31
33
  showElementLinks = true,
34
+ showDiagramTitle = true,
35
+ enableDynamicViewWalkthrough = true,
32
36
  initialWidth,
33
37
  initialHeight,
34
38
  keepAspectRatio = false,
@@ -42,6 +46,7 @@ export function LikeC4Diagram({
42
46
  onNodeClick,
43
47
  onNodeContextMenu
44
48
  }: LikeC4DiagramProps) {
49
+ console.log('LikeC4Diagram')
45
50
  const initialRef = useRef<{
46
51
  defaultNodes: XYFlowData['nodes']
47
52
  defaultEdges: XYFlowData['edges']
@@ -100,18 +105,22 @@ export function LikeC4Diagram({
100
105
  pannable !== true && cssDisablePan,
101
106
  background === 'transparent' && cssTransparentBg
102
107
  )}
103
- background={background}
104
- controls={controls}
105
108
  defaultNodes={initialRef.current.defaultNodes}
106
109
  defaultEdges={initialRef.current.defaultEdges}
107
110
  >
108
- {readonly !== true && <OptionsPanel />}
111
+ <XYFlowInner
112
+ showDiagramTitle={showDiagramTitle}
113
+ enableDynamicViewWalkthrough={enableDynamicViewWalkthrough}
114
+ background={background}
115
+ controls={controls}
116
+ />
109
117
  </XYFlow>
118
+ <WhenInitialized>
119
+ <SyncWithDiagram />
120
+ {fitView && <FitViewOnDiagramChange />}
121
+ {fitView && zoomable && <SelectEdgesOnNodeFocus />}
122
+ </WhenInitialized>
110
123
  </KeepAspectRatioContainer>
111
- <WhenInitialized>
112
- <SyncWithDiagram />
113
- <FitViewOnDiagramChange />
114
- </WhenInitialized>
115
124
  </DiagramContextProvider>
116
125
  </XYFlowProvider>
117
126
  </EnsureMantine>
@@ -31,6 +31,8 @@ export function StaticLikeC4Diagram({
31
31
  controls={false}
32
32
  background={background}
33
33
  showElementLinks
34
+ showDiagramTitle={false}
35
+ enableDynamicViewWalkthrough={false}
34
36
  nodesSelectable={false}
35
37
  nodesDraggable={false}
36
38
  {...rest}
@@ -1,5 +1,5 @@
1
1
  import { defaultTheme } from '@likec4/core'
2
- import { createGlobalTheme } from '@vanilla-extract/css'
2
+ import { createGlobalTheme, globalStyle } from '@vanilla-extract/css'
3
3
  import { scale, toHex } from 'khroma'
4
4
  import { keys, omit } from 'remeda'
5
5
  import { mantine } from './mantine.css'
@@ -7,6 +7,11 @@ import { vars } from './theme.css'
7
7
 
8
8
  export const rootClassName = 'likec4-diagram-root'
9
9
 
10
+ globalStyle(`.${rootClassName}`, {
11
+ WebkitFontSmoothing: mantine.webkitFontSmoothing,
12
+ MozOsxFontSmoothing: mantine.mozFontSmoothing
13
+ })
14
+
10
15
  createGlobalTheme(`.${rootClassName}`, {
11
16
  ...omit(vars, ['optionsPanel', 'default'])
12
17
  }, {
@@ -20,6 +25,7 @@ createGlobalTheme(`.${rootClassName}`, {
20
25
  }
21
26
  }
22
27
  },
28
+ filterDimmed: 'brightness(.6) grayscale(.8) opacity(.5) blur(1px)',
23
29
  compound: {
24
30
  font: vars.likec4.font,
25
31
  titleColor: vars.element.loContrast
package/src/index.ts CHANGED
@@ -1,6 +1,3 @@
1
- import '@xyflow/react/dist/style.css'
2
- import './globals.css'
3
-
4
1
  export { LikeC4Diagram } from './LikeC4Diagram'
5
2
  export { StaticLikeC4Diagram } from './StaticLikeC4Diagram'
6
3
 
@@ -1,4 +1,5 @@
1
- import { createContext, type PropsWithChildren, useRef } from 'react'
1
+ import { createContext, type PropsWithChildren, useEffect, useRef } from 'react'
2
+ import { hasSubObject, isIncludedIn } from 'remeda'
2
3
  import { useUpdateEffect } from '../hooks'
3
4
  import { useXYFlow } from '../xyflow/hooks'
4
5
  import { createDiagramStore, type DiagramInitialState } from './diagramStore'
@@ -18,20 +19,28 @@ export function DiagramContextProvider({ children, view, ...props }: PropsWithCh
18
19
  })
19
20
  }
20
21
 
21
- useUpdateEffect(
22
- () => store.current?.setState({ xyflow }, false, 'update xyflow'),
23
- [xyflow],
24
- Object.is
25
- )
26
-
27
- useUpdateEffect(
28
- () => store.current?.getState().updateView(view),
29
- [view]
22
+ useEffect(
23
+ () => {
24
+ if (store.current?.getState().xyflow !== xyflow) {
25
+ store.current?.setState({ xyflow }, false, 'update xyflow')
26
+ }
27
+ },
28
+ [xyflow]
30
29
  )
31
30
 
32
31
  useUpdateEffect(
33
- () => store.current?.setState(props, false, 'update incoming props'),
34
- [props]
32
+ () => {
33
+ if (!store.current) return
34
+ const state = store.current.getState()
35
+ if (state.view !== view) {
36
+ state.updateView(view)
37
+ }
38
+ if (!hasSubObject(state, props)) {
39
+ store.current.setState(props, false, 'update incoming props')
40
+ }
41
+ isIncludedIn
42
+ },
43
+ [view, props]
35
44
  )
36
45
 
37
46
  return (