@likec4/diagram 1.36.1 → 1.38.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 (173) hide show
  1. package/bundle/{chunk-DHvr-RGh.js → chunk-BZV0K82k.js} +870 -900
  2. package/bundle/custom.js +64 -56
  3. package/bundle/index.js +3565 -3327
  4. package/dist/LikeC4Diagram.props.d.ts +5 -5
  5. package/dist/LikeC4Styles.js +17 -15
  6. package/dist/StaticLikeC4Diagram.d.ts +1 -1
  7. package/dist/StaticLikeC4Diagram.js +3 -0
  8. package/dist/base/BaseXYFlow.d.ts +1 -1
  9. package/dist/base/BaseXYFlow.js +25 -27
  10. package/dist/base/const.d.ts +4 -4
  11. package/dist/base/const.js +5 -4
  12. package/dist/base/primitives/MarkdownBlock.js +4 -1
  13. package/dist/base/primitives/compound/CompoundActionButton.js +27 -42
  14. package/dist/base/primitives/compound/CompoundDetailsButton.js +23 -48
  15. package/dist/base/primitives/compound/CompoundNodeContainer.js +16 -48
  16. package/dist/base/primitives/compound/CompoundTitle.js +5 -80
  17. package/dist/base/primitives/compound/actionbtns.css.js +1 -13
  18. package/dist/base/primitives/customEdge.d.ts +1 -1
  19. package/dist/base/primitives/customNode.d.ts +4 -4
  20. package/dist/base/primitives/customNode.js +7 -7
  21. package/dist/base/primitives/edge/EdgeLabel.d.ts +5 -4
  22. package/dist/base/primitives/edge/EdgeLabel.js +39 -21
  23. package/dist/base/primitives/edge/EdgeLabelContainer.js +11 -23
  24. package/dist/base/primitives/edge/edge.css.js +19 -11
  25. package/dist/base/primitives/element/ElementShape.js +38 -18
  26. package/dist/base/primitives/element/ElementTags.js +7 -4
  27. package/dist/base/primitives/element/ElementTitle.js +10 -2
  28. package/dist/base/types.d.ts +17 -21
  29. package/dist/bundle/LikeC4View.d.ts +2 -2
  30. package/dist/bundle/LikeC4View.js +4 -1
  31. package/dist/bundle/LikeC4View.props.d.ts +2 -2
  32. package/dist/bundle/ReactLikeC4.d.ts +3 -3
  33. package/dist/bundle/custom.js +2 -1
  34. package/dist/bundle/index.js +2 -1
  35. package/dist/components/Link.js +3 -2
  36. package/dist/context/ReduceGraphics.js +2 -5
  37. package/dist/context/RootContainer.js +1 -5
  38. package/dist/custom/customNodes.d.ts +32 -26
  39. package/dist/custom/customNodes.js +12 -8
  40. package/dist/custom/hooks.d.ts +2 -1
  41. package/dist/custom/index.js +2 -1
  42. package/dist/globals.css.js +1 -1
  43. package/dist/hooks/index.d.ts +1 -1
  44. package/dist/hooks/useDiagram.d.ts +18 -1
  45. package/dist/hooks/useDiagram.js +18 -2
  46. package/dist/hooks/useXYFlow.d.ts +40 -21
  47. package/dist/index.d.ts +1 -1
  48. package/dist/index.js +2 -1
  49. package/dist/likec4diagram/DiagramUI.js +5 -2
  50. package/dist/likec4diagram/DiagramXYFlow.js +9 -9
  51. package/dist/likec4diagram/custom/edges/RelationshipEdge.d.ts +3 -3
  52. package/dist/likec4diagram/custom/edges/RelationshipEdge.js +27 -44
  53. package/dist/likec4diagram/custom/index.js +3 -3
  54. package/dist/likec4diagram/custom/nodes/nodes.d.ts +8 -6
  55. package/dist/likec4diagram/custom/nodes/nodes.js +13 -14
  56. package/dist/likec4diagram/custom/nodes/toolbar/CompoundToolbar.js +3 -2
  57. package/dist/likec4diagram/custom/nodes/toolbar/_shared.d.ts +2 -2
  58. package/dist/likec4diagram/relationship-popover/RelationshipPopover.d.ts +2 -0
  59. package/dist/likec4diagram/relationship-popover/RelationshipPopover.js +441 -0
  60. package/dist/likec4diagram/relationship-popover/actor.d.ts +177 -0
  61. package/dist/likec4diagram/relationship-popover/actor.js +155 -0
  62. package/dist/likec4diagram/relationship-popover/styles.css.d.ts +2 -0
  63. package/dist/likec4diagram/{custom/edges/RelationshipsDropdownMenu.css.js → relationship-popover/styles.css.js} +4 -17
  64. package/dist/likec4diagram/useLayoutConstraints.js +0 -1
  65. package/dist/likec4model/useLikeC4ElementsTree.js +1 -1
  66. package/dist/likec4model/useLikeC4Project.js +15 -1
  67. package/dist/navigationpanel/NavigationPanelDropdown.js +1 -2
  68. package/dist/navigationpanel/actor.js +1 -2
  69. package/dist/navigationpanel/controls/NavigationButtons.js +1 -5
  70. package/dist/navigationpanel/controls/ViewDetailsCard.js +2 -0
  71. package/dist/overlays/element-details/actor.d.ts +564 -8
  72. package/dist/overlays/overlay/Overlay.css.d.ts +1 -1
  73. package/dist/overlays/relationship-details/actor.d.ts +3 -1
  74. package/dist/overlays/relationship-details/hooks.d.ts +19 -1
  75. package/dist/overlays/relationship-details/layout-to-xyflow.js +0 -1
  76. package/dist/overlays/relationship-details/layout.js +1 -2
  77. package/dist/overlays/relationships-browser/actor.d.ts +26 -2
  78. package/dist/overlays/relationships-browser/custom/nodeTypes.d.ts +16 -0
  79. package/dist/overlays/relationships-browser/custom/nodeTypes.js +18 -8
  80. package/dist/overlays/relationships-browser/useViewToNodesEdges.js +0 -1
  81. package/dist/search/components/_shared.css.d.ts +1 -1
  82. package/dist/state/DiagramActorProvider.js +2 -19
  83. package/dist/state/assign.js +24 -10
  84. package/dist/state/diagram-machine.d.ts +149 -474
  85. package/dist/state/diagram-machine.js +94 -54
  86. package/dist/state/types.d.ts +1 -1
  87. package/dist/styles-min.css +1 -1
  88. package/dist/styles-xyflow.css +1 -1
  89. package/dist/styles.css +1 -1
  90. package/dist/styles.css2.js +1 -1
  91. package/dist/utils/index.d.ts +2 -1
  92. package/dist/utils/roundDpr.d.ts +1 -0
  93. package/dist/utils/roundDpr.js +20 -0
  94. package/dist/utils/xyflow.d.ts +0 -1
  95. package/dist/utils/xyflow.js +1 -7
  96. package/package.json +16 -15
  97. package/panda.buildinfo.json +91 -156
  98. package/src/LikeC4Diagram.props.ts +5 -5
  99. package/src/LikeC4Styles.tsx +22 -14
  100. package/src/StaticLikeC4Diagram.tsx +3 -0
  101. package/src/base/BaseXYFlow.tsx +26 -29
  102. package/src/base/const.ts +5 -4
  103. package/src/base/primitives/MarkdownBlock.tsx +6 -1
  104. package/src/base/primitives/compound/CompoundActionButton.tsx +31 -43
  105. package/src/base/primitives/compound/CompoundDetailsButton.tsx +26 -48
  106. package/src/base/primitives/compound/CompoundNodeContainer.tsx +15 -43
  107. package/src/base/primitives/compound/CompoundTitle.tsx +4 -76
  108. package/src/base/primitives/compound/actionbtns.css.ts +0 -12
  109. package/src/base/primitives/customEdge.ts +1 -1
  110. package/src/base/primitives/customNode.tsx +20 -24
  111. package/src/base/primitives/edge/EdgeLabel.tsx +23 -8
  112. package/src/base/primitives/edge/EdgeLabelContainer.tsx +9 -21
  113. package/src/base/primitives/edge/edge.css.ts +19 -11
  114. package/src/base/primitives/element/ElementShape.tsx +40 -18
  115. package/src/base/primitives/element/ElementTags.tsx +7 -4
  116. package/src/base/primitives/element/ElementTitle.tsx +23 -11
  117. package/src/base/types.ts +21 -25
  118. package/src/bundle/LikeC4View.props.ts +2 -2
  119. package/src/bundle/LikeC4View.tsx +8 -5
  120. package/src/bundle/ReactLikeC4.tsx +3 -3
  121. package/src/components/Link.tsx +3 -2
  122. package/src/context/RootContainer.tsx +1 -5
  123. package/src/context/TagStylesContext.tsx +2 -0
  124. package/src/custom/{customNodes.tsx → customNodes.ts} +58 -52
  125. package/src/custom/hooks.ts +7 -0
  126. package/src/globals.css +58 -5
  127. package/src/hooks/index.ts +1 -1
  128. package/src/hooks/useDiagram.ts +39 -5
  129. package/src/hooks/useXYFlow.ts +3 -1
  130. package/src/index.ts +1 -0
  131. package/src/likec4diagram/DiagramUI.tsx +3 -0
  132. package/src/likec4diagram/DiagramXYFlow.tsx +9 -11
  133. package/src/likec4diagram/custom/edges/RelationshipEdge.tsx +25 -49
  134. package/src/likec4diagram/custom/index.ts +5 -4
  135. package/src/likec4diagram/custom/nodes/nodes.tsx +13 -11
  136. package/src/likec4diagram/custom/nodes/toolbar/CompoundToolbar.tsx +3 -2
  137. package/src/likec4diagram/relationship-popover/RelationshipPopover.tsx +535 -0
  138. package/src/likec4diagram/relationship-popover/actor.ts +192 -0
  139. package/src/likec4diagram/{custom/edges/RelationshipsDropdownMenu.css.ts → relationship-popover/styles.css.ts} +3 -19
  140. package/src/likec4diagram/useLayoutConstraints.ts +0 -1
  141. package/src/likec4model/useLikeC4ElementsTree.ts +1 -1
  142. package/src/navigationpanel/NavigationPanelDropdown.tsx +1 -2
  143. package/src/navigationpanel/actor.ts +2 -2
  144. package/src/navigationpanel/controls/NavigationButtons.tsx +1 -5
  145. package/src/navigationpanel/controls/ViewDetailsCard.tsx +2 -0
  146. package/src/overlays/relationship-details/layout-to-xyflow.ts +0 -1
  147. package/src/overlays/relationship-details/layout.ts +4 -3
  148. package/src/overlays/relationships-browser/custom/nodeTypes.tsx +22 -8
  149. package/src/overlays/relationships-browser/useViewToNodesEdges.ts +0 -1
  150. package/src/state/DiagramActorProvider.tsx +2 -20
  151. package/src/state/assign.ts +24 -10
  152. package/src/state/diagram-machine.ts +101 -53
  153. package/src/state/types.ts +4 -1
  154. package/src/utils/index.ts +2 -1
  155. package/src/utils/roundDpr.ts +27 -0
  156. package/src/utils/xyflow.ts +0 -7
  157. package/dist/base/primitives/compound/CompoundNodeContainer.css.d.ts +0 -35
  158. package/dist/base/primitives/compound/CompoundNodeContainer.css.js +0 -132
  159. package/dist/base/primitives/edge/EdgeLabel.css.d.ts +0 -7
  160. package/dist/base/primitives/edge/EdgeLabel.css.js +0 -57
  161. package/dist/base/primitives/element/ElementShape.css.d.ts +0 -6
  162. package/dist/base/primitives/element/ElementShape.css.js +0 -107
  163. package/dist/likec4diagram/custom/edges/NotePopover.css.js +0 -21
  164. package/dist/likec4diagram/custom/edges/NotePopover.js +0 -91
  165. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.css.d.ts +0 -5
  166. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.d.ts +0 -13
  167. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.js +0 -215
  168. package/dist/likec4diagram/custom/index.d.ts +0 -62
  169. package/dist/overlays/relationship-details/custom/nodeTypes.d.ts +0 -10
  170. package/src/base/primitives/compound/CompoundNodeContainer.css.ts +0 -138
  171. package/src/base/primitives/edge/EdgeLabel.css.ts +0 -64
  172. package/src/base/primitives/element/ElementShape.css.ts +0 -112
  173. package/src/likec4diagram/custom/edges/RelationshipsDropdownMenu.tsx +0 -281
