@likec4/diagram 1.0.0-rc.1 → 1.0.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 (38) hide show
  1. package/dist/LikeC4Diagram.d.ts +1 -1
  2. package/dist/LikeC4Diagram.props.d.ts +6 -3
  3. package/dist/StaticLikeC4Diagram.d.ts +1 -1
  4. package/dist/index.d.ts +1 -2
  5. package/dist/index.mjs +124 -221
  6. package/dist/mantine/EnsureMantine.d.ts +2 -3
  7. package/dist/style.css +3 -29
  8. package/dist/xyflow/nodes/element/ElementIcon.d.ts +1 -1
  9. package/dist/xyflow/types.d.ts +1 -1
  10. package/package.json +4 -4
  11. package/src/LikeC4Diagram.props.ts +12 -8
  12. package/src/LikeC4Diagram.tsx +3 -3
  13. package/src/StaticLikeC4Diagram.tsx +0 -1
  14. package/src/globals.css.ts +1 -1
  15. package/src/index.ts +1 -2
  16. package/src/mantine/EnsureMantine.tsx +8 -18
  17. package/src/mantine/theme.ts +1 -0
  18. package/src/ui/KeepAspectRatio.css.ts +2 -2
  19. package/src/ui/OptionsPanel.tsx +1 -1
  20. package/src/ui/options/NodeOptions.tsx +1 -2
  21. package/src/xyflow/FitviewOnDiagramChange.tsx +1 -1
  22. package/src/xyflow/SyncWithDiagram.tsx +23 -81
  23. package/src/xyflow/XYFlowEvents.tsx +1 -2
  24. package/src/xyflow/XYFlowWrapper.tsx +3 -7
  25. package/src/xyflow/edges/RelationshipEdge.tsx +4 -5
  26. package/src/xyflow/edges/edges.css.ts +3 -0
  27. package/src/xyflow/nodes/compound/CompoundNode.css.ts +3 -2
  28. package/src/xyflow/nodes/compound/CompoundNode.tsx +2 -2
  29. package/src/xyflow/nodes/element/ElementIcon.tsx +1 -3
  30. package/src/xyflow/nodes/element/ElementLink.css.ts +2 -2
  31. package/src/xyflow/nodes/element/ElementLink.tsx +3 -3
  32. package/src/xyflow/nodes/element/ElementNode.tsx +0 -2
  33. package/src/xyflow/nodes/element/element.css.ts +4 -4
  34. package/src/xyflow/types.ts +11 -2
  35. package/dist/EmbeddedLikeC4Diagram.css.d.ts +0 -5
  36. package/dist/EmbeddedLikeC4Diagram.d.ts +0 -17
  37. package/src/EmbeddedLikeC4Diagram.css.ts +0 -35
  38. package/src/EmbeddedLikeC4Diagram.tsx +0 -101
