@likec4/diagram 1.17.1 → 1.18.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/package.json +17 -15
- package/src/LikeC4Diagram.props.ts +21 -12
- package/src/LikeC4Diagram.tsx +5 -7
- package/src/LikeC4Search.tsx +54 -51
- package/src/hooks/useDiagramState.ts +8 -3
- package/src/hooks/useXYFlow.ts +2 -1
- package/src/likec4model/useLikeC4ElementsTree.ts +6 -13
- package/src/likec4model/useLikeC4Model.ts +21 -11
- package/src/overlays/Overlays.tsx +96 -63
- package/src/overlays/edge-details/EdgeDetailsXYFlow.tsx +3 -1
- package/src/overlays/edge-details/_types.ts +7 -3
- package/src/overlays/edge-details/use-layouted-edge-details.ts +21 -14
- package/src/overlays/edge-details/xyflow/ElementNode.tsx +4 -2
- package/src/overlays/edge-details/xyflow/RelationshipEdge.tsx +4 -4
- package/src/overlays/element-details/ElementDetailsCard.tsx +91 -78
- package/src/overlays/element-details/TabPanelDeployments.css.ts +69 -0
- package/src/overlays/element-details/TabPanelDeployments.tsx +217 -0
- package/src/overlays/element-details/TabPanelRelationships.tsx +8 -9
- package/src/overlays/element-details/TabPanelStructure.tsx +10 -10
- package/src/overlays/relationships-of/RelationshipsOverlay.tsx +1 -1
- package/src/overlays/relationships-of/RelationshipsXYFlow.tsx +3 -11
- package/src/overlays/relationships-of/SelectElement.tsx +2 -2
- package/src/overlays/relationships-of/_types.ts +2 -2
- package/src/overlays/relationships-of/use-layouted-relationships.ts +18 -19
- package/src/overlays/relationships-of/xyflow/CompoundNode.tsx +1 -3
- package/src/overlays/relationships-of/xyflow/ElementNode.tsx +12 -6
- package/src/overlays/relationships-of/xyflow/RelationshipEdge.tsx +0 -1
- package/src/state/diagramStore.ts +28 -11
- package/src/ui/DiagramTitlePanel.tsx +2 -29
- package/src/ui/Link.tsx +40 -0
- package/src/ui/notation/NotationPanel.tsx +4 -2
- package/src/ui/top-left/ChangeAutoLayoutButton.tsx +2 -2
- package/src/ui/top-left/TopLeftPanel.tsx +5 -5
- package/src/xyflow/edges/EdgeLabel.tsx +4 -4
- package/src/xyflow/edges/RelationshipsDropdownMenu.tsx +20 -7
- package/src/xyflow/nodes/compound/CompoundNode.css.ts +28 -13
- package/src/xyflow/nodes/compound/CompoundNode.tsx +51 -19
- package/src/xyflow/nodes/element/ElementNode.tsx +147 -124
- package/src/xyflow/nodes/element/element.css.ts +52 -19
- package/src/xyflow/nodes/shared/ElementIcon.tsx +1 -1
- package/src/xyflow/nodes/shared/Toolbar.tsx +24 -8
- package/src/xyflow/useLayoutConstraints.ts +1 -1
- package/src/xyflow/useXYFlowEvents.ts +18 -5
- package/src/ui/OptionsPanel.css.ts +0 -9
- package/src/ui/OptionsPanel.tsx +0 -70
- package/src/ui/options/EdgeOptions.tsx +0 -142
- package/src/ui/options/NodeOptions.tsx +0 -362
- package/src/xyflow/nodes/element/ElementDetails.css.ts +0 -101
- package/src/xyflow/nodes/element/ElementDetails.tsx +0 -393
|
@@ -16,11 +16,12 @@ import {
|
|
|
16
16
|
Tooltip as MantineTooltip,
|
|
17
17
|
TooltipGroup
|
|
18
18
|
} from '@mantine/core'
|
|
19
|
-
import { IconArrowRight,
|
|
19
|
+
import { IconArrowRight, IconFileSymlink, IconInfoCircle, IconZoomScan } from '@tabler/icons-react'
|
|
20
20
|
import clsx from 'clsx'
|
|
21
21
|
import { forwardRef, Fragment, type MouseEventHandler, type PropsWithChildren, useCallback } from 'react'
|
|
22
22
|
import { filter, isTruthy, map, partition, pick, pipe } from 'remeda'
|
|
23
23
|
import { useDiagramState, useDiagramStoreApi, useMantinePortalProps, useXYNodesData } from '../../hooks'
|
|
24
|
+
import { Link } from '../../ui/Link'
|
|
24
25
|
import type { RelationshipData } from '../types'
|
|
25
26
|
import * as css from './RelationshipsDropdownMenu.css'
|
|
26
27
|
|
|
@@ -72,7 +73,7 @@ export function RelationshipsDropdownMenu({
|
|
|
72
73
|
}
|
|
73
74
|
}),
|
|
74
75
|
filter(isTruthy),
|
|
75
|
-
partition(r => r.
|
|
76
|
+
partition(r => r.source.id === edge.source && r.target.id === edge.target)
|
|
76
77
|
)
|
|
77
78
|
|
|
78
79
|
const onClickOpenOverlay = useCallback((e: React.MouseEvent): void => {
|
|
@@ -84,7 +85,7 @@ export function RelationshipsDropdownMenu({
|
|
|
84
85
|
}
|
|
85
86
|
}, [edge.id, openOverlay, enableRelationshipBrowser])
|
|
86
87
|
|
|
87
|
-
const renderRelationship = (relationship: LikeC4Model.
|
|
88
|
+
const renderRelationship = (relationship: LikeC4Model.AnyRelation, index: number) => (
|
|
88
89
|
<Fragment key={relationship.id}>
|
|
89
90
|
{index > 0 && <MenuDivider opacity={0.65} />}
|
|
90
91
|
<MenuItem
|
|
@@ -155,7 +156,7 @@ export function RelationshipsDropdownMenu({
|
|
|
155
156
|
const Relationship = forwardRef<
|
|
156
157
|
HTMLDivElement,
|
|
157
158
|
StackProps & {
|
|
158
|
-
relationship: LikeC4Model.
|
|
159
|
+
relationship: LikeC4Model.AnyRelation
|
|
159
160
|
edge: RelationshipData['edge']
|
|
160
161
|
sourceNode: DiagramNode
|
|
161
162
|
targetNode: DiagramNode
|
|
@@ -175,12 +176,13 @@ const Relationship = forwardRef<
|
|
|
175
176
|
hasOnNavigateTo
|
|
176
177
|
} = useDiagramState(s => ({
|
|
177
178
|
viewId: s.view.id,
|
|
178
|
-
hasOnOpenSourceRelation: !!s.
|
|
179
|
+
hasOnOpenSourceRelation: !!s.onOpenSource,
|
|
179
180
|
hasOnNavigateTo: !!s.onNavigateTo
|
|
180
181
|
}))
|
|
181
182
|
const sourceId = nameFromFqn(edge.source) + r.source.id.slice(edge.source.length)
|
|
182
183
|
const targetId = nameFromFqn(edge.target) + r.target.id.slice(edge.target.length)
|
|
183
|
-
const navigateTo = hasOnNavigateTo && r.
|
|
184
|
+
const navigateTo = hasOnNavigateTo && r.navigateTo?.id !== viewId ? r.navigateTo?.id : undefined
|
|
185
|
+
const links = r.links
|
|
184
186
|
|
|
185
187
|
return (
|
|
186
188
|
<Stack ref={ref} className={clsx(css.menuItemRelationship, className)} {...props}>
|
|
@@ -223,7 +225,9 @@ const Relationship = forwardRef<
|
|
|
223
225
|
onPointerDownCapture={stopPropagation}
|
|
224
226
|
onClick={event => {
|
|
225
227
|
event.stopPropagation()
|
|
226
|
-
diagramApi.getState().
|
|
228
|
+
diagramApi.getState().onOpenSource?.({
|
|
229
|
+
relation: r.id
|
|
230
|
+
})
|
|
227
231
|
}}
|
|
228
232
|
role="button"
|
|
229
233
|
>
|
|
@@ -235,6 +239,15 @@ const Relationship = forwardRef<
|
|
|
235
239
|
)}
|
|
236
240
|
</Group>
|
|
237
241
|
<Box className={css.title}>{r.title || 'untitled'}</Box>
|
|
242
|
+
{r.description && <Text size="xs" c="dimmed">{r.description}</Text>}
|
|
243
|
+
{links.length > 0 && (
|
|
244
|
+
<Stack
|
|
245
|
+
gap={3}
|
|
246
|
+
justify="stretch"
|
|
247
|
+
align="stretch">
|
|
248
|
+
{links.map((link) => <Link key={link.url} link={link} />)}
|
|
249
|
+
</Stack>
|
|
250
|
+
)}
|
|
238
251
|
</Stack>
|
|
239
252
|
)
|
|
240
253
|
})
|
|
@@ -49,7 +49,20 @@ globalStyle(`.react-flow__node-compound:has(${dimmed})`, {
|
|
|
49
49
|
willChange: 'opacity, filter'
|
|
50
50
|
})
|
|
51
51
|
|
|
52
|
+
globalStyle(`:where([data-mantine-color-scheme='dark'] .likec4-compound-transparent)`, {
|
|
53
|
+
vars: {
|
|
54
|
+
['--_compound-border-color']: `color-mix(in srgb, ${vars.compound.titleColor} 25%, ${vars.element.stroke})`
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
globalStyle(`:where([data-mantine-color-scheme='light'] .likec4-compound-transparent)`, {
|
|
58
|
+
vars: {
|
|
59
|
+
['--_compound-title-color']: vars.element.stroke
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
|
|
52
63
|
export const varOpacity = createVar('opacity')
|
|
64
|
+
export const varBorderColor = createVar('border-color')
|
|
65
|
+
export const varBorderRadius = createVar('border-transparency')
|
|
53
66
|
export const varBorderTransparency = createVar('border-transparency')
|
|
54
67
|
|
|
55
68
|
const outlineColor = fallbackVar(
|
|
@@ -62,14 +75,17 @@ export const compoundBody = style({
|
|
|
62
75
|
width: '100%',
|
|
63
76
|
height: '100%',
|
|
64
77
|
position: 'relative',
|
|
65
|
-
borderRadius:
|
|
78
|
+
borderRadius: varBorderRadius,
|
|
66
79
|
boxShadow: '0 4px 10px 0.5px rgba(0,0,0,0.1) , 0 2px 2px -1px rgba(0,0,0,0.4)',
|
|
67
80
|
padding: 0,
|
|
68
81
|
margin: 0,
|
|
69
82
|
transition: 'all 200ms ease-out',
|
|
70
|
-
backgroundClip: 'padding-box',
|
|
83
|
+
// backgroundClip: 'padding-box',
|
|
71
84
|
// overflow: 'hidden',
|
|
72
85
|
cursor: 'default',
|
|
86
|
+
vars: {
|
|
87
|
+
[varBorderRadius]: '6px'
|
|
88
|
+
},
|
|
73
89
|
selectors: {
|
|
74
90
|
[`:where(.react-flow__node.selected) &`]: {
|
|
75
91
|
boxShadow: 'none'
|
|
@@ -88,8 +104,11 @@ export const compoundBody = style({
|
|
|
88
104
|
width: '100%',
|
|
89
105
|
height: '100%',
|
|
90
106
|
pointerEvents: 'none',
|
|
107
|
+
border: '1px solid transparent',
|
|
108
|
+
borderRadius: varBorderRadius,
|
|
91
109
|
transition: 'background 175ms ease-out, opacity 175ms ease-out',
|
|
92
|
-
background: vars.element.fill
|
|
110
|
+
background: vars.element.fill,
|
|
111
|
+
backgroundClip: 'border-box'
|
|
93
112
|
}
|
|
94
113
|
})
|
|
95
114
|
export const compoundTitle = style({
|
|
@@ -97,19 +116,20 @@ export const compoundTitle = style({
|
|
|
97
116
|
alignItems: 'center',
|
|
98
117
|
gap: 6,
|
|
99
118
|
paddingLeft: 14,
|
|
100
|
-
paddingTop:
|
|
119
|
+
paddingTop: 6,
|
|
101
120
|
minHeight: 30,
|
|
121
|
+
paddingRight: 2,
|
|
102
122
|
selectors: {
|
|
103
123
|
[`:where(.react-flow__node.draggable) &`]: {
|
|
104
124
|
cursor: 'grab'
|
|
105
125
|
},
|
|
106
126
|
[`:where(.likec4-compound-transparent) &`]: {
|
|
107
|
-
paddingTop:
|
|
127
|
+
paddingTop: 3
|
|
108
128
|
}
|
|
109
129
|
}
|
|
110
130
|
})
|
|
111
131
|
export const withNavigation = style({
|
|
112
|
-
paddingLeft:
|
|
132
|
+
paddingLeft: 32
|
|
113
133
|
})
|
|
114
134
|
|
|
115
135
|
const opacityDeltaOnHover = createVar('opacityDeltaOnHover')
|
|
@@ -117,8 +137,9 @@ export const transparent = style({
|
|
|
117
137
|
borderStyle: 'dashed',
|
|
118
138
|
borderWidth: 3,
|
|
119
139
|
boxShadow: 'none',
|
|
120
|
-
borderColor: `color-mix(in srgb , ${
|
|
140
|
+
borderColor: `color-mix(in srgb , ${varBorderColor}, transparent ${fallbackVar(varBorderTransparency, '5%')})`,
|
|
121
141
|
vars: {
|
|
142
|
+
[varBorderColor]: `var(--_compound-border-color,${vars.element.stroke})`,
|
|
122
143
|
[opacityDeltaOnHover]: '0'
|
|
123
144
|
},
|
|
124
145
|
':before': {
|
|
@@ -156,12 +177,6 @@ export const title = style({
|
|
|
156
177
|
mixBlendMode: 'screen'
|
|
157
178
|
})
|
|
158
179
|
|
|
159
|
-
globalStyle(`:where([data-mantine-color-scheme='light'] .likec4-compound-transparent)`, {
|
|
160
|
-
vars: {
|
|
161
|
-
['--_compound-title-color']: vars.element.stroke
|
|
162
|
-
}
|
|
163
|
-
})
|
|
164
|
-
|
|
165
180
|
const indicatorKeyframes = keyframes({
|
|
166
181
|
'from': {
|
|
167
182
|
opacity: 0.6
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { type ThemeColor } from '@likec4/core'
|
|
1
|
+
import { DiagramNode, type ThemeColor } from '@likec4/core'
|
|
2
2
|
import { ActionIcon, Box, Text, Tooltip } from '@mantine/core'
|
|
3
3
|
import { useDebouncedValue } from '@mantine/hooks'
|
|
4
|
-
import { IconId,
|
|
4
|
+
import { IconId, IconZoomScan } from '@tabler/icons-react'
|
|
5
5
|
import { assignInlineVars } from '@vanilla-extract/dynamic'
|
|
6
6
|
import { Handle, type NodeProps, Position } from '@xyflow/react'
|
|
7
7
|
import clsx from 'clsx'
|
|
8
8
|
import { deepEqual as eq } from 'fast-equals'
|
|
9
9
|
import { m, type Variants } from 'framer-motion'
|
|
10
10
|
import { memo, useCallback, useState } from 'react'
|
|
11
|
-
import { clamp
|
|
11
|
+
import { clamp } from 'remeda'
|
|
12
12
|
import { useDiagramState } from '../../../hooks/useDiagramState'
|
|
13
13
|
import type { CompoundXYFlowNode } from '../../types'
|
|
14
14
|
import { stopPropagation } from '../../utils'
|
|
@@ -30,14 +30,28 @@ const isEqualProps = (prev: CompoundNodeProps, next: CompoundNodeProps) => (
|
|
|
30
30
|
)
|
|
31
31
|
|
|
32
32
|
const VariantsRoot = {
|
|
33
|
-
idle: {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
idle: (_, { translateZ }) => ({
|
|
34
|
+
// Why? translateZ is used to determine state
|
|
35
|
+
...translateZ !== 0 && {
|
|
36
|
+
transition: {
|
|
37
|
+
delayChildren: .08
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
transitionEnd: {
|
|
41
|
+
translateZ: 0
|
|
37
42
|
}
|
|
38
|
-
},
|
|
43
|
+
}),
|
|
39
44
|
selected: {},
|
|
40
|
-
hovered: {}
|
|
45
|
+
hovered: (_, { translateZ }) => ({
|
|
46
|
+
...translateZ !== 1 && {
|
|
47
|
+
transition: {
|
|
48
|
+
delayChildren: .08
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
transitionEnd: {
|
|
52
|
+
translateZ: 1
|
|
53
|
+
}
|
|
54
|
+
}),
|
|
41
55
|
tap: {}
|
|
42
56
|
} satisfies Variants
|
|
43
57
|
|
|
@@ -61,18 +75,21 @@ const VariantsNavigate = {
|
|
|
61
75
|
'hovered:navigate': {
|
|
62
76
|
scale: 1.42
|
|
63
77
|
},
|
|
64
|
-
'hovered:
|
|
78
|
+
'hovered:details': {},
|
|
65
79
|
'tap:navigate': {
|
|
66
80
|
scale: 1.15
|
|
67
81
|
}
|
|
68
82
|
} satisfies Variants
|
|
69
|
-
VariantsNavigate['selected'] = VariantsNavigate
|
|
83
|
+
VariantsNavigate['selected'] = VariantsNavigate.hovered
|
|
84
|
+
VariantsNavigate['hovered:details'] = VariantsNavigate.idle
|
|
70
85
|
|
|
71
86
|
const VariantsDetailsBtn = {
|
|
72
87
|
idle: {
|
|
73
88
|
'--ai-bg': 'var(--ai-bg-idle)',
|
|
74
89
|
scale: 1,
|
|
75
|
-
opacity: 0.3
|
|
90
|
+
opacity: 0.3,
|
|
91
|
+
originX: 0.45,
|
|
92
|
+
originY: 0.55
|
|
76
93
|
},
|
|
77
94
|
selected: {},
|
|
78
95
|
hovered: {
|
|
@@ -100,15 +117,17 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>((
|
|
|
100
117
|
}
|
|
101
118
|
}
|
|
102
119
|
) => {
|
|
120
|
+
const modelRef = DiagramNode.modelRef(element)
|
|
103
121
|
const { depth, style, color } = element
|
|
104
122
|
const isNotViewGroup = !isViewGroup
|
|
105
123
|
const opacity = clamp((style.opacity ?? 100) / 100, {
|
|
106
124
|
min: 0,
|
|
107
125
|
max: 1
|
|
108
126
|
})
|
|
109
|
-
const
|
|
127
|
+
const MAX_TRANSPARENCY = 40
|
|
128
|
+
const borderTransparency = clamp(MAX_TRANSPARENCY - opacity * MAX_TRANSPARENCY, {
|
|
110
129
|
min: 0,
|
|
111
|
-
max:
|
|
130
|
+
max: MAX_TRANSPARENCY
|
|
112
131
|
})
|
|
113
132
|
|
|
114
133
|
const {
|
|
@@ -121,6 +140,7 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>((
|
|
|
121
140
|
isInteractive,
|
|
122
141
|
isNavigable,
|
|
123
142
|
renderIcon,
|
|
143
|
+
isInActiveOverlay,
|
|
124
144
|
enableElementDetails
|
|
125
145
|
} = useDiagramState(s => ({
|
|
126
146
|
viewId: s.view.id,
|
|
@@ -134,6 +154,7 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>((
|
|
|
134
154
|
// If this is a view group, we don't want to show the navigate button
|
|
135
155
|
isNavigable: isNotViewGroup && !!s.onNavigateTo && !!element.navigateTo,
|
|
136
156
|
renderIcon: s.renderIcon,
|
|
157
|
+
isInActiveOverlay: (s.activeOverlay?.elementDetails ?? s.activeOverlay?.relationshipsOf) === id,
|
|
137
158
|
enableElementDetails: isNotViewGroup && s.enableElementDetails
|
|
138
159
|
}))
|
|
139
160
|
const _isToolbarVisible = isNotViewGroup && isEditable && (isHovered || (import.meta.env.DEV && selected))
|
|
@@ -143,6 +164,9 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>((
|
|
|
143
164
|
|
|
144
165
|
let animate: keyof typeof VariantsRoot
|
|
145
166
|
switch (true) {
|
|
167
|
+
case isInActiveOverlay:
|
|
168
|
+
animate = 'idle'
|
|
169
|
+
break
|
|
146
170
|
case dragging && selected:
|
|
147
171
|
animate = 'selected'
|
|
148
172
|
break
|
|
@@ -169,7 +193,7 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>((
|
|
|
169
193
|
const onOpenDetails = useCallback((e: React.MouseEvent) => {
|
|
170
194
|
e.stopPropagation()
|
|
171
195
|
openOverlay({ elementDetails: element.id })
|
|
172
|
-
}, [openOverlay, element
|
|
196
|
+
}, [openOverlay, element])
|
|
173
197
|
|
|
174
198
|
const elementIcon = ElementIcon({
|
|
175
199
|
element,
|
|
@@ -189,6 +213,7 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>((
|
|
|
189
213
|
)}
|
|
190
214
|
<Box
|
|
191
215
|
component={m.div}
|
|
216
|
+
variants={VariantsRoot}
|
|
192
217
|
key={`${viewId}:element:${id}`}
|
|
193
218
|
layoutId={`${viewId}:element:${id}`}
|
|
194
219
|
className={css.containerForFramer}>
|
|
@@ -196,7 +221,7 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>((
|
|
|
196
221
|
component={m.div}
|
|
197
222
|
variants={VariantsRoot}
|
|
198
223
|
initial={false}
|
|
199
|
-
animate={(isHovered && !dragging) ? (animateVariants ?? animate) : animate}
|
|
224
|
+
animate={(isHovered && !dragging && !isInActiveOverlay) ? (animateVariants ?? animate) : animate}
|
|
200
225
|
className={clsx(
|
|
201
226
|
css.container,
|
|
202
227
|
'likec4-compound-node',
|
|
@@ -237,7 +262,13 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>((
|
|
|
237
262
|
[css.varBorderTransparency]: `${borderTransparency}%`,
|
|
238
263
|
[css.varOpacity]: opacity.toFixed(2)
|
|
239
264
|
}),
|
|
240
|
-
|
|
265
|
+
...style.border === 'none'
|
|
266
|
+
? {
|
|
267
|
+
borderColor: 'transparent'
|
|
268
|
+
}
|
|
269
|
+
: {
|
|
270
|
+
borderStyle: style.border ?? 'dashed'
|
|
271
|
+
}
|
|
241
272
|
})
|
|
242
273
|
}}
|
|
243
274
|
>
|
|
@@ -255,7 +286,7 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>((
|
|
|
255
286
|
className={css.title}>
|
|
256
287
|
{element.title}
|
|
257
288
|
</Text>
|
|
258
|
-
{enableElementDetails && (
|
|
289
|
+
{enableElementDetails && !!modelRef && (
|
|
259
290
|
<Tooltip
|
|
260
291
|
fz="xs"
|
|
261
292
|
color="dark"
|
|
@@ -264,6 +295,7 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>((
|
|
|
264
295
|
offset={2}
|
|
265
296
|
openDelay={600}>
|
|
266
297
|
<ActionIcon
|
|
298
|
+
key={`${id}details`}
|
|
267
299
|
component={m.div}
|
|
268
300
|
variants={VariantsDetailsBtn}
|
|
269
301
|
data-animate-target="details"
|
|
@@ -283,7 +315,7 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>((
|
|
|
283
315
|
</Box>
|
|
284
316
|
{isNavigable && (
|
|
285
317
|
<ActionIcon
|
|
286
|
-
key={
|
|
318
|
+
key={`${id}navigate`}
|
|
287
319
|
component={m.div}
|
|
288
320
|
variants={VariantsNavigate}
|
|
289
321
|
data-animate-target="navigate"
|