@likec4/diagram 1.36.1 → 1.37.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-DSORWspW.js} +1008 -988
  2. package/bundle/custom.js +64 -56
  3. package/bundle/index.js +3539 -3315
  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 +11 -10
  97. package/panda.buildinfo.json +90 -155
  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
@@ -2,19 +2,7 @@ import { cva } from '@likec4/styles/css';
2
2
 
3
3
  const compoundActionBtn = cva({
4
4
  base: {
5
- transitionDuration: "normal",
6
- "[data-compound-title-inverse] &": {
7
- _dark: {
8
- "--actionbtn-color": "color-mix(in srgb, var(--likec4-palette-loContrast) 60%, var(--likec4-palette-fill))"
9
- },
10
- _light: {
11
- "--actionbtn-color": "var(--likec4-palette-stroke)",
12
- "--actionbtn-color-hovered": "var(--likec4-palette-stroke)",
13
- "--actionbtn-color-hovered-btn": "var(--likec4-palette-hiContrast)",
14
- "--actionbtn-bg-hovered": `var(--likec4-palette-fill)/50`,
15
- "--actionbtn-bg-hovered-btn": `var(--likec4-palette-fill)`
16
- }
17
- }
5
+ transitionDuration: "normal"
18
6
  },
19
7
  variants: {
20
8
  delay: {
@@ -1,4 +1,4 @@
1
1
  import { FunctionComponent } from 'react';
2
2
  import { Base, EdgeProps } from '../types';
3
3
  export declare const edgePropsEqual: <P extends Record<string, unknown> = Base.EdgeData>(prev: EdgeProps<P>, next: EdgeProps<P>) => boolean;
4
- export declare function customEdge<P extends Record<string, unknown> = Base.NodeData>(Edge: FunctionComponent<EdgeProps<P>>): FunctionComponent<EdgeProps<P>>;
4
+ export declare function customEdge<P extends Record<string, unknown> = Base.EdgeData>(Edge: FunctionComponent<EdgeProps<P>>): FunctionComponent<EdgeProps<P>>;
@@ -1,4 +1,4 @@
1
- import { FunctionComponent, MemoExoticComponent } from 'react';
2
- import { Base, NodeProps } from '../types';
3
- export declare const nodePropsEqual: <P extends Record<string, unknown> = Base.NodeData>(prev: NodeProps<P>, next: NodeProps<P>) => boolean;
4
- export declare function customNode<P extends Record<string, unknown> = {}, NodeType extends string = string>(Node: FunctionComponent<NodeProps<P, NodeType>>): MemoExoticComponent<(props: NodeProps<P, NodeType>) => import("react/jsx-runtime").JSX.Element>;
1
+ import { FunctionComponent } from 'react';
2
+ import { NodeProps } from '../types';
3
+ export declare function nodePropsEqual<P extends NodeProps<any, any>>(prev: P, next: P): boolean;
4
+ export declare function customNode<P extends Record<string, unknown> = {}, NodeType extends string = string>(Node: FunctionComponent<NodeProps<P, NodeType>>): FunctionComponent<NodeProps<P, NodeType>>;
@@ -1,14 +1,14 @@
1
- import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
1
  import { deepEqual } from 'fast-equals';
3
2
  import { memo } from 'react';
4
- import { DefaultHandles } from './NodeHandles.js';
5
3
 
6
- const nodePropsEqual = (prev, next) => prev.id === next.id && deepEqual(prev.selected ?? false, next.selected ?? false) && deepEqual(prev.dragging ?? false, next.dragging ?? false) && deepEqual(prev.width ?? 0, next.width ?? 0) && deepEqual(prev.height ?? 0, next.height ?? 0) && deepEqual(prev.zIndex ?? 0, next.zIndex ?? 0) && deepEqual(prev.data, next.data);
4
+ function nodePropsEqual(prev, next) {
5
+ return prev.id === next.id && deepEqual(prev.selected ?? false, next.selected ?? false) && deepEqual(prev.dragging ?? false, next.dragging ?? false) && deepEqual(prev.width ?? 0, next.width ?? 0) && deepEqual(prev.height ?? 0, next.height ?? 0) && deepEqual(prev.zIndex ?? 0, next.zIndex ?? 0) && deepEqual(prev.data, next.data);
6
+ }
7
7
  function customNode(Node) {
8
- const NodeComponent = memo((props) => /* @__PURE__ */ jsxs(Fragment, { children: [
9
- /* @__PURE__ */ jsx(Node, { ...props }),
10
- /* @__PURE__ */ jsx(DefaultHandles, {})
11
- ] }), nodePropsEqual);
8
+ const NodeComponent = memo(
9
+ Node,
10
+ (prev, next) => nodePropsEqual(prev, next)
11
+ );
12
12
  NodeComponent.displayName = "Node";
13
13
  return NodeComponent;
14
14
  }
@@ -1,11 +1,12 @@
1
1
  import { DiagramEdge } from '@likec4/core/types';
2
- import { BoxProps } from '@likec4/styles/jsx';
3
- import { PropsWithChildren, ForwardRefExoticComponent, RefAttributes } from 'react';
2
+ import { HTMLMotionProps } from 'motion/react';
4
3
  import { UndefinedOnPartialDeep } from 'type-fest';
5
4
  import { EdgeProps } from '../../types';
5
+ import { ForwardRefExoticComponent, RefAttributes } from 'react';
6
6
  type Data = UndefinedOnPartialDeep<Pick<DiagramEdge, 'label' | 'technology'>>;
7
- type EdgeLabelProps = PropsWithChildren<BoxProps & {
7
+ type EdgeLabelProps = HTMLMotionProps<'div'> & {
8
+ children?: React.ReactNode;
8
9
  edgeProps: EdgeProps<Data>;
9
- }>;
10
+ };
10
11
  export declare const EdgeLabel: ForwardRefExoticComponent<Omit<EdgeLabelProps, "ref"> & RefAttributes<HTMLDivElement>>;
11
12
  export {};
@@ -3,6 +3,7 @@ import { isStepEdgeId, extractStep } from '@likec4/core';
3
3
  import { cx, css } from '@likec4/styles/css';
4
4
  import { Box } from '@likec4/styles/jsx';
5
5
  import { edgeLabel } from '@likec4/styles/recipes';
6
+ import * as m from 'motion/react-m';
6
7
  import { forwardRef } from 'react';
7
8
  import { isTruthy } from 'remeda';
8
9
 
@@ -11,8 +12,11 @@ const EdgeLabel = forwardRef(({
11
12
  id,
12
13
  data: {
13
14
  label,
14
- technology
15
- }
15
+ technology,
16
+ hovered: isHovered = false
17
+ },
18
+ selected = false,
19
+ selectable = false
16
20
  },
17
21
  className,
18
22
  style,
@@ -21,27 +25,41 @@ const EdgeLabel = forwardRef(({
21
25
  }, ref) => {
22
26
  const stepNum = isStepEdgeId(id) ? extractStep(id) : null;
23
27
  const classes = edgeLabel({
24
- isStepEdge: stepNum !== null
28
+ isStepEdge: stepNum !== null,
29
+ cursor: selectable || stepNum !== null ? "pointer" : "default"
25
30
  });
26
- return /* @__PURE__ */ jsxs(Box, { ref, className: cx(classes.root, className), ...rest, children: [
27
- stepNum !== null && /* @__PURE__ */ jsx(Box, { className: classes.stepNumber, children: stepNum }),
28
- /* @__PURE__ */ jsxs(Box, { className: classes.labelContents, children: [
29
- isTruthy(label) && /* @__PURE__ */ jsx(
30
- Box,
31
- {
32
- className: cx(
33
- classes.labelText,
34
- css({
35
- lineClamp: 5
36
- })
31
+ return /* @__PURE__ */ jsxs(
32
+ m.div,
33
+ {
34
+ ref,
35
+ className: cx(classes.root, "likec4-edge-label", className),
36
+ "data-edge-id": id,
37
+ animate: {
38
+ originY: 0.25,
39
+ scale: isHovered && !selected ? 1.08 : 1
40
+ },
41
+ ...rest,
42
+ children: [
43
+ stepNum !== null && /* @__PURE__ */ jsx(Box, { className: classes.stepNumber, children: stepNum }),
44
+ /* @__PURE__ */ jsxs(Box, { className: classes.labelContents, children: [
45
+ isTruthy(label) && /* @__PURE__ */ jsx(
46
+ Box,
47
+ {
48
+ className: cx(
49
+ classes.labelText,
50
+ css({
51
+ lineClamp: 5
52
+ })
53
+ ),
54
+ children: label
55
+ }
37
56
  ),
38
- children: label
39
- }
40
- ),
41
- isTruthy(technology) && /* @__PURE__ */ jsx(Box, { className: classes.labelTechnology, children: "[ " + technology + " ]" }),
42
- children
43
- ] })
44
- ] });
57
+ isTruthy(technology) && /* @__PURE__ */ jsx(Box, { className: classes.labelTechnology, children: "[ " + technology + " ]" }),
58
+ children
59
+ ] })
60
+ ]
61
+ }
62
+ );
45
63
  });
46
64
  EdgeLabel.displayName = "EdgeLabel";
47
65
 
@@ -1,9 +1,8 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { cx } from '@likec4/styles/css';
2
+ import { cx, css } from '@likec4/styles/css';
3
3
  import { EdgeLabelRenderer } from '@xyflow/react';
4
4
  import { isNumber } from 'remeda';
5
5
  import { ZIndexes } from '../../const.js';
6
- import { translate, edgeLabelContainer } from './EdgeLabel.css.js';
7
6
 
8
7
  const toCssVarValue = (value) => {
9
8
  if (value === void 0) return void 0;
@@ -34,12 +33,17 @@ function EdgeLabelContainer({
34
33
  if (labelX === void 0 || labelY === void 0) {
35
34
  return null;
36
35
  }
37
- const translate$1 = labelXY?.translate;
36
+ const translate = labelXY?.translate;
38
37
  return /* @__PURE__ */ jsx(EdgeLabelRenderer, { children: /* @__PURE__ */ jsx(
39
38
  "div",
40
39
  {
41
40
  className: cx(
42
- edgeLabelContainer,
41
+ css({
42
+ display: {
43
+ _reduceGraphicsOnPan: "none",
44
+ _smallZoom: "none"
45
+ }
46
+ }),
43
47
  "nodrag nopan",
44
48
  "likec4-edge-label-container",
45
49
  className
@@ -52,31 +56,15 @@ function EdgeLabelContainer({
52
56
  "data-likec4-dimmed": isDimmed
53
57
  },
54
58
  style: {
55
- top: toCssVarValue(labelY),
56
- left: toCssVarValue(labelX),
57
- ...translate$1 && {
58
- [translate.var]: translate$1
59
- },
60
59
  ...labelBBox && {
61
60
  maxWidth: labelBBox.width + 18
62
61
  },
63
62
  zIndex,
64
- ...style
63
+ ...style,
64
+ transform: `translate(${toCssVarValue(labelX)}, ${toCssVarValue(labelY)}) ${translate || ""}`
65
65
  },
66
66
  ...rest,
67
- children: /* @__PURE__ */ jsx(
68
- "div",
69
- {
70
- style: {
71
- display: "contents"
72
- },
73
- // Work around to keep same global selector data-likec4-dimmed
74
- ...isDimmed !== false && {
75
- "data-likec4-dimmed": isDimmed
76
- },
77
- children
78
- }
79
- )
67
+ children
80
68
  },
81
69
  id
82
70
  ) }, id);
@@ -19,9 +19,11 @@ const edgePathBg = css(_hideOnReducedGraphics, {
19
19
  fill: "[none]",
20
20
  strokeWidth: "calc(var(--xy-edge-stroke-width) + 2)",
21
21
  strokeOpacity: 0.08,
22
- transitionProperty: "stroke-width, stroke-opacity",
23
- transitionDuration: "fast",
24
- transitionTimingFunction: "inOut",
22
+ _noReduceGraphics: {
23
+ transitionProperty: "stroke-width, stroke-opacity",
24
+ transitionDuration: "fast",
25
+ transitionTimingFunction: "inOut"
26
+ },
25
27
  _whenHovered: {
26
28
  transitionTimingFunction: "out",
27
29
  strokeWidth: "calc(var(--xy-edge-stroke-width) + 4)",
@@ -43,18 +45,24 @@ const cssEdgePath = css({
43
45
  fill: "[none!]",
44
46
  strokeDashoffset: 10,
45
47
  _noReduceGraphics: {
48
+ animationStyle: "xyedgeAnimated",
49
+ animationPlayState: "paused",
46
50
  transition: "stroke 130ms ease-out,stroke-width 130ms ease-out"
47
51
  },
52
+ [`:where([data-edge-dir='back']) &`]: {
53
+ animationDirection: "reverse"
54
+ },
48
55
  _whenHovered: {
49
- animationStyle: "xyedgeAnimated",
50
- animationDelay: "450ms"
56
+ _noReduceGraphics: {
57
+ animationPlayState: "running",
58
+ animationDelay: "450ms"
59
+ }
51
60
  },
52
61
  [`:where(${isSelected}, [data-edge-active='true'], [data-edge-animated='true']) &`]: {
53
- animationStyle: "xyedgeAnimated",
54
- animationDelay: "0ms"
55
- },
56
- [`:where([data-edge-dir='back']) &`]: {
57
- animationDirection: "reverse"
62
+ _noReduceGraphics: {
63
+ animationPlayState: "running",
64
+ animationDelay: "0ms"
65
+ }
58
66
  },
59
67
  _whenDimmed: {
60
68
  animationPlayState: "paused"
@@ -64,7 +72,7 @@ const cssEdgePath = css({
64
72
  },
65
73
  _whenPanning: {
66
74
  strokeDasharray: "none !important",
67
- animationName: "none"
75
+ animationPlayState: "paused"
68
76
  }
69
77
  });
70
78
 
@@ -1,13 +1,13 @@
1
- import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { nonexhaustive } from '@likec4/core';
3
- import { cx } from '@likec4/styles/css';
4
- import { toDomPrecision } from '../../../utils/xyflow.js';
5
- import { shapeSvgMultiple, shapeSvg, fillMixStroke, fillElementFill, indicator } from './ElementShape.css.js';
3
+ import { Box } from '@likec4/styles/jsx';
4
+ import { elementShapeRecipe } from '@likec4/styles/recipes';
5
+ import { roundDpr } from '../../../utils/roundDpr.js';
6
6
 
7
7
  function cylinderSVGPath(diameter, height, tilt = 0.065) {
8
8
  const radius = Math.round(diameter / 2);
9
9
  const rx = radius;
10
- const ry = toDomPrecision(tilt * radius);
10
+ const ry = roundDpr(tilt * radius);
11
11
  const tiltAdjustedHeight = height - 2 * ry;
12
12
  const path = ` M ${diameter},${ry}
13
13
  a ${rx},${ry} 0,0,0 ${-diameter} 0
@@ -26,7 +26,7 @@ function queueSVGPath(width, height, tilt = 0.185) {
26
26
  const diameter = height;
27
27
  const radius = Math.round(diameter / 2);
28
28
  const ry = radius;
29
- const rx = toDomPrecision(diameter / 2 * tilt);
29
+ const rx = roundDpr(diameter / 2 * tilt);
30
30
  const tiltAdjustedWidth = width - 2 * rx;
31
31
  const path = `
32
32
  M ${rx},0
@@ -45,7 +45,7 @@ const PersonIcon = {
45
45
  height: 120,
46
46
  path: `M57.9197 0C10.9124 0 33.5766 54.75 33.5766 54.75C38.6131 62.25 45.3285 60.75 45.3285 66C45.3285 70.5 39.4526 72 33.5766 72.75C24.3431 72.75 15.9489 71.25 7.55474 84.75C2.51825 93 0 120 0 120H115C115 120 112.482 93 108.285 84.75C99.8905 70.5 91.4963 72.75 82.2628 72C76.3869 71.25 70.5109 69.75 70.5109 65.25C70.5109 60.75 77.2263 62.25 82.2628 54C82.2628 54.75 104.927 0 57.9197 0V0Z`
47
47
  };
48
- function ElementShapeSvg({ shape, w, h }) {
48
+ function ShapeSvg({ shape, w, h }) {
49
49
  switch (shape) {
50
50
  case "mobile": {
51
51
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -55,11 +55,11 @@ function ElementShapeSvg({ shape, w, h }) {
55
55
  width: w,
56
56
  height: h,
57
57
  rx: 6,
58
- className: fillMixStroke,
58
+ "data-likec4-fill": "mix-stroke",
59
59
  strokeWidth: 0
60
60
  }
61
61
  ),
62
- /* @__PURE__ */ jsxs("g", { className: fillElementFill, strokeWidth: 0, children: [
62
+ /* @__PURE__ */ jsxs("g", { "data-likec4-fill": "fill", strokeWidth: 0, children: [
63
63
  /* @__PURE__ */ jsx("circle", { cx: 17, cy: h / 2, r: 12 }),
64
64
  /* @__PURE__ */ jsx("rect", { x: 33, y: 12, width: w - 44, height: h - 24, rx: 5 })
65
65
  ] })
@@ -73,11 +73,11 @@ function ElementShapeSvg({ shape, w, h }) {
73
73
  width: w,
74
74
  height: h,
75
75
  rx: 6,
76
- className: fillMixStroke,
76
+ "data-likec4-fill": "mix-stroke",
77
77
  strokeWidth: 0
78
78
  }
79
79
  ),
80
- /* @__PURE__ */ jsxs("g", { className: fillElementFill, strokeWidth: 0, children: [
80
+ /* @__PURE__ */ jsxs("g", { "data-likec4-fill": "fill", strokeWidth: 0, children: [
81
81
  /* @__PURE__ */ jsx("circle", { cx: 16, cy: 17, r: 7 }),
82
82
  /* @__PURE__ */ jsx("circle", { cx: 36, cy: 17, r: 7 }),
83
83
  /* @__PURE__ */ jsx("circle", { cx: 56, cy: 17, r: 7 }),
@@ -105,7 +105,7 @@ function ElementShapeSvg({ shape, w, h }) {
105
105
  width: PersonIcon.width,
106
106
  height: PersonIcon.height,
107
107
  viewBox: `0 0 ${PersonIcon.width} ${PersonIcon.height}`,
108
- className: fillMixStroke,
108
+ "data-likec4-fill": "mix-stroke",
109
109
  children: /* @__PURE__ */ jsx(
110
110
  "path",
111
111
  {
@@ -121,7 +121,7 @@ function ElementShapeSvg({ shape, w, h }) {
121
121
  const { path, rx, ry } = queueSVGPath(w, h);
122
122
  return /* @__PURE__ */ jsxs(Fragment, { children: [
123
123
  /* @__PURE__ */ jsx("path", { d: path, strokeWidth: 2 }),
124
- /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: ry, ry: ry - 0.75, rx, className: fillMixStroke, strokeWidth: 2 })
124
+ /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: ry, ry: ry - 0.75, rx, "data-likec4-fill": "mix-stroke", strokeWidth: 2 })
125
125
  ] });
126
126
  }
127
127
  case "storage":
@@ -129,7 +129,7 @@ function ElementShapeSvg({ shape, w, h }) {
129
129
  const { path, rx, ry } = cylinderSVGPath(w, h);
130
130
  return /* @__PURE__ */ jsxs(Fragment, { children: [
131
131
  /* @__PURE__ */ jsx("path", { d: path, strokeWidth: 2 }),
132
- /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: ry, ry, rx: rx - 0.75, className: fillMixStroke, strokeWidth: 2 })
132
+ /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: ry, ry, rx: rx - 0.75, "data-likec4-fill": "mix-stroke", strokeWidth: 2 })
133
133
  ] });
134
134
  }
135
135
  case "rectangle": {
@@ -148,15 +148,35 @@ function ElementShapeSvg({ shape, w, h }) {
148
148
  }
149
149
  }
150
150
  }
151
+ function ShapeHtml({ multiple, withOutLine }) {
152
+ return /* @__PURE__ */ jsxs(
153
+ Box,
154
+ {
155
+ className: elementShapeRecipe({
156
+ shapetype: "html"
157
+ }),
158
+ children: [
159
+ multiple && /* @__PURE__ */ jsx("div", { className: "likec4-shape-multiple" }),
160
+ withOutLine && /* @__PURE__ */ jsx("div", { className: "likec4-shape-outline" })
161
+ ]
162
+ }
163
+ );
164
+ }
151
165
  function ElementShape({ data, width, height, withSelectedIndicator = true }) {
152
166
  let w = !!width && width > 10 ? width : data.width;
153
167
  let h = !!height && height > 10 ? height : data.height;
154
168
  const isMultiple = data.style?.multiple ?? false;
169
+ if (data.shape === "rectangle") {
170
+ return /* @__PURE__ */ jsx(ShapeHtml, { multiple: isMultiple, withOutLine: withSelectedIndicator });
171
+ }
172
+ const className = elementShapeRecipe({
173
+ shapetype: "svg"
174
+ });
155
175
  return /* @__PURE__ */ jsxs(Fragment, { children: [
156
- isMultiple && /* @__PURE__ */ jsx("svg", { className: cx(shapeSvgMultiple), viewBox: `0 0 ${w} ${h}`, children: /* @__PURE__ */ jsx(ElementShapeSvg, { shape: data.shape, w, h }) }),
157
- /* @__PURE__ */ jsxs("svg", { className: shapeSvg, viewBox: `0 0 ${w} ${h}`, children: [
176
+ isMultiple && /* @__PURE__ */ jsx("svg", { className, "data-likec4-shape-multiple": "true", viewBox: `0 0 ${w} ${h}`, children: /* @__PURE__ */ jsx(ShapeSvg, { shape: data.shape, w, h }) }),
177
+ /* @__PURE__ */ jsxs("svg", { className, viewBox: `0 0 ${w} ${h}`, children: [
158
178
  withSelectedIndicator && /* @__PURE__ */ jsx(SelectedIndicator, { shape: data.shape, w, h }),
159
- /* @__PURE__ */ jsx(ElementShapeSvg, { shape: data.shape, w, h })
179
+ /* @__PURE__ */ jsx(ShapeSvg, { shape: data.shape, w, h })
160
180
  ] })
161
181
  ] });
162
182
  }
@@ -185,7 +205,7 @@ function SelectedIndicator({ shape, w, h }) {
185
205
  break;
186
206
  }
187
207
  }
188
- return /* @__PURE__ */ jsx("g", { className: indicator, children: svg });
208
+ return /* @__PURE__ */ jsx("g", { className: "likec4-shape-outline", children: svg });
189
209
  }
190
210
 
191
211
  export { ElementShape, SelectedIndicator, cylinderSVGPath };
@@ -14,7 +14,7 @@ import { useCurrentZoom } from '../../../hooks/useXYFlow.js';
14
14
  import { stopPropagation } from '../../../utils/xyflow.js';
15
15
 
16
16
  const ElementTag = forwardRef(
17
- ({ tag, cursor = "default", className, ...props }, ref) => {
17
+ ({ tag, cursor, className, style, ...props }, ref) => {
18
18
  const spec = useTagSpecification(tag);
19
19
  return /* @__PURE__ */ jsxs(
20
20
  Box,
@@ -28,7 +28,10 @@ const ElementTag = forwardRef(
28
28
  className
29
29
  ),
30
30
  ...props,
31
- style: { cursor },
31
+ style: {
32
+ cursor,
33
+ ...style
34
+ },
32
35
  children: [
33
36
  /* @__PURE__ */ jsx("span", { children: "#" }),
34
37
  /* @__PURE__ */ jsx("span", { children: tag })
@@ -107,7 +110,7 @@ const ElementTags = memo(({ id, data: { tags, width, hovered = false } }) => {
107
110
  "data-likec4-tag": tag,
108
111
  className: css({
109
112
  layerStyle: "likec4.tag",
110
- flex: 1,
113
+ flex: "1",
111
114
  display: "flex",
112
115
  alignItems: "center",
113
116
  justifyContent: "center",
@@ -142,9 +145,9 @@ const ElementTags = memo(({ id, data: { tags, width, hovered = false } }) => {
142
145
  ElementTag,
143
146
  {
144
147
  tag,
148
+ cursor: "pointer",
145
149
  className: css({
146
150
  userSelect: "none",
147
- cursor: "pointer",
148
151
  ...zoomIsLargeEnough && {
149
152
  fontSize: "lg",
150
153
  borderRadius: "[4px]",
@@ -56,7 +56,7 @@ function ElementTitle({ id, data, iconSize }) {
56
56
  children: data.technology
57
57
  }
58
58
  ),
59
- data.description && /* @__PURE__ */ jsx(
59
+ data.description?.nonEmpty && (data.description.isMarkdown ? /* @__PURE__ */ jsx(
60
60
  MarkdownBlock,
61
61
  {
62
62
  className: cx(classes.description, "likec4-element-description"),
@@ -66,7 +66,15 @@ function ElementTitle({ id, data, iconSize }) {
66
66
  maxHeight: data.description.isMarkdown ? "8rem" : void 0,
67
67
  lineClamp: isSmOrXs ? 3 : 5
68
68
  }
69
- )
69
+ ) : /* @__PURE__ */ jsx(
70
+ Text,
71
+ {
72
+ component: "div",
73
+ className: cx(classes.description, "likec4-element-description"),
74
+ lineClamp: isSmOrXs ? 3 : 5,
75
+ children: data.description.text
76
+ }
77
+ ))
70
78
  ] })
71
79
  ]
72
80
  }
@@ -2,25 +2,21 @@ import { Edge as RFEdge, EdgeProps as ReactFlowEdgeProps, Node as RFNode, NodePr
2
2
  import { OptionalKeysOf, SetRequired, Simplify } from 'type-fest';
3
3
  import * as Base from './types.Base';
4
4
  /**
5
-
6
- To cooperate with `exactOptionalPropertyTypes` in `tsconfig.json`
7
-
8
- @example
9
- ```
10
- interface User {
11
- name: string;
12
- surname?: string;
13
- luckyNumber?: number;
14
- }
15
-
16
- type NonOptionalUser = NonOptional<User>
17
-
18
- // NonOptionalUser = {
19
- // name: string
20
- // surname: string | undefined
21
- // luckyNumber: number | undefined
22
- // }
23
- ```
5
+ * To cooperate with `exactOptionalPropertyTypes` in `tsconfig.json`
6
+ *
7
+ * @example
8
+ * interface User {
9
+ * name: string;
10
+ * surname?: string;
11
+ * luckyNumber?: number;
12
+ * }
13
+ *
14
+ * type NonOptionalUser = NonOptional<User>
15
+ * // NonOptionalUser = {
16
+ * // name: string
17
+ * // surname: string | undefined
18
+ * // luckyNumber: number | undefined
19
+ * // }
24
20
  */
25
21
  export type NonOptional<T extends object, Keys extends OptionalKeysOf<T> = OptionalKeysOf<T>> = Simplify<{
26
22
  [P in Exclude<keyof T, Keys>]: T[P];
@@ -30,11 +26,11 @@ export type NonOptional<T extends object, Keys extends OptionalKeysOf<T> = Optio
30
26
  /**
31
27
  * ReactFlow Custom Node properties with BaseNodeData at least
32
28
  */
33
- export type NodeProps<T extends Record<string, unknown> = {}, NodeType extends string = string> = ReactFlowNodeProps<RFNode<Base.NodeData & T, NodeType>>;
29
+ export type NodeProps<T extends Record<string, unknown> = {}, NodeType extends string = string> = Simplify<ReactFlowNodeProps<RFNode<Base.NodeData & T, NodeType>>>;
34
30
  /**
35
31
  * ReactFlow Custom Edge properties with BaseEdgeData at least
36
32
  */
37
- export type EdgeProps<T extends Record<string, unknown> = {}> = SetRequired<ReactFlowEdgeProps<RFEdge<Base.EdgeData & T, any>>, 'data'>;
33
+ export type EdgeProps<T extends Record<string, unknown> = {}, EdgeType extends string = string> = SetRequired<Simplify<ReactFlowEdgeProps<RFEdge<Base.EdgeData & T, EdgeType>>>, 'data'>;
38
34
  export type ReactFlowNode<Data extends Record<string, unknown>, NodeType extends string> = SetRequired<RFNode<Data, NodeType>, 'type' | 'initialWidth' | 'initialHeight'>;
39
35
  export type ReactFlowEdge<Data extends Record<string, unknown>, EdgeType extends string> = SetRequired<RFEdge<Data, EdgeType>, 'type' | 'data'>;
40
36
  export * as Base from './types.Base';
@@ -1,3 +1,3 @@
1
- import { aux } from '@likec4/core/types';
1
+ import { Any, UnknownLayouted } from '@likec4/core/types';
2
2
  import { LikeC4ViewProps } from './LikeC4View.props';
3
- export declare function LikeC4View<A extends aux.Any = aux.UnknownLayouted>({ viewId, ...props }: LikeC4ViewProps<A>): import("react/jsx-runtime").JSX.Element;
3
+ export declare function LikeC4View<A extends Any = UnknownLayouted>({ viewId, ...props }: LikeC4ViewProps<A>): import("react/jsx-runtime").JSX.Element;
@@ -129,7 +129,10 @@ const LikeC4ViewInner = memo(({
129
129
  controls,
130
130
  nodesDraggable: false,
131
131
  reduceGraphics,
132
- className: cx(isBrowserEnabled && cssInteractive),
132
+ className: cx(
133
+ "likec4-static-view",
134
+ isBrowserEnabled && cssInteractive
135
+ ),
133
136
  enableSearch: false,
134
137
  ...isBrowserEnabled && {
135
138
  onNavigateTo,
@@ -1,7 +1,7 @@
1
- import { aux, WhereOperator } from '@likec4/core/types';
1
+ import { Any, aux, WhereOperator } from '@likec4/core/types';
2
2
  import { CSSProperties } from 'react';
3
3
  import { CustomNodes, ElementIconRenderer, OverrideReactFlowProps, PaddingWithUnit, ViewPadding } from '../LikeC4Diagram.props';
4
- export interface LikeC4ViewProps<A extends aux.Any> {
4
+ export interface LikeC4ViewProps<A extends Any> {
5
5
  /**
6
6
  * View to display.
7
7
  */
@@ -1,7 +1,7 @@
1
- import { aux } from '@likec4/core/types';
1
+ import { Any, aux, UnknownLayouted } from '@likec4/core/types';
2
2
  import { CSSProperties } from 'react';
3
3
  import { LikeC4DiagramProps } from '../LikeC4Diagram';
4
- export type ReactLikeC4Props<A extends aux.Any> = Omit<LikeC4DiagramProps<A>, 'view'> & {
4
+ export type ReactLikeC4Props<A extends Any> = Omit<LikeC4DiagramProps<A>, 'view'> & {
5
5
  viewId: aux.ViewId<A>;
6
6
  /**
7
7
  * Keep aspect ratio of the diagram
@@ -27,7 +27,7 @@ export type ReactLikeC4Props<A extends aux.Any> = Omit<LikeC4DiagramProps<A>, 'v
27
27
  /** Function to generate nonce attribute added to all generated `<style />` tags */
28
28
  styleNonce?: string | (() => string) | undefined;
29
29
  };
30
- export declare function ReactLikeC4<A extends aux.Any = aux.UnknownLayouted>({ viewId, ...props }: ReactLikeC4Props<A>): import("react/jsx-runtime").JSX.Element;
30
+ export declare function ReactLikeC4<A extends Any = UnknownLayouted>({ viewId, ...props }: ReactLikeC4Props<A>): import("react/jsx-runtime").JSX.Element;
31
31
  export declare namespace ReactLikeC4 {
32
32
  var displayName: string;
33
33
  }
@@ -22,11 +22,12 @@ export { IfEnabled, IfNotEnabled, IfNotReadOnly, IfReadOnly, useEnabledFeatures
22
22
  export { Overlay } from '../overlays/overlay/Overlay.js';
23
23
  export { useDiagramEventHandlers } from '../context/DiagramEventHandlers.js';
24
24
  export { useCurrentViewId } from '../hooks/useCurrentViewId.js';
25
- export { useDiagram, useDiagramContext } from '../hooks/useDiagram.js';
25
+ export { useDiagram, useDiagramContext, useOnDiagramEvent } from '../hooks/useDiagram.js';
26
26
  export { useDiagramActorRef } from '../hooks/safeContext.js';
27
27
  export { useXYFlow, useXYInternalNode, useXYStore, useXYStoreApi } from '../hooks/useXYFlow.js';
28
28
  export { useCurrentViewModel } from '../likec4model/useCurrentViewModel.js';
29
29
  export { useLikeC4Model, useLikeC4Specification, useLikeC4ViewModel } from '../likec4model/useLikeC4Model.js';
30
+ export { useHasProjects, useLikeC4ProjectId, useLikeC4Projects, useLikeC4ProjectsContext } from '../likec4model/useLikeC4Project.js';
30
31
  export { useMantinePortalProps } from '../hooks/useMantinePortalProps.js';
31
32
  export { useSetState } from '../hooks/useSetState.js';
32
33
  export { useUpdateEffect } from '../hooks/useUpdateEffect.js';
@@ -6,11 +6,12 @@ export { ViewNotFound } from './ViewNotFound.js';
6
6
  export { useDiagramEventHandlers } from '../context/DiagramEventHandlers.js';
7
7
  export { useEnabledFeatures } from '../context/DiagramFeatures.js';
8
8
  export { useCurrentViewId } from '../hooks/useCurrentViewId.js';
9
- export { useDiagram, useDiagramContext } from '../hooks/useDiagram.js';
9
+ export { useDiagram, useDiagramContext, useOnDiagramEvent } from '../hooks/useDiagram.js';
10
10
  export { useDiagramActorRef } from '../hooks/safeContext.js';
11
11
  export { useXYFlow, useXYInternalNode, useXYStore, useXYStoreApi } from '../hooks/useXYFlow.js';
12
12
  export { useCurrentViewModel } from '../likec4model/useCurrentViewModel.js';
13
13
  export { useLikeC4Model, useLikeC4Specification, useLikeC4ViewModel } from '../likec4model/useLikeC4Model.js';
14
+ export { useHasProjects, useLikeC4ProjectId, useLikeC4Projects, useLikeC4ProjectsContext } from '../likec4model/useLikeC4Project.js';
14
15
  export { useMantinePortalProps } from '../hooks/useMantinePortalProps.js';
15
16
  export { useSetState } from '../hooks/useSetState.js';
16
17
  export { useUpdateEffect } from '../hooks/useUpdateEffect.js';
@@ -52,8 +52,9 @@ const Link = forwardRef(
52
52
  maxWidth: 500,
53
53
  userSelect: "all",
54
54
  pr: "0",
55
- _hover: {
56
- backgroundColor: {
55
+ backgroundColor: {
56
+ base: "transparent",
57
+ _hover: {
57
58
  base: "mantine.colors.gray[1]",
58
59
  _dark: "mantine.colors.dark[5]"
59
60
  }