package/dist/style.css CHANGED
@@ -724,27 +724,6 @@ svg.react-flow__connectionline {
724
724
  --likec4-relation-lineColor: #6366f1;
725
725
  --likec4-relation-labelBg: #1e1b4b;
726
726
  --likec4-relation-labelColor: #818cf8;
727
- }._1yqpph0 {
728
- background-color: transparent;
729
- }
730
- ._1yqpph1 {
731
- padding: 0;
732
- height: 100%;
733
- }
734
- ._1yqpph2 {
735
- position: absolute;
736
- top: 1rem;
737
- left: 1rem;
738
- }
739
- ._1yqpph3 {
740
- position: absolute;
741
- top: 1rem;
742
- right: 1rem;
743
- }
744
- @media (min-width: 62em) {
745
- ._1yqpph4 {
746
- --cb-size: var(--cb-size-lg);
747
- }
748
727
  }.react-flow._2h8g8h0 {
749
728
  --xy-background-color: var(--likec4-background-color);
750
729
  --xy-background-pattern-color: var(--likec4-background-pattern-color);
@@ -761,9 +740,7 @@ svg.react-flow__connectionline {
761
740
  display: none;
762
741
  }._14qhjro0 {
763
742
  width: 100%;
764
- width: -webkit-fill-available;
765
743
  height: 100%;
766
- height: -webkit-fill-available;
767
744
  padding: 0;
768
745
  }._1lmzt1h0 {
769
746
  top: var(--likec4-options-panel-top, 1rem);
@@ -789,6 +766,9 @@ svg.react-flow__connectionline {
789
766
  --xy-edge-stroke-width: 2.5;
790
767
  }
791
768
  .react-flow__edges > svg {
769
+ mix-blend-mode: screen;
770
+ }
771
+ :where([data-mantine-color-scheme="dark"]) .react-flow__edges > svg {
792
772
  mix-blend-mode: lighten;
793
773
  }
794
774
  .bexn7q1 {
@@ -847,9 +827,7 @@ svg.react-flow__connectionline {
847
827
  }
848
828
  .lbtzdo0 {
849
829
  width: 100%;
850
- width: -webkit-fill-available;
851
830
  height: 100%;
852
- height: -webkit-fill-available;
853
831
  position: relative;
854
832
  padding: 0;
855
833
  margin: 0;
@@ -992,9 +970,7 @@ svg.react-flow__connectionline {
992
970
  --_1b6tkn0: color-mix(in srgb, var(--likec4-element-stroke) 90%, var(--likec4-element-fill));
993
971
  position: relative;
994
972
  width: 100%;
995
- width: -webkit-fill-available;
996
973
  height: 100%;
997
- height: -webkit-fill-available;
998
974
  padding: 0;
999
975
  margin: 0;
1000
976
  }
@@ -1076,9 +1052,7 @@ svg.react-flow__connectionline {
1076
1052
  --_1b6tkn1: calc(1.5rem * var(--mantine-scale));
1077
1053
  position: relative;
1078
1054
  width: 100%;
1079
- width: -webkit-fill-available;
1080
1055
  height: 100%;
1081
- height: -webkit-fill-available;
1082
1056
  padding: var(--_1b6tkn1);
1083
1057
  display: flex;
1084
1058
  flex-direction: column;
@@ -6,5 +6,5 @@ type ElementIconProps = {
6
6
  paddingX?: number | undefined;
7
7
  paddingY?: number | undefined;
8
8
  };
9
- export declare function ElementIcon({ node, maxWidth, paddingX, paddingY }: ElementIconProps): JSX.Element | null;
9
+ export declare function ElementIcon({ node, paddingY }: ElementIconProps): JSX.Element | null;
10
10
  export {};
@@ -1,6 +1,6 @@
1
1
  import { SetReadonly, SetRequired, Simplify } from 'type-fest';
2
2
  import { MouseEvent as ReactMouseEvent } from 'react';
3
- import { Edge, InternalNode, Node, ReactFlowInstance, ReactFlowState, EdgeMouseHandler, NodeMouseHandler, OnMoveEnd, OnMoveStart } from '@xyflow/react';
3
+ import { Edge, EdgeMouseHandler, InternalNode, Node, NodeMouseHandler, OnMoveEnd, OnMoveStart, ReactFlowInstance, ReactFlowState } from '@xyflow/react';
4
4
  import { BBox, DiagramEdge, DiagramNode, Fqn, Point } from '@likec4/core';
5
5
 
6
6
  export type ElementNodeData = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@likec4/diagram",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0",
4
4
  "license": "MIT",
5
5
  "bugs": "https://github.com/likec4/likec4/issues",
6
6
  "homepage": "https://likec4.dev",
@@ -50,7 +50,7 @@
50
50
  "clean": "run -T rimraf -v dist/* .tsbuildinfo"
51
51
  },
52
52
  "dependencies": {
53
- "@likec4/core": "1.0.0-rc.1",
53
+ "@likec4/core": "1.0.0",
54
54
  "@mantine/core": "^7.9.0",
55
55
  "@mantine/hooks": "^7.9.0",
56
56
  "@react-hookz/web": "^24.0.4",
@@ -74,14 +74,14 @@
74
74
  "@vanilla-extract/dynamic": "^2.1.0",
75
75
  "@vanilla-extract/esbuild-plugin": "^2.3.5",
76
76
  "@vitejs/plugin-react": "^4.2.1",
77
- "@xyflow/react": "^12.0.0-next.17",
77
+ "@xyflow/react": "^12.0.0-next",
78
78
  "clsx": "^2.1.1",
79
79
  "execa": "^8.0.1",
80
80
  "khroma": "^2.1.0",
81
81
  "react": "^18.2.0",
82
82
  "react-dom": "^18.2.0",
83
83
  "tilg": "^0.1.1",
84
- "type-fest": "^4.18.1",
84
+ "type-fest": "^4.18.2",
85
85
  "typescript": "^5.4.5",
86
86
  "unbuild": "^2.0.0",
87
87
  "vite": "^5.2.11",
@@ -15,12 +15,14 @@ import type { XYBackgroundProps } from './xyflow/XYFlowBackground'
15
15
 
16
16
  export type DiagramNodeWithNavigate = Simplify<SetRequired<DiagramNode, 'navigateTo'>>
17
17
 
18
- export type OnNavigateTo = (
19
- to: ViewID,
20
- event: ReactMouseEvent,
21
- element: DiagramNodeWithNavigate,
22
- xynode: XYFlowNode
23
- ) => void
18
+ export type OnNavigateTo = {
19
+ (
20
+ to: ViewID,
21
+ event: ReactMouseEvent,
22
+ element: DiagramNodeWithNavigate,
23
+ xynode: XYFlowNode
24
+ ): void
25
+ }
24
26
  export type OnNodeClick = (
25
27
  event: {
26
28
  element: DiagramNode
@@ -62,7 +64,9 @@ export type Change =
62
64
  export type ChangeEvent = {
63
65
  changes: NonEmptyArray<Change>
64
66
  }
65
- export type OnChange = (event: ChangeEvent) => void
67
+ export type OnChange = {
68
+ (event: ChangeEvent): void
69
+ }
66
70
  export type LikeC4ColorScheme = 'light' | 'dark'
67
71
 
68
72
  export interface LikeC4DiagramProperties {
@@ -76,7 +80,7 @@ export interface LikeC4DiagramProperties {
76
80
  *
77
81
  * @example 'light' | 'dark'
78
82
  */
79
- colorScheme?: LikeC4ColorScheme | undefined
83
+ // colorScheme?: LikeC4ColorScheme | undefined
80
84
 
81
85
  /**
82
86
  * Show/hide controls menu
@@ -5,7 +5,8 @@ import { rootClassName } from './globals.css'
5
5
  import { cssDisablePan, cssNoControls, cssReactFlow, cssTransparentBg } from './LikeC4Diagram.css'
6
6
  import { type LikeC4DiagramEventHandlers, type LikeC4DiagramProperties } from './LikeC4Diagram.props'
7
7
  import { EnsureMantine } from './mantine/EnsureMantine'
8
- import { DiagramContextProvider, WhenInitialized } from './state'
8
+ import { DiagramContextProvider } from './state/DiagramContext'
9
+ import { WhenInitialized } from './state/WhenInitialized'
9
10
  import { KeepAspectRatio } from './ui/KeepAspectRatio'
10
11
  import OptionsPanel from './ui/OptionsPanel'
11
12
  import { diagramViewToXYFlowData } from './xyflow/diagram-to-xyflow'
@@ -20,7 +21,6 @@ export function LikeC4Diagram({
20
21
  className,
21
22
  fitView = true,
22
23
  fitViewPadding = 0,
23
- colorScheme,
24
24
  readonly = true,
25
25
  pannable = true,
26
26
  zoomable = true,
@@ -61,7 +61,7 @@ export function LikeC4Diagram({
61
61
  }
62
62
  }
63
63
  return (
64
- <EnsureMantine colorScheme={colorScheme}>
64
+ <EnsureMantine>
65
65
  <XYFlowProvider
66
66
  fitView={fitView}
67
67
  {...initialRef.current}
@@ -6,7 +6,6 @@ export type StaticLikeC4DiagramProps = Pick<
6
6
  | 'view'
7
7
  | 'keepAspectRatio'
8
8
  | 'className'
9
- | 'colorScheme'
10
9
  | 'fitView'
11
10
  | 'fitViewPadding'
12
11
  | 'background'
@@ -1,6 +1,6 @@
1
1
  import type { ThemeColor } from '@likec4/core'
2
2
  import { defaultTheme } from '@likec4/core'
3
- import { createGlobalTheme, createTheme, fallbackVar, globalStyle, style } from '@vanilla-extract/css'
3
+ import { createGlobalTheme } from '@vanilla-extract/css'
4
4
  import { omit } from 'remeda'
5
5
  import { mantine } from './mantine.css'
6
6
  import { vars } from './theme.css'
package/src/index.ts CHANGED
@@ -1,11 +1,10 @@
1
1
  import '@xyflow/react/dist/style.css'
2
2
  import './globals.css'
3
3
 
4
- export { EmbeddedLikeC4Diagram } from './EmbeddedLikeC4Diagram'
5
4
  export { LikeC4Diagram } from './LikeC4Diagram'
6
5
  export { StaticLikeC4Diagram } from './StaticLikeC4Diagram'
7
6
 
8
- export type * from './EmbeddedLikeC4Diagram'
7
+ export * from './hooks'
9
8
  export type * from './LikeC4Diagram'
10
9
  export type * from './LikeC4Diagram.props'
11
10
  export type * from './StaticLikeC4Diagram'
@@ -1,24 +1,14 @@
1
- import { MantineContext, MantineProvider } from '@mantine/core'
1
+ import { MantineContext } from '@mantine/core'
2
2
  import { type PropsWithChildren, useContext } from 'react'
3
- import type { LikeC4DiagramProperties } from '../LikeC4Diagram.props'
4
- import { theme } from './theme'
5
3
 
6
- type EnsureMantineProps = PropsWithChildren<Pick<LikeC4DiagramProperties, 'colorScheme'>>
4
+ type EnsureMantineProps = PropsWithChildren<{}>
7
5
 
8
- export function EnsureMantine({ colorScheme, children }: EnsureMantineProps) {
6
+ export function EnsureMantine({ children }: EnsureMantineProps) {
9
7
  const mantineCtx = useContext(MantineContext)
10
- if (mantineCtx) {
11
- return <>{children}</>
8
+
9
+ if (!mantineCtx) {
10
+ throw new Error('LikeC4Diagram must be a child of MantineProvider')
12
11
  }
13
- return (
14
- <MantineProvider
15
- {...(colorScheme && {
16
- forceColorScheme: colorScheme
17
- })}
18
- theme={theme}
19
- defaultColorScheme="auto"
20
- >
21
- {children}
22
- </MantineProvider>
23
- )
12
+
13
+ return <>{children}</>
24
14
  }
@@ -3,6 +3,7 @@ import { createTheme, type MantineTheme } from '@mantine/core'
3
3
  export const theme = createTheme({
4
4
  primaryColor: 'indigo',
5
5
  cursorType: 'pointer',
6
+ defaultRadius: 'sm',
6
7
  headings: {
7
8
  fontWeight: '500',
8
9
  sizes: {
@@ -1,7 +1,7 @@
1
1
  import { style } from '@vanilla-extract/css'
2
2
 
3
3
  export const wrapper = style({
4
- width: ['100%', '-webkit-fill-available'],
5
- height: ['100%', '-webkit-fill-available'],
4
+ width: '100%',
5
+ height: '100%',
6
6
  padding: 0
7
7
  })
@@ -11,7 +11,7 @@ const OptionsPanelMemo = /* @__PURE__ */ memo(function OptionsPanel() {
11
11
  const [selectedNodes, setSelectedNodes] = useState([] as string[])
12
12
 
13
13
  useOnSelectionChange({
14
- onChange: ({ nodes, edges }) => {
14
+ onChange: ({ nodes }) => {
15
15
  const next = nodes.map(n => n.id).sort()
16
16
  setSelectedNodes(prev => {
17
17
  return shallowEqual(prev, next) ? prev : next
@@ -21,7 +21,7 @@ import {
21
21
  } from '@mantine/core'
22
22
  import { hasAtLeast, keys, takeWhile } from 'remeda'
23
23
  import { useDiagramStoreApi } from '../../state'
24
- import { useXYFlow, useXYNodesData } from '../../xyflow/hooks'
24
+ import { useXYNodesData } from '../../xyflow/hooks'
25
25
  import { XYFlowNode } from '../../xyflow/types'
26
26
 
27
27
  // const ColorPanel = () => {
@@ -54,7 +54,6 @@ type XYNodesData = Pick<XYFlowNode, 'id' | 'data' | 'type'>
54
54
  export function NodeOptions({ selectedNodeIds }: { selectedNodeIds: string[] }) {
55
55
  const diagramApi = useDiagramStoreApi()
56
56
  const nodes = useXYNodesData(selectedNodeIds)
57
- const api = useXYFlow()
58
57
  if (!hasAtLeast(nodes, 1)) {
59
58
  return null
60
59
  }
@@ -38,7 +38,7 @@ function FitViewOnDiagramChanges() {
38
38
  const diagramApi = useDiagramStoreApi()
39
39
  const [viewportMoved, setViewportMoved] = useState(diagramApi.getState().viewportChanged)
40
40
  const [processedChangeId, setProcessed] = useState(diagramChangeId(diagramApi.getState()))
41
- const [pendingChangeId, setPending] = useDebouncedState(processedChangeId, 50)
41
+ const [pendingChangeId, setPending] = useDebouncedState(processedChangeId, 100)
42
42
 
43
43
  const isReady = useNodesInitialized({
44
44
  includeHiddenNodes: true
@@ -1,30 +1,15 @@
1
1
  import { deepEqual as eq, shallowEqual } from 'fast-equals'
2
2
  import { useXYFlow, useXYStoreApi } from './hooks'
3
- import type { XYFlowEdge, XYFlowNode } from './types'
3
+ import type { XYFlowNode } from './types'
4
4
 
5
- import { memo, useCallback, useEffect } from 'react'
6
- import { type DiagramState, useDiagramStoreApi } from '../state'
5
+ import { memo, useEffect } from 'react'
6
+ import { useDiagramStoreApi } from '../state'
7
7
  import { diagramViewToXYFlowData } from './diagram-to-xyflow'
8
8
  import { toDomPrecision } from './utils'
9
9
 
10
10
  const isSameNode = (a: XYFlowNode) => (b: XYFlowNode) =>
11
11
  a.id === b.id && a.type === b.type && Object.is(a.parentId, b.parentId)
12
12
 
13
- function hasNoChanges(existing: XYFlowNode, update: XYFlowNode) {
14
- return existing.id === update.id
15
- && existing.type === update.type
16
- && existing.parentId == update.parentId
17
- && eq(existing.data.element, update.data.element)
18
- }
19
-
20
- function edgeHasNoChanges(existing: XYFlowEdge, update: XYFlowEdge) {
21
- return existing.id === update.id
22
- && existing.type === update.type
23
- && existing.source === update.source
24
- && existing.target === update.target
25
- && eq(existing.data, update.data)
26
- }
27
-
28
13
  /**
29
14
  * Syncs the diagram state with the XYFlow instance
30
15
  */
@@ -33,51 +18,6 @@ export const SyncWithDiagram = memo(() => {
33
18
  const xyflowApi = useXYStoreApi()
34
19
  const diagramStoreApi = useDiagramStoreApi()
35
20
 
36
- const correctPosition = useCallback((
37
- lastOnNavigate: NonNullable<DiagramState['lastOnNavigate']>,
38
- nodes: DiagramState['view']['nodes']
39
- ) => {
40
- // const {
41
- // lastOnNavigate,
42
- // view: {
43
- // nodes,
44
- // id: viewId
45
- // }
46
- // } = diagramStoreApi.getState()
47
- // if (lastOnNavigate.toView !== viewId || lastOnNavigate.positionCorrected) {
48
- // return
49
- // }
50
-
51
- const elFrom = lastOnNavigate.element
52
- const elTo = nodes.find(n => n.id === elFrom.id)
53
- if (elTo) {
54
- const centerFrom = lastOnNavigate.elementCenterScreenPosition,
55
- centerTo = xyflow.flowToScreenPosition({
56
- x: elTo.position[0] + elTo.width / 2,
57
- y: elTo.position[1] + elTo.height / 2
58
- }),
59
- diff = {
60
- x: toDomPrecision(centerFrom.x - centerTo.x),
61
- y: toDomPrecision(centerFrom.y - centerTo.y)
62
- }
63
- requestAnimationFrame(() => {
64
- xyflowApi.getState().panBy(diff)
65
- })
66
- }
67
- queueMicrotask(() => {
68
- diagramStoreApi.setState(
69
- {
70
- lastOnNavigate: {
71
- ...lastOnNavigate,
72
- positionCorrected: true
73
- }
74
- },
75
- false,
76
- 'positionCorrected'
77
- )
78
- })
79
- }, [diagramStoreApi, xyflowApi])
80
-
81
21
  useEffect(() => {
82
22
  return diagramStoreApi.subscribe(
83
23
  // selector
@@ -123,28 +63,30 @@ export const SyncWithDiagram = memo(() => {
123
63
  )
124
64
 
125
65
  if (lastOnNavigate?.toView === viewId && !lastOnNavigate.positionCorrected) {
126
- // correctPosition(
127
- // lastOnNavigate,
128
- // nodes
129
- // )
130
66
  const elFrom = lastOnNavigate.element
131
67
  const elTo = nodes.find(n => n.id === elFrom.id)
132
68
  if (elTo) {
133
- const centerFrom = lastOnNavigate.elementCenterScreenPosition,
134
- // xyflow.flowToScreenPosition({
135
- // x: elFrom.position[0] + elFrom.width / 2,
136
- // y: elFrom.position[1] + elFrom.height / 2
137
- // }),
138
- centerTo = xyflow.flowToScreenPosition({
139
- x: elTo.position[0] + elTo.width / 2,
140
- y: elTo.position[1] + elTo.height / 2
141
- }),
142
- diff = {
143
- x: toDomPrecision(centerFrom.x - centerTo.x),
144
- y: toDomPrecision(centerFrom.y - centerTo.y)
145
- }
69
+ const centerFrom = lastOnNavigate.elementCenterScreenPosition
70
+ const nextZoom = Math.min(elFrom.width / elTo.width, elFrom.height / elTo.height)
71
+
146
72
  requestAnimationFrame(() => {
147
73
  requestAnimationFrame(() => {
74
+ const v = xyflow.getViewport()
75
+ if (nextZoom < v.zoom) {
76
+ xyflow.setViewport({
77
+ x: v.x,
78
+ y: v.y,
79
+ zoom: nextZoom
80
+ })
81
+ }
82
+ const centerTo = xyflow.flowToScreenPosition({
83
+ x: elTo.position[0] + elTo.width / 2,
84
+ y: elTo.position[1] + elTo.height / 2
85
+ }),
86
+ diff = {
87
+ x: toDomPrecision(centerFrom.x - centerTo.x),
88
+ y: toDomPrecision(centerFrom.y - centerTo.y)
89
+ }
148
90
  xyflowApi.getState().panBy(diff)
149
91
  })
150
92
  })
@@ -165,7 +107,7 @@ export const SyncWithDiagram = memo(() => {
165
107
  equalityFn: shallowEqual
166
108
  }
167
109
  )
168
- }, [xyflow, xyflowApi, diagramStoreApi, correctPosition])
110
+ }, [xyflow, xyflowApi, diagramStoreApi])
169
111
 
170
112
  return null
171
113
  })
@@ -1,5 +1,4 @@
1
- import { nonNullable } from '@likec4/core'
2
- import type { EdgeMouseHandler, NodeMouseHandler, OnMoveEnd, OnMoveStart, Viewport } from '@xyflow/react'
1
+ import type { EdgeMouseHandler, NodeMouseHandler, OnMoveEnd } from '@xyflow/react'
3
2
  import type { MouseEvent as ReactMouseEvent } from 'react'
4
3
  import { useMemo, useRef } from 'react'
5
4
  import { useDiagramStoreApi } from '../state'
@@ -1,6 +1,6 @@
1
1
  import { useMantineColorScheme } from '@mantine/core'
2
- import { Controls, ReactFlow as GenericReactFlow, type ReactFlowProps } from '@xyflow/react'
3
- import { type CSSProperties, memo, type PropsWithChildren, type RefAttributes } from 'react'
2
+ import { Controls, ReactFlow } from '@xyflow/react'
3
+ import { type CSSProperties, memo, type PropsWithChildren } from 'react'
4
4
  import type { SetNonNullable, Simplify } from 'type-fest'
5
5
  import type { LikeC4DiagramProperties } from '../LikeC4Diagram.props'
6
6
  import { type DiagramState, useDiagramState, useDiagramStoreApi } from '../state'
@@ -13,10 +13,6 @@ import { XYFlowEdge, XYFlowNode } from './types'
13
13
  import { XYFlowBackground } from './XYFlowBackground'
14
14
  import { useXYFlowEvents } from './XYFlowEvents'
15
15
 
16
- // @ts-expect-error - typing in @xyflow/react
17
- const ReactFlow: (props: ReactFlowProps<XYFlowNode, XYFlowEdge> & RefAttributes<HTMLDivElement>) => JSX.Element =
18
- GenericReactFlow
19
-
20
16
  const nodeTypes = {
21
17
  element: ElementNode,
22
18
  compound: CompoundNode
@@ -89,7 +85,7 @@ function XYFlowWrapper({
89
85
  const colorMode = colorScheme !== 'auto' ? colorScheme : undefined
90
86
 
91
87
  return (
92
- <ReactFlow
88
+ <ReactFlow<XYFlowNode, XYFlowEdge>
93
89
  className={className}
94
90
  style={style}
95
91
  {...colorMode && { colorMode }}
@@ -1,5 +1,5 @@
1
1
  import { invariant, type NonEmptyArray, nonNullable, type Point } from '@likec4/core'
2
- import { Box, Text } from '@mantine/core'
2
+ import { Box } from '@mantine/core'
3
3
  import { assignInlineVars } from '@vanilla-extract/dynamic'
4
4
  import type { EdgeProps, XYPosition } from '@xyflow/react'
5
5
  import { EdgeLabelRenderer, getBezierPath } from '@xyflow/react'
@@ -93,8 +93,8 @@ const isEqualProps = (prev: EdgeProps<XYFlowEdge>, next: EdgeProps<XYFlowEdge>)
93
93
  export const RelationshipEdge = /* @__PURE__ */ memo<EdgeProps<XYFlowEdge>>(function RelationshipEdgeR({
94
94
  id,
95
95
  data,
96
- selected,
97
- markerEnd,
96
+ selected: _selected,
97
+ markerEnd: _markerEnd,
98
98
  style,
99
99
  source,
100
100
  target,
@@ -109,8 +109,7 @@ export const RelationshipEdge = /* @__PURE__ */ memo<EdgeProps<XYFlowEdge>>(func
109
109
 
110
110
  invariant(data, 'data is required')
111
111
  const {
112
- edge,
113
- controlPoints
112
+ edge
114
113
  } = data
115
114
  // const edgePath = bezierPath(edge.points)
116
115
 
@@ -46,6 +46,9 @@ globalStyle(`.react-flow__edge.selected ${container}`, {
46
46
  })
47
47
 
48
48
  globalStyle(`.react-flow__edges > svg`, {
49
+ mixBlendMode: 'screen'
50
+ })
51
+ globalStyle(`:where([data-mantine-color-scheme="dark"]) .react-flow__edges > svg`, {
49
52
  mixBlendMode: 'lighten'
50
53
  })
51
54
 
@@ -4,8 +4,8 @@ import { mantine } from '../../../mantine.css'
4
4
  import { vars } from '../../../theme.css'
5
5
 
6
6
  export const cssContainer = style({
7
- width: ['100%', '-webkit-fill-available'],
8
- height: ['100%', '-webkit-fill-available'],
7
+ width: '100%',
8
+ height: '100%',
9
9
  position: 'relative',
10
10
  padding: 0,
11
11
  margin: 0
@@ -40,6 +40,7 @@ export const cssCompound = style({
40
40
  }
41
41
  })
42
42
 
43
+ // @ts-ignore
43
44
  const cssTransparentCompound = style({
44
45
  width: '100%',
45
46
  height: '100%',
@@ -16,6 +16,8 @@ type CompoundNodeProps = Pick<
16
16
  NodeProps<CompoundXYFlowNode>,
17
17
  'id' | 'data' | 'width' | 'height' | 'selected'
18
18
  >
19
+
20
+ // @ts-ignore
19
21
  const isEqualProps = (prev: CompoundNodeProps, next: CompoundNodeProps) => (
20
22
  prev.id === next.id
21
23
  && prev.selected === next.selected
@@ -72,7 +74,6 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>(function
72
74
  }}
73
75
  >
74
76
  <Handle
75
- // @ts-expect-error
76
77
  type="target"
77
78
  position={Position.Top}
78
79
  style={{ visibility: 'hidden' }}
@@ -95,7 +96,6 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>(function
95
96
  </div>
96
97
  {isnavigable && <NavigateToBtn xynodeId={id} className={cssNavigateBtn} />}
97
98
  <Handle
98
- // @ts-expect-error
99
99
  type="source"
100
100
  position={Position.Bottom}
101
101
  style={{ visibility: 'hidden' }}
@@ -12,8 +12,6 @@ type ElementIconProps = {
12
12
 
13
13
  export function ElementIcon({
14
14
  node,
15
- maxWidth,
16
- paddingX = 32,
17
15
  paddingY = 32
18
16
  }: ElementIconProps) {
19
17
  if (!node.icon) {
@@ -26,7 +24,7 @@ export function ElementIcon({
26
24
 
27
25
  const firstLabelY = Math.floor(firstLabel.pt[1] - firstLabel.fontSize * 1.25)
28
26
  const maxIconHeight = Math.floor(firstLabelY - paddingY - 16)
29
- const maxIconWidth = maxWidth ?? node.width - paddingX * 2
27
+ // const maxIconWidth = maxWidth ?? node.width - paddingX * 2
30
28
 
31
29
  // const centerY = paddingY + Math.floor(maxIconHeight / 2)
32
30
  // const centerX = Math.floor(node.width / 2)
@@ -19,8 +19,8 @@ export const elementLink = style({
19
19
  }
20
20
  // fontSize: rem(10),
21
21
  // height: 12,
22
- // width: ['100%', '-webkit-fill-available'],
23
- // height: ['100%', '-webkit-fill-available'],
22
+ // width: '100%',
23
+ // height: '100%',
24
24
  // vars: {
25
25
  // [stokeFillMix]: `color-mix(in srgb, ${vars.element.stroke} 90%, ${vars.element.fill})`
26
26
  // }
@@ -68,9 +68,9 @@ export function ElementLink({
68
68
  <span>links</span>
69
69
  </UnstyledButton>
70
70
  </HoverCardTarget>
71
- <HoverCardDropdown p={'xs'}>
72
- <Stack onClick={e => e.stopPropagation()} gap={'xs'}>
73
- {element.links.map((link, i) => (
71
+ <HoverCardDropdown onClick={e => e.stopPropagation()} p={'xs'}>
72
+ <Stack gap={'xs'}>
73
+ {element.links.map((link) => (
74
74
  <Group key={link} wrap="nowrap" gap={'sm'}>
75
75
  <Box flex={'1'} style={{ overflow: 'clip', maxWidth: clamp(element.width, { min: 200, max: 400 }) }}>
76
76
  <Anchor href={link} target="_blank" fz="13" truncate="end">
@@ -157,7 +157,6 @@ export function ElementNode({
157
157
  ))} */
158
158
  }
159
159
  <Handle
160
- // @ts-expect-error
161
160
  type="target"
162
161
  position={Position.Top}
163
162
  style={{ visibility: 'hidden' }}
@@ -204,7 +203,6 @@ export function ElementNode({
204
203
  )}
205
204
  </div>
206
205
  <Handle
207
- // @ts-expect-error
208
206
  type="source"
209
207
  position={Position.Bottom}
210
208
  style={{ visibility: 'hidden' }}