@@ -1,10 +1,11 @@
1
1
  import { extractStep, isStepEdgeId } from '@likec4/core'
2
2
  import type { DiagramEdge } from '@likec4/core/types'
3
3
  import { css, cx } from '@likec4/styles/css'
4
- import { type BoxProps, Box } from '@likec4/styles/jsx'
4
+ import { Box } from '@likec4/styles/jsx'
5
5
  import { edgeLabel } from '@likec4/styles/recipes'
6
- import { Text } from '@mantine/core'
7
- import { type PropsWithChildren, forwardRef } from 'react'
6
+ import type { HTMLMotionProps } from 'motion/react'
7
+ import * as m from 'motion/react-m'
8
+ import { forwardRef } from 'react'
8
9
  import { isTruthy } from 'remeda'
9
10
  import type { UndefinedOnPartialDeep } from 'type-fest'
10
11
  import type { EdgeProps } from '../../types'
@@ -17,11 +18,12 @@ type Data = UndefinedOnPartialDeep<
17
18
  >
18
19
  >
19
20
 
20
- type EdgeLabelProps = PropsWithChildren<
21
- BoxProps & {
21
+ type EdgeLabelProps =
22
+ & HTMLMotionProps<'div'>
23
+ & {
24
+ children?: React.ReactNode
22
25
  edgeProps: EdgeProps<Data>
23
26
  }
24
- >
25
27
 
26
28
  export const EdgeLabel = forwardRef<HTMLDivElement, EdgeLabelProps>((
27
29
  {
@@ -30,7 +32,10 @@ export const EdgeLabel = forwardRef<HTMLDivElement, EdgeLabelProps>((
30
32
  data: {
31
33
  label,
32
34
  technology,
35
+ hovered: isHovered = false,
33
36
  },
37
+ selected = false,
38
+ selectable = false,
34
39
  },
35
40
  className,
36
41
  style,
@@ -42,10 +47,20 @@ export const EdgeLabel = forwardRef<HTMLDivElement, EdgeLabelProps>((
42
47
  const stepNum = isStepEdgeId(id) ? extractStep(id) : null
43
48
  const classes = edgeLabel({
44
49
  isStepEdge: stepNum !== null,
50
+ cursor: selectable || stepNum !== null ? 'pointer' : 'default',
45
51
  })
46
52
 
47
53
  return (
48
- <Box ref={ref} className={cx(classes.root, className)} {...rest}>
54
+ <m.div
55
+ ref={ref}
56
+ className={cx(classes.root, 'likec4-edge-label', className)}
57
+ data-edge-id={id}
58
+ animate={{
59
+ originY: 0.25,
60
+ scale: isHovered && !selected ? 1.08 : 1,
61
+ }}
62
+ {...rest}
63
+ >
49
64
  {stepNum !== null && (
50
65
  <Box className={classes.stepNumber}>
51
66
  {stepNum}
@@ -70,7 +85,7 @@ export const EdgeLabel = forwardRef<HTMLDivElement, EdgeLabelProps>((
70
85
  )}
71
86
  {children}
72
87
  </Box>
73
- </Box>
88
+ </m.div>
74
89
  )
75
90
  })
76
91
  EdgeLabel.displayName = 'EdgeLabel'
@@ -1,12 +1,11 @@
1
1
  import type { DiagramEdge } from '@likec4/core/types'
2
- import { cx } from '@likec4/styles/css'
2
+ import { css, cx } from '@likec4/styles/css'
3
3
  import { EdgeLabelRenderer } from '@xyflow/react'
4
4
  import { type HTMLAttributes } from 'react'
5
5
  import { isNumber } from 'remeda'
6
6
  import type { UndefinedOnPartialDeep } from 'type-fest'
7
7
  import { ZIndexes } from '../../const'
8
8
  import type { EdgeProps } from '../../types'
9
- import { edgeLabelContainer, translate as _translate } from './EdgeLabel.css'
10
9
 
11
10
  type Data = UndefinedOnPartialDeep<
12
11
  Pick<
@@ -70,7 +69,12 @@ export function EdgeLabelContainer({
70
69
  <div
71
70
  key={id}
72
71
  className={cx(
73
- edgeLabelContainer,
72
+ css({
73
+ display: {
74
+ _reduceGraphicsOnPan: 'none',
75
+ _smallZoom: 'none',
76
+ },
77
+ }),
74
78
  'nodrag nopan',
75
79
  'likec4-edge-label-container',
76
80
  className,
@@ -83,32 +87,16 @@ export function EdgeLabelContainer({
83
87
  'data-likec4-dimmed': isDimmed,
84
88
  }}
85
89
  style={{
86
- top: toCssVarValue(labelY),
87
- left: toCssVarValue(labelX),
88
- ...(translate && {
89
- [_translate.var]: translate,
90
- }),
91
90
  ...(labelBBox && {
92
91
  maxWidth: labelBBox.width + 18,
93
92
  }),
94
93
  zIndex,
95
94
  ...style,
95
+ transform: `translate(${toCssVarValue(labelX)}, ${toCssVarValue(labelY)}) ${translate || ''}`,
96
96
  }}
97
97
  {...rest}
98
98
  >
99
- <div
100
- style={{
101
- display: 'contents',
102
- }}
103
- {
104
- // Work around to keep same global selector data-likec4-dimmed
105
- ...isDimmed !== false && {
106
- 'data-likec4-dimmed': isDimmed,
107
- }
108
- }
109
- >
110
- {children}
111
- </div>
99
+ {children}
112
100
  </div>
113
101
  </EdgeLabelRenderer>
114
102
  )
@@ -22,9 +22,11 @@ export const edgePathBg = css(_hideOnReducedGraphics, {
22
22
  fill: '[none]',
23
23
  strokeWidth: 'calc(var(--xy-edge-stroke-width) + 2)',
24
24
  strokeOpacity: 0.08,
25
- transitionProperty: 'stroke-width, stroke-opacity',
26
- transitionDuration: 'fast',
27
- transitionTimingFunction: 'inOut',
25
+ _noReduceGraphics: {
26
+ transitionProperty: 'stroke-width, stroke-opacity',
27
+ transitionDuration: 'fast',
28
+ transitionTimingFunction: 'inOut',
29
+ },
28
30
  _whenHovered: {
29
31
  transitionTimingFunction: 'out',
30
32
  strokeWidth: 'calc(var(--xy-edge-stroke-width) + 4)',
@@ -49,18 +51,24 @@ export const cssEdgePath = css({
49
51
  fill: '[none!]',
50
52
  strokeDashoffset: 10,
51
53
  _noReduceGraphics: {
54
+ animationStyle: 'xyedgeAnimated',
55
+ animationPlayState: 'paused',
52
56
  transition: 'stroke 130ms ease-out,stroke-width 130ms ease-out',
53
57
  },
58
+ [`:where([data-edge-dir='back']) &`]: {
59
+ animationDirection: 'reverse',
60
+ },
54
61
  _whenHovered: {
55
- animationStyle: 'xyedgeAnimated',
56
- animationDelay: '450ms',
62
+ _noReduceGraphics: {
63
+ animationPlayState: 'running',
64
+ animationDelay: '450ms',
65
+ },
57
66
  },
58
67
  [`:where(${isSelected}, [data-edge-active='true'], [data-edge-animated='true']) &`]: {
59
- animationStyle: 'xyedgeAnimated',
60
- animationDelay: '0ms',
61
- },
62
- [`:where([data-edge-dir='back']) &`]: {
63
- animationDirection: 'reverse',
68
+ _noReduceGraphics: {
69
+ animationPlayState: 'running',
70
+ animationDelay: '0ms',
71
+ },
64
72
  },
65
73
  _whenDimmed: {
66
74
  animationPlayState: 'paused',
@@ -70,6 +78,6 @@ export const cssEdgePath = css({
70
78
  },
71
79
  _whenPanning: {
72
80
  strokeDasharray: 'none !important',
73
- animationName: 'none',
81
+ animationPlayState: 'paused',
74
82
  },
75
83
  })
@@ -1,14 +1,14 @@
1
1
  import { nonexhaustive } from '@likec4/core'
2
2
  import type { ElementShape, ElementStyle } from '@likec4/core/types'
3
- import { cx as clsx } from '@likec4/styles/css'
4
- import { toDomPrecision } from '../../../utils/xyflow'
5
- import * as css from './ElementShape.css'
3
+ import { Box } from '@likec4/styles/jsx'
4
+ import { elementShapeRecipe } from '@likec4/styles/recipes'
5
+ import { roundDpr } from '../../../utils'
6
6
 
7
7
  export function cylinderSVGPath(diameter: number, height: number, tilt = 0.065) {
8
8
  const radius = Math.round(diameter / 2)
9
9
  // const tiltAdjustedHeight = height * Math.cos((tilt * Math.PI) / 2)
10
10
  const rx = radius
11
- const ry = toDomPrecision(tilt * radius)
11
+ const ry = roundDpr(tilt * radius)
12
12
  const tiltAdjustedHeight = height - 2 * ry
13
13
 
14
14
  const path = ` M ${diameter},${ry}
@@ -31,7 +31,7 @@ function queueSVGPath(width: number, height: number, tilt = 0.185) {
31
31
  const diameter = height
32
32
  const radius = Math.round(diameter / 2)
33
33
  const ry = radius
34
- const rx = toDomPrecision((diameter / 2) * tilt)
34
+ const rx = roundDpr((diameter / 2) * tilt)
35
35
  const tiltAdjustedWidth = width - 2 * rx
36
36
 
37
37
  const path = `
@@ -62,7 +62,7 @@ type ElementShapeProps = {
62
62
  h: number
63
63
  }
64
64
 
65
- function ElementShapeSvg({ shape, w, h }: ElementShapeProps) {
65
+ function ShapeSvg({ shape, w, h }: ElementShapeProps) {
66
66
  switch (shape) {
67
67
  case 'mobile': {
68
68
  return (
@@ -71,10 +71,10 @@ function ElementShapeSvg({ shape, w, h }: ElementShapeProps) {
71
71
  width={w}
72
72
  height={h}
73
73
  rx={6}
74
- className={css.fillMixStroke}
74
+ data-likec4-fill="mix-stroke"
75
75
  strokeWidth={0}
76
76
  />
77
- <g className={css.fillElementFill} strokeWidth={0}>
77
+ <g data-likec4-fill="fill" strokeWidth={0}>
78
78
  <circle cx={17} cy={h / 2} r={12} />
79
79
  <rect x={33} y={12} width={w - 44} height={h - 24} rx={5} />
80
80
  </g>
@@ -88,10 +88,10 @@ function ElementShapeSvg({ shape, w, h }: ElementShapeProps) {
88
88
  width={w}
89
89
  height={h}
90
90
  rx={6}
91
- className={css.fillMixStroke}
91
+ data-likec4-fill="mix-stroke"
92
92
  strokeWidth={0}
93
93
  />
94
- <g className={css.fillElementFill} strokeWidth={0}>
94
+ <g data-likec4-fill="fill" strokeWidth={0}>
95
95
  <circle cx={16} cy={17} r={7} />
96
96
  <circle cx={36} cy={17} r={7} />
97
97
  <circle cx={56} cy={17} r={7} />
@@ -115,7 +115,7 @@ function ElementShapeSvg({ shape, w, h }: ElementShapeProps) {
115
115
  width={PersonIcon.width}
116
116
  height={PersonIcon.height}
117
117
  viewBox={`0 0 ${PersonIcon.width} ${PersonIcon.height}`}
118
- className={css.fillMixStroke}
118
+ data-likec4-fill="mix-stroke"
119
119
  >
120
120
  <path
121
121
  strokeWidth={0}
@@ -129,7 +129,7 @@ function ElementShapeSvg({ shape, w, h }: ElementShapeProps) {
129
129
  return (
130
130
  <>
131
131
  <path d={path} strokeWidth={2} />
132
- <ellipse cx={rx} cy={ry} ry={ry - 0.75} rx={rx} className={css.fillMixStroke} strokeWidth={2} />
132
+ <ellipse cx={rx} cy={ry} ry={ry - 0.75} rx={rx} data-likec4-fill="mix-stroke" strokeWidth={2} />
133
133
  </>
134
134
  )
135
135
  }
@@ -139,7 +139,7 @@ function ElementShapeSvg({ shape, w, h }: ElementShapeProps) {
139
139
  return (
140
140
  <>
141
141
  <path d={path} strokeWidth={2} />
142
- <ellipse cx={rx} cy={ry} ry={ry} rx={rx - 0.75} className={css.fillMixStroke} strokeWidth={2} />
142
+ <ellipse cx={rx} cy={ry} ry={ry} rx={rx - 0.75} data-likec4-fill="mix-stroke" strokeWidth={2} />
143
143
  </>
144
144
  )
145
145
  }
@@ -158,6 +158,19 @@ function ElementShapeSvg({ shape, w, h }: ElementShapeProps) {
158
158
  }
159
159
  }
160
160
 
161
+ function ShapeHtml({ multiple, withOutLine }: { multiple: boolean; withOutLine: boolean }) {
162
+ return (
163
+ <Box
164
+ className={elementShapeRecipe({
165
+ shapetype: 'html',
166
+ })}
167
+ >
168
+ {multiple && <div className={'likec4-shape-multiple'} />}
169
+ {withOutLine && <div className={'likec4-shape-outline'} />}
170
+ </Box>
171
+ )
172
+ }
173
+
161
174
  type Data = {
162
175
  shape: ElementShape
163
176
  width: number
@@ -183,16 +196,25 @@ export function ElementShape(
183
196
  let w = !!width && width > 10 ? width : data.width
184
197
  let h = !!height && height > 10 ? height : data.height
185
198
  const isMultiple = data.style?.multiple ?? false
199
+
200
+ if (data.shape === 'rectangle') {
201
+ return <ShapeHtml multiple={isMultiple} withOutLine={withSelectedIndicator} />
202
+ }
203
+
204
+ const className = elementShapeRecipe({
205
+ shapetype: 'svg',
206
+ })
207
+
186
208
  return (
187
209
  <>
188
210
  {isMultiple && (
189
- <svg className={clsx(css.shapeSvgMultiple)} viewBox={`0 0 ${w} ${h}`}>
190
- <ElementShapeSvg shape={data.shape} w={w} h={h} />
211
+ <svg className={className} data-likec4-shape-multiple="true" viewBox={`0 0 ${w} ${h}`}>
212
+ <ShapeSvg shape={data.shape} w={w} h={h} />
191
213
  </svg>
192
214
  )}
193
- <svg className={css.shapeSvg} viewBox={`0 0 ${w} ${h}`}>
215
+ <svg className={className} viewBox={`0 0 ${w} ${h}`}>
194
216
  {withSelectedIndicator && <SelectedIndicator shape={data.shape} w={w} h={h} />}
195
- <ElementShapeSvg shape={data.shape} w={w} h={h} />
217
+ <ShapeSvg shape={data.shape} w={w} h={h} />
196
218
  </svg>
197
219
  </>
198
220
  )
@@ -224,5 +246,5 @@ export function SelectedIndicator({ shape, w, h }: ElementShapeProps) {
224
246
  break
225
247
  }
226
248
  }
227
- return <g className={css.indicator}>{svg}</g>
249
+ return <g className={'likec4-shape-outline'}>{svg}</g>
228
250
  }
@@ -19,7 +19,7 @@ export type ElementTagProps = {
19
19
  } & Omit<BoxProps, 'children'>
20
20
 
21
21
  export const ElementTag = forwardRef<HTMLDivElement, ElementTagProps>(
22
- ({ tag, cursor = 'default', className, ...props }, ref) => {
22
+ ({ tag, cursor, className, style, ...props }, ref) => {
23
23
  const spec = useTagSpecification(tag)
24
24
  return (
25
25
  <Box
@@ -32,7 +32,10 @@ export const ElementTag = forwardRef<HTMLDivElement, ElementTagProps>(
32
32
  className,
33
33
  )}
34
34
  {...props}
35
- style={{ cursor }}
35
+ style={{
36
+ cursor,
37
+ ...style,
38
+ }}
36
39
  >
37
40
  <span>#</span>
38
41
  <span>{tag}</span>
@@ -129,7 +132,7 @@ export const ElementTags = memo(({ id, data: { tags, width, hovered = false } }:
129
132
  data-likec4-tag={tag}
130
133
  className={css({
131
134
  layerStyle: 'likec4.tag',
132
- flex: 1,
135
+ flex: '1',
133
136
  display: 'flex',
134
137
  alignItems: 'center',
135
138
  justifyContent: 'center',
@@ -162,9 +165,9 @@ export const ElementTags = memo(({ id, data: { tags, width, hovered = false } }:
162
165
  <ElementTag
163
166
  key={tag}
164
167
  tag={tag}
168
+ cursor="pointer"
165
169
  className={css({
166
170
  userSelect: 'none',
167
- cursor: 'pointer',
168
171
  ...(zoomIsLargeEnough && {
169
172
  fontSize: 'lg',
170
173
  borderRadius: '[4px]',
@@ -77,17 +77,29 @@ export function ElementTitle({ id, data, iconSize }: ElementTitleProps) {
77
77
  </Text>
78
78
  )}
79
79
 
80
- {data.description && (
81
- <MarkdownBlock
82
- className={cx(classes.description, 'likec4-element-description')}
83
- value={data.description}
84
- uselikec4palette
85
- hideIfEmpty
86
- // Workaround for lineClamp not working with nested TABLE elements (if markdown has tables)
87
- maxHeight={data.description.isMarkdown ? '8rem' : undefined}
88
- // textScale={0.95}
89
- lineClamp={isSmOrXs ? 3 : 5}
90
- />
80
+ {data.description?.nonEmpty && (
81
+ data.description.isMarkdown
82
+ ? (
83
+ <MarkdownBlock
84
+ className={cx(classes.description, 'likec4-element-description')}
85
+ value={data.description}
86
+ uselikec4palette
87
+ hideIfEmpty
88
+ // Workaround for lineClamp not working with nested TABLE elements (if markdown has tables)
89
+ maxHeight={data.description.isMarkdown ? '8rem' : undefined}
90
+ // textScale={0.95}
91
+ lineClamp={isSmOrXs ? 3 : 5}
92
+ />
93
+ )
94
+ : (
95
+ <Text
96
+ component="div"
97
+ className={cx(classes.description, 'likec4-element-description')}
98
+ lineClamp={isSmOrXs ? 3 : 5}
99
+ >
100
+ {data.description.text}
101
+ </Text>
102
+ )
91
103
  )}
92
104
  </Box>
93
105
  </Box>
package/src/base/types.ts CHANGED
@@ -8,25 +8,21 @@ import type { OptionalKeysOf, SetRequired, Simplify } from 'type-fest'
8
8
  import * as Base from './types.Base'
9
9
 
10
10
  /**
11
-
12
- To cooperate with `exactOptionalPropertyTypes` in `tsconfig.json`
13
-
14
- @example
15
- ```
16
- interface User {
17
- name: string;
18
- surname?: string;
19
- luckyNumber?: number;
20
- }
21
-
22
- type NonOptionalUser = NonOptional<User>
23
-
24
- // NonOptionalUser = {
25
- // name: string
26
- // surname: string | undefined
27
- // luckyNumber: number | undefined
28
- // }
29
- ```
11
+ * To cooperate with `exactOptionalPropertyTypes` in `tsconfig.json`
12
+ *
13
+ * @example
14
+ * interface User {
15
+ * name: string;
16
+ * surname?: string;
17
+ * luckyNumber?: number;
18
+ * }
19
+ *
20
+ * type NonOptionalUser = NonOptional<User>
21
+ * // NonOptionalUser = {
22
+ * // name: string
23
+ * // surname: string | undefined
24
+ * // luckyNumber: number | undefined
25
+ * // }
30
26
  */
31
27
  export type NonOptional<T extends object, Keys extends OptionalKeysOf<T> = OptionalKeysOf<T>> = Simplify<
32
28
  & {
@@ -40,17 +36,17 @@ export type NonOptional<T extends object, Keys extends OptionalKeysOf<T> = Optio
40
36
  /**
41
37
  * ReactFlow Custom Node properties with BaseNodeData at least
42
38
  */
43
- export type NodeProps<T extends Record<string, unknown> = {}, NodeType extends string = string> = ReactFlowNodeProps<
44
- RFNode<Base.NodeData & T, NodeType>
39
+ export type NodeProps<T extends Record<string, unknown> = {}, NodeType extends string = string> = Simplify<
40
+ ReactFlowNodeProps<
41
+ RFNode<Base.NodeData & T, NodeType>
42
+ >
45
43
  >
46
44
 
47
45
  /**
48
46
  * ReactFlow Custom Edge properties with BaseEdgeData at least
49
47
  */
50
- export type EdgeProps<T extends Record<string, unknown> = {}> = SetRequired<
51
- ReactFlowEdgeProps<
52
- RFEdge<Base.EdgeData & T, any>
53
- >,
48
+ export type EdgeProps<T extends Record<string, unknown> = {}, EdgeType extends string = string> = SetRequired<
49
+ Simplify<ReactFlowEdgeProps<RFEdge<Base.EdgeData & T, EdgeType>>>,
54
50
  'data'
55
51
  >
56
52
 
@@ -1,4 +1,4 @@
1
- import type { aux, WhereOperator } from '@likec4/core/types'
1
+ import type { Any, aux, WhereOperator } from '@likec4/core/types'
2
2
  import type { CSSProperties } from 'react'
3
3
  import type {
4
4
  CustomNodes,
@@ -8,7 +8,7 @@ import type {
8
8
  ViewPadding,
9
9
  } from '../LikeC4Diagram.props'
10
10
 
11
- export interface LikeC4ViewProps<A extends aux.Any> {
11
+ export interface LikeC4ViewProps<A extends Any> {
12
12
  /**
13
13
  * View to display.
14
14
  */
@@ -1,4 +1,4 @@
1
- import type { Any, aux, DiagramView } from '@likec4/core/types'
1
+ import type { Any, aux, DiagramView, UnknownLayouted } from '@likec4/core/types'
2
2
  import { cx } from '@likec4/styles/css'
3
3
  import { ActionIcon, Box } from '@mantine/core'
4
4
  import { shallowEqual } from '@mantine/hooks'
@@ -15,7 +15,7 @@ import { ShadowRoot } from './ShadowRoot'
15
15
  import { cssInteractive, useColorScheme, useShadowRootStyle } from './styles.css'
16
16
  import { ErrorMessage, ViewNotFound } from './ViewNotFound'
17
17
 
18
- export function LikeC4View<A extends aux.Any = aux.UnknownLayouted>({
18
+ export function LikeC4View<A extends Any = UnknownLayouted>({
19
19
  viewId,
20
20
  ...props
21
21
  }: LikeC4ViewProps<A>) {
@@ -44,10 +44,10 @@ const DEFAULT_BROWSER_PADDING: ViewPadding = {
44
44
  right: '16px',
45
45
  }
46
46
 
47
- type LikeC4ViewInnerProps<A extends aux.Any> = Omit<LikeC4ViewProps<A>, 'viewId'> & {
47
+ type LikeC4ViewInnerProps<A extends Any> = Omit<LikeC4ViewProps<A>, 'viewId'> & {
48
48
  view: DiagramView<A>
49
49
  }
50
- const LikeC4ViewInner = memo<LikeC4ViewInnerProps<aux.Any>>(({
50
+ const LikeC4ViewInner = memo<LikeC4ViewInnerProps<Any>>(({
51
51
  view,
52
52
  className,
53
53
  pannable = false,
@@ -140,7 +140,10 @@ const LikeC4ViewInner = memo<LikeC4ViewInnerProps<aux.Any>>(({
140
140
  controls={controls}
141
141
  nodesDraggable={false}
142
142
  reduceGraphics={reduceGraphics}
143
- className={cx(isBrowserEnabled && cssInteractive)}
143
+ className={cx(
144
+ 'likec4-static-view',
145
+ isBrowserEnabled && cssInteractive,
146
+ )}
144
147
  // We may have multiple embedded views on the same page
145
148
  // so we don't want enable search and hotkeys
146
149
  enableSearch={false}
@@ -1,4 +1,4 @@
1
- import type { Any, aux, DiagramView } from '@likec4/core/types'
1
+ import type { Any, aux, DiagramView, UnknownLayouted } from '@likec4/core/types'
2
2
  import { cx } from '@likec4/styles/css'
3
3
  import { type CSSProperties } from 'react'
4
4
  import { isFunction, isString } from 'remeda'
@@ -8,7 +8,7 @@ import { ShadowRoot } from './ShadowRoot'
8
8
  import { useColorScheme, useShadowRootStyle } from './styles.css'
9
9
  import { ErrorMessage, ViewNotFound } from './ViewNotFound'
10
10
 
11
- export type ReactLikeC4Props<A extends aux.Any> = Omit<LikeC4DiagramProps<A>, 'view'> & {
11
+ export type ReactLikeC4Props<A extends Any> = Omit<LikeC4DiagramProps<A>, 'view'> & {
12
12
  viewId: aux.ViewId<A>
13
13
 
14
14
  /**
@@ -41,7 +41,7 @@ export type ReactLikeC4Props<A extends aux.Any> = Omit<LikeC4DiagramProps<A>, 'v
41
41
  styleNonce?: string | (() => string) | undefined
42
42
  }
43
43
 
44
- export function ReactLikeC4<A extends aux.Any = aux.UnknownLayouted>({
44
+ export function ReactLikeC4<A extends Any = UnknownLayouted>({
45
45
  viewId,
46
46
  ...props
47
47
  }: ReactLikeC4Props<A>) {
@@ -58,8 +58,9 @@ export const Link = forwardRef<HTMLDivElement, Omit<BadgeProps, 'children' | 'cl
58
58
  maxWidth: 500,
59
59
  userSelect: 'all',
60
60
  pr: '0',
61
- _hover: {
62
- backgroundColor: {
61
+ backgroundColor: {
62
+ base: 'transparent',
63
+ _hover: {
63
64
  base: 'mantine.colors.gray[1]',
64
65
  _dark: 'mantine.colors.dark[5]',
65
66
  },
@@ -21,11 +21,7 @@ export function RootContainer({
21
21
 
22
22
  useEffect(() => {
23
23
  return $isPanning.listen((isPanning) => {
24
- if (isPanning) {
25
- ref.current?.setAttribute('data-likec4-diagram-panning', 'true')
26
- } else {
27
- ref.current?.removeAttribute('data-likec4-diagram-panning')
28
- }
24
+ ref.current?.setAttribute('data-likec4-diagram-panning', isPanning ? 'true' : 'false')
29
25
  })
30
26
  }, [$isPanning])
31
27
 
@@ -7,6 +7,7 @@ import { useLikeC4Specification } from '../likec4model/useLikeC4Model'
7
7
 
8
8
  const TagStylesContext = createContext<Record<string, TagSpecification>>({})
9
9
 
10
+ // TODO: keep this in sync with styled-system/preset/src/const.ts
10
11
  const radixColors = [
11
12
  'yellow',
12
13
  'orange',
@@ -28,6 +29,7 @@ const radixColors = [
28
29
 
29
30
  const generateColorVars = (spec: TagSpecification) => {
30
31
  const color = spec.color
32
+ // Tag has a color defined in the specification
31
33
  if (isTagColorSpecified(spec)) {
32
34
  return `
33
35
  --colors-likec4-tag-bg: ${color};