@likec4/diagram 1.4.0 → 1.5.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 (83) hide show
  1. package/dist/LikeC4Diagram.css.d.ts +0 -1
  2. package/dist/LikeC4Diagram.props.d.ts +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.mjs +1398 -1114
  5. package/dist/state/DiagramContext.d.ts +86 -4159
  6. package/dist/state/diagramStore.d.ts +88 -4162
  7. package/dist/state/hooks.d.ts +4 -0
  8. package/dist/state/index.d.ts +1 -2
  9. package/dist/style.css +182 -156
  10. package/dist/ui/options/EdgeOptions.d.ts +19 -0
  11. package/dist/ui/options/NodeOptions.d.ts +2 -2
  12. package/dist/xyflow/EdgeMarkers.d.ts +11 -0
  13. package/dist/xyflow/XYFlowEvents.d.ts +8 -5
  14. package/dist/xyflow/const.d.ts +3 -3
  15. package/dist/xyflow/diagram-to-xyflow.d.ts +1 -1
  16. package/dist/xyflow/edges/RelationshipEdge.d.ts +3 -2
  17. package/dist/xyflow/edges/edges.css.d.ts +1 -0
  18. package/dist/xyflow/edges/utils.d.ts +1 -0
  19. package/dist/xyflow/hooks/index.d.ts +3 -2
  20. package/dist/xyflow/hooks/useXYFlow.d.ts +13 -12
  21. package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +1 -0
  22. package/dist/xyflow/nodes/element/ElementIcon.d.ts +1 -4
  23. package/dist/xyflow/nodes/element/element.css.d.ts +2 -1
  24. package/dist/xyflow/types.d.ts +2 -32
  25. package/package.json +19 -19
  26. package/src/LikeC4Diagram.css.ts +0 -8
  27. package/src/LikeC4Diagram.props.ts +2 -2
  28. package/src/LikeC4Diagram.tsx +14 -20
  29. package/src/globals.css.ts +10 -3
  30. package/src/index.ts +1 -1
  31. package/src/mantine.css.ts +2 -2
  32. package/src/state/DiagramContext.tsx +44 -13
  33. package/src/state/diagramStore.ts +64 -52
  34. package/src/state/hooks.ts +5 -0
  35. package/src/state/index.ts +1 -2
  36. package/src/ui/BackwardForwardPanel.css.ts +9 -9
  37. package/src/ui/BackwardForwardPanel.tsx +1 -1
  38. package/src/ui/DiagramTitlePanel.css.ts +7 -2
  39. package/src/ui/DiagramTitlePanel.tsx +5 -3
  40. package/src/ui/DynamicViewWalkthrough.tsx +6 -4
  41. package/src/ui/OptionsPanel.tsx +37 -27
  42. package/src/ui/options/EdgeOptions.tsx +157 -0
  43. package/src/ui/options/NodeOptions.tsx +37 -29
  44. package/src/xyflow/EdgeMarkers.tsx +148 -0
  45. package/src/xyflow/FitviewOnDiagramChange.tsx +8 -4
  46. package/src/xyflow/SelectEdgesOnNodeFocus.tsx +59 -55
  47. package/src/xyflow/SyncWithDiagram.tsx +13 -20
  48. package/src/xyflow/XYFlow.tsx +2 -4
  49. package/src/xyflow/XYFlowEvents.tsx +48 -33
  50. package/src/xyflow/XYFlowInner.tsx +1 -1
  51. package/src/xyflow/const.ts +3 -3
  52. package/src/xyflow/diagram-to-xyflow.ts +17 -41
  53. package/src/xyflow/edges/RelationshipEdge.tsx +207 -118
  54. package/src/xyflow/edges/edges.css.ts +36 -22
  55. package/src/xyflow/edges/utils.ts +10 -0
  56. package/src/xyflow/hooks/index.ts +4 -2
  57. package/src/xyflow/hooks/useLayoutConstraints.ts +3 -4
  58. package/src/xyflow/hooks/useXYFlow.ts +28 -1
  59. package/src/xyflow/nodes/compound/CompoundNode.css.ts +34 -24
  60. package/src/xyflow/nodes/compound/CompoundNode.tsx +52 -53
  61. package/src/xyflow/nodes/element/ElementIcon.tsx +11 -22
  62. package/src/xyflow/nodes/element/ElementLink.tsx +11 -16
  63. package/src/xyflow/nodes/element/ElementNode.tsx +64 -108
  64. package/src/xyflow/nodes/element/element.css.ts +30 -10
  65. package/src/xyflow/nodes/shared/NavigateToBtn.tsx +1 -1
  66. package/src/xyflow/types.ts +2 -4
  67. package/src/xyflow/utils.ts +3 -6
  68. package/dist/KeepAspectRatioContainer.d.ts +0 -9
  69. package/dist/icons/Clipboard.d.ts +0 -3
  70. package/dist/icons/Link.d.ts +0 -3
  71. package/dist/icons/ZoomIn.d.ts +0 -3
  72. package/dist/icons/index.d.ts +0 -3
  73. package/dist/mantine/theme.d.ts +0 -3
  74. package/dist/state/WhenInitialized.d.ts +0 -3
  75. package/dist/ui/Camera.d.ts +0 -3
  76. package/src/KeepAspectRatioContainer.tsx +0 -36
  77. package/src/icons/Clipboard.tsx +0 -24
  78. package/src/icons/Link.tsx +0 -23
  79. package/src/icons/ZoomIn.tsx +0 -25
  80. package/src/icons/index.ts +0 -3
  81. package/src/mantine/theme.ts +0 -20
  82. package/src/state/WhenInitialized.tsx +0 -24
  83. package/src/ui/Camera.tsx +0 -174
@@ -12,6 +12,12 @@ export const container = style({
12
12
  margin: 0
13
13
  })
14
14
 
15
+ export const nodeHandlerInCenter = style({
16
+ top: '50%',
17
+ left: '50%',
18
+ visibility: 'hidden'
19
+ })
20
+
15
21
  export const dimmed = style({})
16
22
 
17
23
  globalStyle(`.react-flow__node-compound:has(${dimmed})`, {
@@ -37,8 +43,12 @@ export const compoundBody = style({
37
43
  position: 'relative',
38
44
  borderRadius: 6,
39
45
  boxShadow: '0 4px 10px 0.5px rgba(0,0,0,0.1) , 0 2px 2px -1px rgba(0,0,0,0.4)',
40
- padding: 8,
46
+ padding: 0,
47
+ margin: 0,
41
48
  transition: 'all 200ms ease-out',
49
+ backgroundClip: 'padding-box',
50
+ overflow: 'hidden',
51
+ cursor: 'default',
42
52
  selectors: {
43
53
  [`:where(.react-flow__node.selected) &`]: {
44
54
  boxShadow: 'none'
@@ -56,11 +66,9 @@ export const compoundBody = style({
56
66
  left: 0,
57
67
  width: '100%',
58
68
  height: '100%',
59
- borderRadius: 6,
60
69
  pointerEvents: 'none',
61
70
  transition: 'background 175ms ease-out, opacity 175ms ease-out',
62
- background: vars.element.fill,
63
- backgroundClip: 'padding-box'
71
+ background: vars.element.fill
64
72
  }
65
73
  })
66
74
 
@@ -68,16 +76,15 @@ const opacityDeltaOnHover = createVar('opacityDeltaOnHover')
68
76
  export const transparent = style({
69
77
  borderStyle: 'dashed',
70
78
  borderWidth: 3,
71
- padding: 6,
72
79
  boxShadow: 'none',
73
80
  borderColor: `color-mix(in srgb , ${vars.element.stroke}, transparent ${fallbackVar(varBorderTransparency, '10%')})`,
74
- backgroundClip: 'padding-box',
75
81
  vars: {
76
82
  [opacityDeltaOnHover]: '0',
77
83
  '--ai-bg': `color-mix(in srgb , ${vars.element.fill}, transparent 99%)`
78
84
  },
79
85
  ':before': {
80
- transitionDelay: '200ms',
86
+ borderRadius: 'unset',
87
+ transitionDelay: '100ms',
81
88
  opacity: calc.add(fallbackVar(varOpacity, '1'), opacityDeltaOnHover)
82
89
  },
83
90
  selectors: {
@@ -88,7 +95,7 @@ export const transparent = style({
88
95
  // },
89
96
  [`:where([data-hovered]) &`]: {
90
97
  vars: {
91
- [opacityDeltaOnHover]: '.07'
98
+ [opacityDeltaOnHover]: '.08'
92
99
  }
93
100
  }
94
101
  }
@@ -96,21 +103,28 @@ export const transparent = style({
96
103
 
97
104
  export const title = style({
98
105
  fontFamily: vars.compound.font,
99
- fontOpticalSizing: 'auto',
100
- fontStyle: 'normal',
101
106
  textAlign: 'left',
102
- display: 'inline-block',
103
107
  fontWeight: 600,
104
- fontSize: '14px',
108
+ fontSize: rem(15),
105
109
  textTransform: 'uppercase',
106
110
  letterSpacing: '0.2px',
107
111
  lineHeight: 1,
108
- opacity: 0.75,
109
112
  color: `var(--_compound-title-color,${vars.compound.titleColor})`,
110
- paddingLeft: 12
113
+ paddingLeft: 14,
114
+ paddingTop: 13,
115
+ paddingBottom: 6,
116
+ mixBlendMode: 'screen',
117
+ selectors: {
118
+ [`:where(.react-flow__node.draggable) &`]: {
119
+ cursor: 'grab'
120
+ },
121
+ [`:where(.likec4-compound-transparent) &`]: {
122
+ paddingTop: 10
123
+ }
124
+ }
111
125
  })
112
126
  export const titleWithNavigation = style({
113
- paddingLeft: 26
127
+ paddingLeft: 32
114
128
  })
115
129
 
116
130
  globalStyle(`:where([data-mantine-color-scheme='light'] .likec4-compound-transparent)`, {
@@ -119,10 +133,6 @@ globalStyle(`:where([data-mantine-color-scheme='light'] .likec4-compound-transpa
119
133
  }
120
134
  })
121
135
 
122
- globalStyle(`:where([data-mantine-color-scheme='light'] .likec4-compound-transparent) ${title}`, {
123
- opacity: 1
124
- })
125
-
126
136
  const indicatorKeyframes = keyframes({
127
137
  'from': {
128
138
  opacity: 0.6
@@ -197,10 +207,10 @@ export const navigateBtn = style({
197
207
  position: 'absolute',
198
208
  pointerEvents: 'all',
199
209
  left: 3,
200
- top: 7,
210
+ top: 6,
201
211
  cursor: 'pointer',
202
212
  color: `var(--_compound-title-color,${navigateBtnColor})`,
203
- transformOrigin: '90% 70%',
213
+ transformOrigin: '90% 50%',
204
214
  opacity: 0.75,
205
215
  transition: 'all 150ms ease-out',
206
216
  transitionDelay: '0ms',
@@ -225,7 +235,7 @@ export const navigateBtn = style({
225
235
  [`:where([data-mantine-color-scheme='light'] .likec4-compound-transparent) &`]: {
226
236
  opacity: 0.85,
227
237
  vars: {
228
- '--ai-bg-hover': `color-mix(in srgb , ${vars.element.fill}, transparent 50%)`,
238
+ '--ai-bg-hover': `color-mix(in srgb , ${vars.element.fill}, transparent 60%)`,
229
239
  '--ai-hover': `color-mix(in srgb , ${vars.element.fill}, transparent 20%)`
230
240
  }
231
241
  },
@@ -241,8 +251,8 @@ export const navigateBtn = style({
241
251
  }
242
252
  })
243
253
  globalStyle(`${navigateBtn} svg.icon`, {
244
- width: '70%',
245
- height: '70%',
254
+ width: '75%',
255
+ height: '75%',
246
256
  strokeWidth: 1.5
247
257
  })
248
258
 
@@ -2,12 +2,10 @@ import { Box, Text } from '@mantine/core'
2
2
  import { assignInlineVars } from '@vanilla-extract/dynamic'
3
3
  import { Handle, type NodeProps, Position } from '@xyflow/react'
4
4
  import clsx from 'clsx'
5
- import { DEV } from 'esm-env'
6
5
  import { deepEqual as eq } from 'fast-equals'
7
6
  import { memo } from 'react'
8
7
  import { clamp } from 'remeda'
9
- import useTilg from 'tilg'
10
- import { useDiagramState } from '../../../state'
8
+ import { useDiagramState } from '../../../state/hooks'
11
9
  import type { CompoundXYFlowNode } from '../../types'
12
10
  import { NavigateToBtn } from '../shared/NavigateToBtn'
13
11
  import * as css from './CompoundNode.css'
@@ -31,7 +29,6 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>(function
31
29
  element
32
30
  }
33
31
  }) {
34
- DEV && useTilg()
35
32
  const { color, style, depth = 1, ...compound } = element
36
33
  // const w = toDomPrecision(width ?? compound.width)
37
34
  // const h = toDomPrecision(height ?? compound.height)
@@ -52,65 +49,67 @@ export const CompoundNodeMemo = /* @__PURE__ */ memo<CompoundNodeProps>(function
52
49
  const isnavigable = !!compound.navigateTo && hasOnNavigateTo
53
50
 
54
51
  return (
55
- <Box
56
- className={clsx(
57
- css.container,
58
- 'likec4-compound-node',
59
- opacity < 1 && 'likec4-compound-transparent',
60
- isDimmed && css.dimmed
61
- )}
62
- mod={{
63
- 'compound-depth': depth,
64
- 'likec4-color': color,
65
- hovered: isHovered
66
- }}
67
- >
52
+ <>
68
53
  <Handle
69
54
  type="target"
70
55
  position={Position.Top}
71
- style={{ visibility: 'hidden' }}
56
+ className={css.nodeHandlerInCenter}
72
57
  />
73
- <svg className={css.indicator}>
74
- <rect
75
- x={0}
76
- y={0}
77
- width={'100%'}
78
- height={'100%'}
79
- rx={6}
80
- />
81
- </svg>
82
- <div
58
+ <Box
83
59
  className={clsx(
84
- css.compoundBody,
85
- opacity < 1 && css.transparent,
86
- 'likec4-compound'
60
+ css.container,
61
+ 'likec4-compound-node',
62
+ opacity < 1 && 'likec4-compound-transparent',
63
+ isDimmed && css.dimmed
87
64
  )}
88
- style={opacity < 1
89
- ? {
90
- ...assignInlineVars({
91
- [css.varBorderTransparency]: `${borderTransparency}%`,
92
- [css.varOpacity]: opacity.toFixed(2)
93
- }),
94
- borderStyle: style.border ?? 'dashed'
95
- }
96
- : undefined}
65
+ mod={{
66
+ 'compound-depth': depth,
67
+ 'likec4-color': color,
68
+ hovered: isHovered
69
+ }}
97
70
  >
98
- <Text
99
- component="div"
71
+ <svg className={css.indicator}>
72
+ <rect
73
+ x={0}
74
+ y={0}
75
+ width={'100%'}
76
+ height={'100%'}
77
+ rx={6}
78
+ />
79
+ </svg>
80
+ <div
100
81
  className={clsx(
101
- css.title,
102
- isnavigable && css.titleWithNavigation,
103
- 'likec4-compound-title'
104
- )}>
105
- {compound.title}
106
- </Text>
107
- </div>
108
- {isnavigable && <NavigateToBtn xynodeId={id} className={css.navigateBtn} />}
82
+ css.compoundBody,
83
+ opacity < 1 && css.transparent,
84
+ 'likec4-compound'
85
+ )}
86
+ style={opacity < 1
87
+ ? {
88
+ ...assignInlineVars({
89
+ [css.varBorderTransparency]: `${borderTransparency}%`,
90
+ [css.varOpacity]: opacity.toFixed(2)
91
+ }),
92
+ borderStyle: style.border ?? 'dashed'
93
+ }
94
+ : undefined}
95
+ >
96
+ <Text
97
+ component="div"
98
+ className={clsx(
99
+ css.title,
100
+ isnavigable && css.titleWithNavigation,
101
+ 'likec4-compound-title'
102
+ )}>
103
+ {compound.title}
104
+ </Text>
105
+ </div>
106
+ {isnavigable && <NavigateToBtn xynodeId={id} className={css.navigateBtn} />}
107
+ </Box>
109
108
  <Handle
110
109
  type="source"
111
- position={Position.Bottom}
112
- style={{ visibility: 'hidden' }}
110
+ position={Position.Top}
111
+ className={css.nodeHandlerInCenter}
113
112
  />
114
- </Box>
113
+ </>
115
114
  )
116
115
  }, isEqualProps)
@@ -1,43 +1,32 @@
1
1
  import { assignInlineVars } from '@vanilla-extract/dynamic'
2
2
  import clsx from 'clsx'
3
3
  import type { XYFlowNode } from '../../types'
4
- import { elementIcon, iconMaxH } from './element.css'
4
+ import { elementIcon, iconOffsetY } from './element.css'
5
5
 
6
6
  type ElementIconProps = {
7
7
  node: XYFlowNode['data']['element']
8
- maxWidth?: number | undefined
9
- paddingX?: number | undefined
10
- paddingY?: number | undefined
11
8
  }
12
9
 
13
10
  export function ElementIcon({
14
- node,
15
- paddingY = 32
16
- }: ElementIconProps) {
17
- if (!node.icon) {
18
- return null
11
+ node: {
12
+ icon,
13
+ title,
14
+ labelBBox
19
15
  }
20
- const firstLabel = node.labels[0]
21
- if (!firstLabel) {
16
+ }: ElementIconProps) {
17
+ if (!icon) {
22
18
  return null
23
19
  }
24
20
 
25
- const firstLabelY = Math.floor(firstLabel.pt[1] - firstLabel.fontSize * 1.25)
26
- const maxIconHeight = Math.floor(firstLabelY - paddingY - 16)
27
- // const maxIconWidth = maxWidth ?? node.width - paddingX * 2
28
-
29
- // const centerY = paddingY + Math.floor(maxIconHeight / 2)
30
- // const centerX = Math.floor(node.width / 2)
31
-
32
21
  return (
33
22
  <div
34
23
  className={clsx(elementIcon, 'likec4-element-icon')}
35
- style={assignInlineVars({ iconMaxH }, {
36
- iconMaxH: maxIconHeight + 'px'
24
+ style={assignInlineVars({ iconOffsetY }, {
25
+ iconOffsetY: labelBBox.y + 'px'
37
26
  })}>
38
27
  <img
39
- src={node.icon!}
40
- alt={node.title}
28
+ src={icon}
29
+ alt={title}
41
30
  />
42
31
  </div>
43
32
  )
@@ -7,14 +7,16 @@ import {
7
7
  Group,
8
8
  HoverCard,
9
9
  HoverCardDropdown,
10
+ type HoverCardProps,
10
11
  HoverCardTarget,
11
12
  Stack,
12
13
  UnstyledButton
13
14
  } from '@mantine/core'
15
+ import { IconLink } from '@tabler/icons-react'
14
16
  import clsx from 'clsx'
15
17
  import { useId } from 'react'
16
18
  import { clamp } from 'remeda'
17
- import { Link } from '../../../icons'
19
+ import { type DiagramState, useDiagramState } from '../../../state/hooks'
18
20
  import type { XYFlowNode } from '../../types'
19
21
  import { elementLink, trigger } from './ElementLink.css'
20
22
 
@@ -22,23 +24,17 @@ type ElementLinkProps = {
22
24
  element: XYFlowNode['data']['element']
23
25
  }
24
26
 
27
+ const selector = (s: DiagramState) => {
28
+ const target = s.getContainer()
29
+ return target ? { target } : null
30
+ }
31
+
25
32
  export function ElementLink({
26
33
  element
27
34
  }: ElementLinkProps) {
28
35
  invariant(element.links, 'ElementLink: links are required')
29
36
  const id = useId()
30
- // const mantineCtx = useMantineContext()
31
- // const root = mantineCtx.getRootElement()
32
-
33
- // const targetSelector = `.react-flow:has([data-likec4-linkid="${id}"])`
34
- // // const target = root?.querySelector<HTMLDivElement>(targetSelector) ?? targetSelector
35
-
36
- // const portalProps = useMemo(() => ({
37
- // get target(): HTMLElement | string {
38
- // const root = mantineCtx.getRootElement()
39
- // return root?.querySelector<HTMLDivElement>(targetSelector) ?? targetSelector
40
- // }
41
- // }), [targetSelector])
37
+ const portalProps = useDiagramState(selector)
42
38
  return (
43
39
  <div className={elementLink} data-likec4-linkid={id}>
44
40
  <HoverCard
@@ -51,8 +47,7 @@ export function ElementLink({
51
47
  transitionProps={{
52
48
  transition: 'pop'
53
49
  }}
54
- // portalProps={portalProps}
55
- withinPortal={false}
50
+ {...(portalProps ? { portalProps } : { withinPortal: false })}
56
51
  floatingStrategy={'fixed'}
57
52
  openDelay={350}
58
53
  closeDelay={800}
@@ -64,7 +59,7 @@ export function ElementLink({
64
59
  <UnstyledButton
65
60
  className={clsx('nodrag nopan', trigger)}
66
61
  autoFocus={false}>
67
- <Link />
62
+ <IconLink size={12} />
68
63
  <span>links</span>
69
64
  </UnstyledButton>
70
65
  </HoverCardTarget>
@@ -1,13 +1,11 @@
1
1
  import { Text } from '@mantine/core'
2
2
  import { Handle, type NodeProps, Position } from '@xyflow/react'
3
3
  import clsx from 'clsx'
4
- import { DEV } from 'esm-env'
5
4
  import { deepEqual as eq } from 'fast-equals'
6
5
  import { m, type Variants } from 'framer-motion'
7
6
  import { memo } from 'react'
8
7
  import { isNumber } from 'remeda'
9
- import useTilg from 'tilg'
10
- import { useDiagramState } from '../../../state'
8
+ import { useDiagramState } from '../../../state/hooks'
11
9
  import type { ElementXYFlowNode } from '../../types'
12
10
  import { toDomPrecision } from '../../utils'
13
11
  import { NavigateToBtn } from '../shared/NavigateToBtn'
@@ -69,6 +67,7 @@ const isEqualProps = (prev: ElementNodeProps, next: ElementNodeProps) => (
69
67
  prev.id === next.id
70
68
  && eq(prev.selected ?? false, next.selected ?? false)
71
69
  && eq(prev.dragging ?? false, next.dragging ?? false)
70
+ && eq(prev.draggable ?? false, next.draggable ?? false)
72
71
  && eq(prev.width ?? 0, next.width ?? 0)
73
72
  && eq(prev.height ?? 0, next.height ?? 0)
74
73
  && eq(prev.data.element, next.data.element)
@@ -80,11 +79,11 @@ export const ElementNodeMemo = memo<ElementNodeProps>(function ElementNode({
80
79
  element
81
80
  },
82
81
  dragging,
82
+ // draggable = false,
83
83
  selected = false,
84
84
  width,
85
85
  height
86
86
  }) {
87
- DEV && useTilg()
88
87
  const { isHovered, isDimmed, hasOnNavigateTo, isHovercards, isInteractive } = useDiagramState(s => ({
89
88
  isHovered: s.hoveredNodeId === id,
90
89
  isDimmed: s.dimmed.has(id),
@@ -120,124 +119,81 @@ export const ElementNodeMemo = memo<ElementNodeProps>(function ElementNode({
120
119
  // useTilg(animate, isHovered, isInteractive)
121
120
 
122
121
  return (
123
- <m.div
124
- id={id}
125
- className={clsx([
126
- css.container,
127
- isDimmed && css.dimmed,
128
- animate !== 'idle' && css.containerAnimated,
129
- 'likec4-element-node'
130
- ])}
131
- data-hovered={!dragging && isHovered}
132
- data-likec4-color={element.color}
133
- data-likec4-shape={element.shape}
134
- variants={variants}
135
- initial={false}
136
- animate={animate}
137
- {...(isInteractive && {
138
- whileTap: dragging ? animate : 'tap'
139
- })}
140
- >
141
- {
142
- /* <NodeToolbar
143
- position={Position.Bottom}
144
- align={'start'}
145
- offset={-10}
146
- isVisible={selected || isHovered}>
147
- <Button>editggg</Button>
148
- </NodeToolbar> */
149
- }
150
- {
151
- /* <NodeResizer minWidth={100} minHeight={30} />
152
- <NodeToolbar
153
- position={Position.Right}
154
- align={'start'}
155
- style={{
156
- background: 'blue'
157
- }}>
158
- <Stack>
159
- <Button>edit</Button>
160
-
161
- </Stack>
162
- </NodeToolbar>*/
163
- }
164
- {
165
- /* {element.inEdges.map((edge) => (
166
- <Handle
167
- key={edge}
168
- id={edge}
169
- type="target"
170
- position={Position.Top}
171
- style={{ visibility: 'hidden' }}
172
- />
173
- ))} */
174
- }
122
+ <>
175
123
  <Handle
176
124
  type="target"
177
125
  position={Position.Top}
178
- style={{ visibility: 'hidden' }}
126
+ className={css.handleCenter}
179
127
  />
180
- <svg
181
- className={clsx(
182
- css.cssShapeSvg
183
- )}
184
- viewBox={`0 0 ${w} ${h}`}
185
- width={w}
186
- height={h}
128
+ <m.div
129
+ id={id}
130
+ className={clsx([
131
+ css.container,
132
+ isDimmed && css.dimmed,
133
+ animate !== 'idle' && css.containerAnimated,
134
+ 'likec4-element-node'
135
+ ])}
136
+ data-hovered={!dragging && isHovered}
137
+ data-likec4-color={element.color}
138
+ data-likec4-shape={element.shape}
139
+ variants={variants}
140
+ initial={false}
141
+ animate={animate}
142
+ {...(isInteractive && {
143
+ whileTap: dragging ? animate : 'tap'
144
+ })}
187
145
  >
188
- <g className={css.indicator}>
189
- <SelectedIndicator
146
+ <svg
147
+ className={clsx(
148
+ css.cssShapeSvg
149
+ )}
150
+ viewBox={`0 0 ${w} ${h}`}
151
+ width={w}
152
+ height={h}
153
+ >
154
+ <g className={css.indicator}>
155
+ <SelectedIndicator
156
+ shape={element.shape}
157
+ w={w}
158
+ h={h}
159
+ />
160
+ </g>
161
+ <ElementShapeSvg
190
162
  shape={element.shape}
191
163
  w={w}
192
164
  h={h}
193
165
  />
194
- </g>
195
- <ElementShapeSvg
196
- shape={element.shape}
197
- w={w}
198
- h={h}
199
- />
200
- </svg>
201
- <div className={clsx(css.element, 'likec4-element')}>
202
- {element.icon && <ElementIcon node={element} />}
203
- <Text
204
- component="div"
205
- className={clsx(css.title, 'likec4-element-title')}>
206
- {element.title}
207
- </Text>
208
- {element.technology && (
166
+ </svg>
167
+ <div className={clsx(css.element, 'likec4-element')}>
168
+ <ElementIcon node={element} />
209
169
  <Text
210
170
  component="div"
211
- className={clsx(css.technology, 'likec4-element-technology')}>
212
- {element.technology}
171
+ className={clsx(css.title, 'likec4-element-title')}>
172
+ {element.title}
213
173
  </Text>
214
- )}
215
- {element.description && (
216
- <Text
217
- component="div"
218
- className={clsx(css.description, 'likec4-element-description')}>
219
- {element.description}
220
- </Text>
221
- )}
222
- </div>
174
+ {element.technology && (
175
+ <Text
176
+ component="div"
177
+ className={clsx(css.technology, 'likec4-element-technology')}>
178
+ {element.technology}
179
+ </Text>
180
+ )}
181
+ {element.description && (
182
+ <Text
183
+ component="div"
184
+ className={clsx(css.description, 'likec4-element-description')}>
185
+ {element.description}
186
+ </Text>
187
+ )}
188
+ </div>
189
+ {isHovercards && element.links && <ElementLink element={element} />}
190
+ {isNavigable && <NavigateToBtn xynodeId={id} className={css.cssNavigateBtn} />}
191
+ </m.div>
223
192
  <Handle
224
193
  type="source"
225
- position={Position.Bottom}
226
- style={{ visibility: 'hidden' }}
194
+ position={Position.Top}
195
+ className={css.handleCenter}
227
196
  />
228
- {
229
- /* {element.outEdges.map((edge) => (
230
- <Handle
231
- key={edge}
232
- id={edge}
233
- type="source"
234
- position={Position.Bottom}
235
- style={{ visibility: 'hidden' }}
236
- />
237
- ))} */
238
- }
239
- {isHovercards && element.links && <ElementLink element={element} />}
240
- {isNavigable && <NavigateToBtn xynodeId={id} className={css.cssNavigateBtn} />}
241
- </m.div>
197
+ </>
242
198
  )
243
199
  }, isEqualProps)