@likec4/diagram 1.36.0 → 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.
- package/bundle/{chunk-7MPUJFHj.js → chunk-DSORWspW.js} +1011 -983
- package/bundle/custom.js +64 -56
- package/bundle/index.js +3546 -3321
- package/dist/LikeC4Diagram.props.d.ts +5 -5
- package/dist/LikeC4Styles.js +17 -15
- package/dist/StaticLikeC4Diagram.d.ts +1 -1
- package/dist/StaticLikeC4Diagram.js +3 -0
- package/dist/base/BaseXYFlow.d.ts +1 -1
- package/dist/base/BaseXYFlow.js +25 -27
- package/dist/base/const.d.ts +4 -4
- package/dist/base/const.js +5 -4
- package/dist/base/primitives/MarkdownBlock.js +4 -1
- package/dist/base/primitives/compound/CompoundActionButton.js +27 -42
- package/dist/base/primitives/compound/CompoundDetailsButton.js +23 -48
- package/dist/base/primitives/compound/CompoundNodeContainer.js +16 -48
- package/dist/base/primitives/compound/CompoundTitle.js +5 -80
- package/dist/base/primitives/compound/actionbtns.css.js +1 -13
- package/dist/base/primitives/customEdge.d.ts +1 -1
- package/dist/base/primitives/customNode.d.ts +4 -4
- package/dist/base/primitives/customNode.js +7 -7
- package/dist/base/primitives/edge/EdgeLabel.d.ts +5 -4
- package/dist/base/primitives/edge/EdgeLabel.js +39 -21
- package/dist/base/primitives/edge/EdgeLabelContainer.js +11 -23
- package/dist/base/primitives/edge/edge.css.js +19 -11
- package/dist/base/primitives/element/ElementShape.js +38 -18
- package/dist/base/primitives/element/ElementTags.js +7 -4
- package/dist/base/primitives/element/ElementTitle.js +10 -2
- package/dist/base/types.d.ts +17 -21
- package/dist/bundle/LikeC4View.d.ts +2 -2
- package/dist/bundle/LikeC4View.js +4 -1
- package/dist/bundle/LikeC4View.props.d.ts +2 -2
- package/dist/bundle/ReactLikeC4.d.ts +3 -3
- package/dist/bundle/custom.js +2 -1
- package/dist/bundle/index.js +2 -1
- package/dist/components/Link.js +3 -2
- package/dist/context/ReduceGraphics.js +2 -5
- package/dist/context/RootContainer.js +1 -5
- package/dist/custom/customNodes.d.ts +32 -26
- package/dist/custom/customNodes.js +12 -8
- package/dist/custom/hooks.d.ts +2 -1
- package/dist/custom/index.js +2 -1
- package/dist/globals.css.js +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/useDiagram.d.ts +18 -1
- package/dist/hooks/useDiagram.js +18 -2
- package/dist/hooks/useXYFlow.d.ts +40 -21
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/likec4diagram/DiagramUI.js +7 -3
- package/dist/likec4diagram/DiagramXYFlow.js +9 -9
- package/dist/likec4diagram/custom/edges/RelationshipEdge.d.ts +3 -3
- package/dist/likec4diagram/custom/edges/RelationshipEdge.js +27 -44
- package/dist/likec4diagram/custom/index.js +3 -3
- package/dist/likec4diagram/custom/nodes/nodes.d.ts +8 -6
- package/dist/likec4diagram/custom/nodes/nodes.js +13 -14
- package/dist/likec4diagram/custom/nodes/toolbar/CompoundToolbar.js +3 -2
- package/dist/likec4diagram/custom/nodes/toolbar/_shared.d.ts +2 -2
- package/dist/likec4diagram/relationship-popover/RelationshipPopover.d.ts +2 -0
- package/dist/likec4diagram/relationship-popover/RelationshipPopover.js +441 -0
- package/dist/likec4diagram/relationship-popover/actor.d.ts +177 -0
- package/dist/likec4diagram/relationship-popover/actor.js +155 -0
- package/dist/likec4diagram/relationship-popover/styles.css.d.ts +2 -0
- package/dist/likec4diagram/{custom/edges/RelationshipsDropdownMenu.css.js → relationship-popover/styles.css.js} +4 -17
- package/dist/likec4diagram/ui/diagram-title/DiagramTitlePanel.js +4 -4
- package/dist/likec4diagram/useLayoutConstraints.js +0 -1
- package/dist/likec4model/LikeC4ModelContext.d.ts +2 -1
- package/dist/likec4model/LikeC4ModelContext.js +10 -2
- package/dist/likec4model/useCurrentViewModel.d.ts +1 -0
- package/dist/likec4model/useCurrentViewModel.js +4 -1
- package/dist/likec4model/useLikeC4ElementsTree.js +1 -1
- package/dist/likec4model/useLikeC4Project.js +15 -1
- package/dist/navigationpanel/NavigationPanelDropdown.js +1 -2
- package/dist/navigationpanel/actor.js +1 -2
- package/dist/navigationpanel/controls/NavigationButtons.js +1 -5
- package/dist/navigationpanel/controls/OpenSource.js +1 -1
- package/dist/navigationpanel/controls/ViewDetailsCard.js +2 -0
- package/dist/overlays/element-details/actor.d.ts +564 -8
- package/dist/overlays/overlay/Overlay.css.d.ts +1 -1
- package/dist/overlays/relationship-details/actor.d.ts +3 -1
- package/dist/overlays/relationship-details/hooks.d.ts +19 -1
- package/dist/overlays/relationship-details/layout-to-xyflow.js +0 -1
- package/dist/overlays/relationship-details/layout.js +1 -2
- package/dist/overlays/relationships-browser/actor.d.ts +26 -2
- package/dist/overlays/relationships-browser/custom/nodeTypes.d.ts +16 -0
- package/dist/overlays/relationships-browser/custom/nodeTypes.js +18 -8
- package/dist/overlays/relationships-browser/useViewToNodesEdges.js +0 -1
- package/dist/search/components/_shared.css.d.ts +1 -1
- package/dist/state/DiagramActorProvider.js +5 -23
- package/dist/state/assign.js +24 -10
- package/dist/state/diagram-machine.d.ts +149 -474
- package/dist/state/diagram-machine.js +94 -54
- package/dist/state/types.d.ts +1 -1
- package/dist/styles-min.css +1 -1
- package/dist/styles-xyflow.css +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.css2.js +1 -1
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/roundDpr.d.ts +1 -0
- package/dist/utils/roundDpr.js +20 -0
- package/dist/utils/xyflow.d.ts +0 -1
- package/dist/utils/xyflow.js +1 -7
- package/package.json +11 -10
- package/panda.buildinfo.json +90 -155
- package/src/LikeC4Diagram.props.ts +5 -5
- package/src/LikeC4Styles.tsx +22 -14
- package/src/StaticLikeC4Diagram.tsx +3 -0
- package/src/base/BaseXYFlow.tsx +26 -29
- package/src/base/const.ts +5 -4
- package/src/base/primitives/MarkdownBlock.tsx +6 -1
- package/src/base/primitives/compound/CompoundActionButton.tsx +31 -43
- package/src/base/primitives/compound/CompoundDetailsButton.tsx +26 -48
- package/src/base/primitives/compound/CompoundNodeContainer.tsx +15 -43
- package/src/base/primitives/compound/CompoundTitle.tsx +4 -76
- package/src/base/primitives/compound/actionbtns.css.ts +0 -12
- package/src/base/primitives/customEdge.ts +1 -1
- package/src/base/primitives/customNode.tsx +20 -24
- package/src/base/primitives/edge/EdgeLabel.tsx +23 -8
- package/src/base/primitives/edge/EdgeLabelContainer.tsx +9 -21
- package/src/base/primitives/edge/edge.css.ts +19 -11
- package/src/base/primitives/element/ElementShape.tsx +40 -18
- package/src/base/primitives/element/ElementTags.tsx +7 -4
- package/src/base/primitives/element/ElementTitle.tsx +23 -11
- package/src/base/types.ts +21 -25
- package/src/bundle/LikeC4View.props.ts +2 -2
- package/src/bundle/LikeC4View.tsx +8 -5
- package/src/bundle/ReactLikeC4.tsx +3 -3
- package/src/components/Link.tsx +3 -2
- package/src/context/RootContainer.tsx +1 -5
- package/src/context/TagStylesContext.tsx +2 -0
- package/src/custom/{customNodes.tsx → customNodes.ts} +58 -52
- package/src/custom/hooks.ts +7 -0
- package/src/globals.css +58 -5
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useDiagram.ts +39 -5
- package/src/hooks/useXYFlow.ts +3 -1
- package/src/index.ts +1 -0
- package/src/likec4diagram/DiagramUI.tsx +11 -2
- package/src/likec4diagram/DiagramXYFlow.tsx +9 -11
- package/src/likec4diagram/custom/edges/RelationshipEdge.tsx +25 -49
- package/src/likec4diagram/custom/index.ts +5 -4
- package/src/likec4diagram/custom/nodes/nodes.tsx +13 -11
- package/src/likec4diagram/custom/nodes/toolbar/CompoundToolbar.tsx +3 -2
- package/src/likec4diagram/relationship-popover/RelationshipPopover.tsx +535 -0
- package/src/likec4diagram/relationship-popover/actor.ts +192 -0
- package/src/likec4diagram/{custom/edges/RelationshipsDropdownMenu.css.ts → relationship-popover/styles.css.ts} +3 -19
- package/src/likec4diagram/ui/diagram-title/DiagramTitlePanel.tsx +4 -5
- package/src/likec4diagram/useLayoutConstraints.ts +0 -1
- package/src/likec4model/{LikeC4ModelContext.ts → LikeC4ModelContext.tsx} +9 -1
- package/src/likec4model/useCurrentViewModel.ts +4 -0
- package/src/likec4model/useLikeC4ElementsTree.ts +1 -1
- package/src/navigationpanel/NavigationPanelDropdown.tsx +1 -2
- package/src/navigationpanel/actor.ts +2 -2
- package/src/navigationpanel/controls/NavigationButtons.tsx +1 -5
- package/src/navigationpanel/controls/OpenSource.tsx +1 -1
- package/src/navigationpanel/controls/ViewDetailsCard.tsx +2 -0
- package/src/overlays/relationship-details/layout-to-xyflow.ts +0 -1
- package/src/overlays/relationship-details/layout.ts +4 -3
- package/src/overlays/relationships-browser/custom/nodeTypes.tsx +22 -8
- package/src/overlays/relationships-browser/useViewToNodesEdges.ts +0 -1
- package/src/state/DiagramActorProvider.tsx +8 -25
- package/src/state/assign.ts +24 -10
- package/src/state/diagram-machine.ts +101 -53
- package/src/state/types.ts +4 -1
- package/src/utils/index.ts +2 -1
- package/src/utils/roundDpr.ts +27 -0
- package/src/utils/xyflow.ts +0 -7
- package/dist/base/primitives/compound/CompoundNodeContainer.css.d.ts +0 -35
- package/dist/base/primitives/compound/CompoundNodeContainer.css.js +0 -132
- package/dist/base/primitives/edge/EdgeLabel.css.d.ts +0 -7
- package/dist/base/primitives/edge/EdgeLabel.css.js +0 -57
- package/dist/base/primitives/element/ElementShape.css.d.ts +0 -6
- package/dist/base/primitives/element/ElementShape.css.js +0 -107
- package/dist/likec4diagram/custom/edges/NotePopover.css.js +0 -21
- package/dist/likec4diagram/custom/edges/NotePopover.js +0 -91
- package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.css.d.ts +0 -5
- package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.d.ts +0 -13
- package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.js +0 -215
- package/dist/likec4diagram/custom/index.d.ts +0 -62
- package/dist/overlays/relationship-details/custom/nodeTypes.d.ts +0 -10
- package/src/base/primitives/compound/CompoundNodeContainer.css.ts +0 -138
- package/src/base/primitives/edge/EdgeLabel.css.ts +0 -64
- package/src/base/primitives/element/ElementShape.css.ts +0 -112
- package/src/likec4diagram/custom/edges/RelationshipsDropdownMenu.tsx +0 -281
package/src/base/BaseXYFlow.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { cx } from '@likec4/styles/css'
|
|
2
2
|
import { useCallbackRef } from '@mantine/hooks'
|
|
3
3
|
import {
|
|
4
4
|
type ReactFlowProps,
|
|
@@ -11,6 +11,7 @@ import type { SetRequired, Simplify } from 'type-fest'
|
|
|
11
11
|
import { useUpdateEffect } from '../hooks/useUpdateEffect'
|
|
12
12
|
import { useIsZoomTooSmall, useXYStoreApi } from '../hooks/useXYFlow'
|
|
13
13
|
import type { ViewPadding } from '../LikeC4Diagram.props'
|
|
14
|
+
import { roundDpr } from '../utils/roundDpr'
|
|
14
15
|
import { stopPropagation } from '../utils/xyflow'
|
|
15
16
|
import { type XYBackground, Background } from './Background'
|
|
16
17
|
import { MaxZoom, MinZoom } from './const'
|
|
@@ -44,29 +45,6 @@ export type BaseXYFlowProps<NodeType extends Base.Node, EdgeType extends Base.Ed
|
|
|
44
45
|
>
|
|
45
46
|
>
|
|
46
47
|
|
|
47
|
-
const cssReactFlow = cva({
|
|
48
|
-
base: {
|
|
49
|
-
'& .react-flow__pane': {
|
|
50
|
-
WebkitUserSelect: 'none',
|
|
51
|
-
},
|
|
52
|
-
'& .react-flow__attribution': {
|
|
53
|
-
display: 'none',
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
variants: {
|
|
57
|
-
transparent: {
|
|
58
|
-
true: {
|
|
59
|
-
background: 'transparent !important',
|
|
60
|
-
['--xy-background-color']: 'transparent !important',
|
|
61
|
-
},
|
|
62
|
-
false: {
|
|
63
|
-
['--xy-background-color']: '{colors.likec4.background}',
|
|
64
|
-
['--xy-background-pattern-color']: '{colors.likec4.background.pattern}',
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
})
|
|
69
|
-
|
|
70
48
|
export const BaseXYFlow = <
|
|
71
49
|
NodeType extends Base.Node,
|
|
72
50
|
EdgeType extends Base.Edge,
|
|
@@ -88,6 +66,10 @@ export const BaseXYFlow = <
|
|
|
88
66
|
zoomOnDoubleClick = false,
|
|
89
67
|
onViewportResize,
|
|
90
68
|
onMoveEnd,
|
|
69
|
+
onNodeMouseEnter,
|
|
70
|
+
onNodeMouseLeave,
|
|
71
|
+
onEdgeMouseEnter,
|
|
72
|
+
onEdgeMouseLeave,
|
|
91
73
|
...props
|
|
92
74
|
}: BaseXYFlowProps<NodeType, EdgeType>) => {
|
|
93
75
|
const isBgWithPattern = background !== 'transparent' && background !== 'solid'
|
|
@@ -100,9 +82,7 @@ export const BaseXYFlow = <
|
|
|
100
82
|
nodes={nodes}
|
|
101
83
|
edges={edges}
|
|
102
84
|
className={cx(
|
|
103
|
-
|
|
104
|
-
transparent: background === 'transparent',
|
|
105
|
-
}),
|
|
85
|
+
background === 'transparent' && 'bg-transparent',
|
|
106
86
|
className,
|
|
107
87
|
)}
|
|
108
88
|
{...isZoomTooSmall && {
|
|
@@ -127,6 +107,7 @@ export const BaseXYFlow = <
|
|
|
127
107
|
defaultMarkerColor="var(--xy-edge-stroke)"
|
|
128
108
|
noDragClassName="nodrag"
|
|
129
109
|
noPanClassName="nopan"
|
|
110
|
+
noWheelClassName="nowheel"
|
|
130
111
|
panOnScroll={pannable}
|
|
131
112
|
panOnDrag={pannable}
|
|
132
113
|
{...(!pannable && {
|
|
@@ -151,14 +132,18 @@ export const BaseXYFlow = <
|
|
|
151
132
|
* https://github.com/xyflow/xyflow/issues/3282
|
|
152
133
|
* https://github.com/likec4/likec4/issues/734
|
|
153
134
|
*/
|
|
154
|
-
const roundedX =
|
|
155
|
-
roundedY =
|
|
135
|
+
const roundedX = roundDpr(x),
|
|
136
|
+
roundedY = roundDpr(y)
|
|
156
137
|
if (x !== roundedX || y !== roundedY) {
|
|
157
138
|
xystore.setState({ transform: [roundedX, roundedY, zoom] })
|
|
158
139
|
}
|
|
159
140
|
onMoveEnd?.(event, { x: roundedX, y: roundedY, zoom })
|
|
160
141
|
})}
|
|
161
142
|
onNodeMouseEnter={useCallbackRef((_event, node) => {
|
|
143
|
+
if (onNodeMouseEnter) {
|
|
144
|
+
onNodeMouseEnter(_event, node)
|
|
145
|
+
return
|
|
146
|
+
}
|
|
162
147
|
if (!node.data.hovered) {
|
|
163
148
|
onNodesChange([{
|
|
164
149
|
id: node.id,
|
|
@@ -168,6 +153,10 @@ export const BaseXYFlow = <
|
|
|
168
153
|
}
|
|
169
154
|
})}
|
|
170
155
|
onNodeMouseLeave={useCallbackRef((_event, node) => {
|
|
156
|
+
if (onNodeMouseLeave) {
|
|
157
|
+
onNodeMouseLeave(_event, node)
|
|
158
|
+
return
|
|
159
|
+
}
|
|
171
160
|
if (node.data.hovered) {
|
|
172
161
|
onNodesChange([{
|
|
173
162
|
id: node.id,
|
|
@@ -177,6 +166,10 @@ export const BaseXYFlow = <
|
|
|
177
166
|
}
|
|
178
167
|
})}
|
|
179
168
|
onEdgeMouseEnter={useCallbackRef((_event, edge) => {
|
|
169
|
+
if (onEdgeMouseEnter) {
|
|
170
|
+
onEdgeMouseEnter(_event, edge)
|
|
171
|
+
return
|
|
172
|
+
}
|
|
180
173
|
if (!edge.data.hovered) {
|
|
181
174
|
onEdgesChange([{
|
|
182
175
|
id: edge.id,
|
|
@@ -186,6 +179,10 @@ export const BaseXYFlow = <
|
|
|
186
179
|
}
|
|
187
180
|
})}
|
|
188
181
|
onEdgeMouseLeave={useCallbackRef((_event, edge) => {
|
|
182
|
+
if (onEdgeMouseLeave) {
|
|
183
|
+
onEdgeMouseLeave(_event, edge)
|
|
184
|
+
return
|
|
185
|
+
}
|
|
189
186
|
if (edge.data.hovered) {
|
|
190
187
|
onEdgesChange([{
|
|
191
188
|
id: edge.id,
|
package/src/base/const.ts
CHANGED
|
@@ -51,7 +51,9 @@ export const MarkdownBlock = forwardRef<HTMLDivElement, MarkdownBlockProps>(({
|
|
|
51
51
|
return null
|
|
52
52
|
}
|
|
53
53
|
const content = value.nonEmpty
|
|
54
|
-
?
|
|
54
|
+
? value.isMarkdown
|
|
55
|
+
? { dangerouslySetInnerHTML: { __html: value.html } }
|
|
56
|
+
: { children: <p>{value.text}</p> }
|
|
55
57
|
: { children: <Text component="span" fz={'xs'} c="dimmed" style={{ userSelect: 'none' }}>{emptyText}</Text> }
|
|
56
58
|
return (
|
|
57
59
|
<Box
|
|
@@ -64,6 +66,9 @@ export const MarkdownBlock = forwardRef<HTMLDivElement, MarkdownBlockProps>(({
|
|
|
64
66
|
className,
|
|
65
67
|
)}
|
|
66
68
|
style={{
|
|
69
|
+
...props.fontSize && {
|
|
70
|
+
'--text-fz': `var(--font-sizes-${props.fontSize}, var(--font-sizes-md))`,
|
|
71
|
+
},
|
|
67
72
|
// @ts-expect-error
|
|
68
73
|
['--mantine-scale']: textScale,
|
|
69
74
|
}}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Box } from '@likec4/styles/jsx'
|
|
1
|
+
import { cx } from '@likec4/styles/css'
|
|
3
2
|
import { actionBtn } from '@likec4/styles/recipes'
|
|
4
3
|
import { ActionIcon } from '@mantine/core'
|
|
5
4
|
import { useDebouncedValue } from '@mantine/hooks'
|
|
@@ -28,47 +27,36 @@ export function CompoundActionButton({
|
|
|
28
27
|
const debounced = useDebouncedValue(isHovered, isHovered ? 130 : 0)
|
|
29
28
|
const isHoverDebounced = debounced[0] && isHovered
|
|
30
29
|
return (
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
30
|
+
<m.div
|
|
31
|
+
initial={false}
|
|
32
|
+
animate={{
|
|
33
|
+
scale: isHoverDebounced ? 1.2 : 1,
|
|
34
|
+
x: isHoverDebounced ? -1 : 0,
|
|
35
|
+
y: isHoverDebounced ? -1 : 0,
|
|
36
|
+
}}
|
|
37
|
+
whileHover={{
|
|
38
|
+
scale: 1.4,
|
|
39
|
+
x: -3,
|
|
40
|
+
y: -1,
|
|
41
|
+
}}
|
|
42
|
+
className="likec4-compound-navigation compound-action"
|
|
43
|
+
whileTap={{ scale: 1 }}
|
|
44
|
+
onClick={stopPropagation}
|
|
45
|
+
>
|
|
46
|
+
<ActionIcon
|
|
47
|
+
className={cx(
|
|
48
|
+
'nodrag nopan',
|
|
49
|
+
compoundActionBtn({
|
|
50
|
+
delay: isHovered && !isHoverDebounced,
|
|
51
|
+
}),
|
|
52
|
+
actionBtn({ variant: 'transparent' }),
|
|
53
|
+
)}
|
|
54
|
+
// Otherwise node receives click event and is selected
|
|
55
|
+
onClick={onClick}
|
|
56
|
+
onDoubleClick={stopPropagation}
|
|
56
57
|
>
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
compoundActionBtn({
|
|
61
|
-
delay: isHovered && !isHoverDebounced,
|
|
62
|
-
}),
|
|
63
|
-
actionBtn(),
|
|
64
|
-
)}
|
|
65
|
-
// Otherwise node receives click event and is selected
|
|
66
|
-
onClick={onClick}
|
|
67
|
-
onDoubleClick={stopPropagation}
|
|
68
|
-
>
|
|
69
|
-
{icon ?? <IconZoomScan stroke={2} />}
|
|
70
|
-
</ActionIcon>
|
|
71
|
-
</m.div>
|
|
72
|
-
</Box>
|
|
58
|
+
{icon ?? <IconZoomScan stroke={2} />}
|
|
59
|
+
</ActionIcon>
|
|
60
|
+
</m.div>
|
|
73
61
|
)
|
|
74
62
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Box } from '@likec4/styles/jsx'
|
|
1
|
+
import { cx } from '@likec4/styles/css'
|
|
3
2
|
import { actionBtn } from '@likec4/styles/recipes'
|
|
4
3
|
import { ActionIcon } from '@mantine/core'
|
|
5
4
|
import { useDebouncedValue } from '@mantine/hooks'
|
|
@@ -28,51 +27,30 @@ export function CompoundDetailsButton({
|
|
|
28
27
|
const debounced = useDebouncedValue(isHovered, isHovered ? 130 : 0)
|
|
29
28
|
const isHoverDebounced = debounced[0] && isHovered
|
|
30
29
|
return (
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
>
|
|
55
|
-
|
|
56
|
-
className={cx(
|
|
57
|
-
'nodrag nopan',
|
|
58
|
-
compoundActionBtn({
|
|
59
|
-
delay: isHovered && !isHoverDebounced,
|
|
60
|
-
}),
|
|
61
|
-
css({
|
|
62
|
-
_whenHovered: {
|
|
63
|
-
opacity: .75,
|
|
64
|
-
},
|
|
65
|
-
_hover: {
|
|
66
|
-
opacity: 1,
|
|
67
|
-
},
|
|
68
|
-
}),
|
|
69
|
-
actionBtn({ variant: 'transparent' }),
|
|
70
|
-
)}
|
|
71
|
-
onClick={onClick}
|
|
72
|
-
onDoubleClick={stopPropagation}>
|
|
73
|
-
{icon ?? <IconId stroke={1.8} style={{ width: '75%' }} />}
|
|
74
|
-
</ActionIcon>
|
|
75
|
-
</m.div>
|
|
76
|
-
</Box>
|
|
30
|
+
<m.div
|
|
31
|
+
initial={false}
|
|
32
|
+
animate={{
|
|
33
|
+
scale: isHoverDebounced ? 1.2 : 1,
|
|
34
|
+
// opacity: isHoverDebounced ? 1 : 0.6,
|
|
35
|
+
}}
|
|
36
|
+
whileHover={{
|
|
37
|
+
scale: 1.4,
|
|
38
|
+
}}
|
|
39
|
+
whileTap={{ scale: 1 }}
|
|
40
|
+
className="likec4-compound-details details-button"
|
|
41
|
+
>
|
|
42
|
+
<ActionIcon
|
|
43
|
+
className={cx(
|
|
44
|
+
'nodrag nopan',
|
|
45
|
+
compoundActionBtn({
|
|
46
|
+
delay: isHovered && !isHoverDebounced,
|
|
47
|
+
}),
|
|
48
|
+
actionBtn({ variant: 'transparent' }),
|
|
49
|
+
)}
|
|
50
|
+
onClick={onClick}
|
|
51
|
+
onDoubleClick={stopPropagation}>
|
|
52
|
+
{icon ?? <IconId stroke={1.8} style={{ width: '75%' }} />}
|
|
53
|
+
</ActionIcon>
|
|
54
|
+
</m.div>
|
|
77
55
|
)
|
|
78
56
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Color, ElementStyle } from '@likec4/core/types'
|
|
2
|
-
import {
|
|
2
|
+
import { cx } from '@likec4/styles/css'
|
|
3
|
+
import { compoundNode } from '@likec4/styles/recipes'
|
|
3
4
|
import { type HTMLMotionProps, m } from 'motion/react'
|
|
4
5
|
import { type PropsWithChildren } from 'react'
|
|
5
|
-
import { clamp
|
|
6
|
-
import { useIsReducedGraphics } from '../../../hooks/useReducedGraphics'
|
|
6
|
+
import { clamp } from 'remeda'
|
|
7
7
|
import type { NodeProps } from '../../types'
|
|
8
|
-
import * as styles from './CompoundNodeContainer.css'
|
|
8
|
+
// import * as styles from './CompoundNodeContainer.css'
|
|
9
9
|
|
|
10
10
|
export type RequiredData = {
|
|
11
11
|
color: Color
|
|
@@ -33,27 +33,24 @@ export function CompoundNodeContainer({
|
|
|
33
33
|
style,
|
|
34
34
|
...rest
|
|
35
35
|
}: CompoundNodeContainerProps) {
|
|
36
|
-
|
|
37
|
-
const isTransparent = isNumber(data.style.opacity) && data.style.opacity < 99
|
|
38
|
-
let opacity = clamp((data.style.opacity ?? 100) / 100, {
|
|
36
|
+
let opacity = clamp(data.style.opacity ?? 100, {
|
|
39
37
|
min: 0,
|
|
40
|
-
max:
|
|
38
|
+
max: 100,
|
|
41
39
|
})
|
|
42
|
-
|
|
43
|
-
opacity = Math.min(opacity + 0.08, 1)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// const [opacity] = useDebouncedValue(Math.round(_opacity * 100) / 100, isHovered ? 200 : 50)
|
|
40
|
+
const isTransparent = opacity < 99
|
|
47
41
|
|
|
48
42
|
const MIN_OPACITY = 65
|
|
49
|
-
const borderOpacity = MIN_OPACITY + clamp((100 - MIN_OPACITY) * opacity, {
|
|
43
|
+
const borderOpacity = MIN_OPACITY + clamp((100 - MIN_OPACITY) * (opacity / 100), {
|
|
50
44
|
min: 0,
|
|
51
45
|
max: 100 - MIN_OPACITY,
|
|
52
46
|
})
|
|
53
47
|
|
|
54
|
-
const
|
|
48
|
+
const compoundClass = compoundNode({
|
|
55
49
|
isTransparent,
|
|
50
|
+
inverseColor: opacity < 60,
|
|
51
|
+
borderStyle: data.style.border ?? (isTransparent ? 'dashed' : 'none'),
|
|
56
52
|
})
|
|
53
|
+
|
|
57
54
|
const depth = clamp(data.depth ?? 1, {
|
|
58
55
|
min: 1,
|
|
59
56
|
max: 5,
|
|
@@ -62,49 +59,24 @@ export function CompoundNodeContainer({
|
|
|
62
59
|
return (
|
|
63
60
|
<m.div
|
|
64
61
|
className={cx(
|
|
65
|
-
|
|
66
|
-
'likec4-compound-node',
|
|
62
|
+
compoundClass,
|
|
67
63
|
className,
|
|
68
64
|
)}
|
|
69
65
|
initial={false}
|
|
70
66
|
data-likec4-hovered={isHovered}
|
|
71
67
|
data-likec4-color={data.color}
|
|
72
68
|
data-compound-depth={depth}
|
|
73
|
-
{...isTransparent && {
|
|
74
|
-
'data-compound-transparent': true,
|
|
75
|
-
'data-compound-title-inverse': opacity < 0.5,
|
|
76
|
-
}}
|
|
77
69
|
{...isDimmed !== false && {
|
|
78
70
|
'data-likec4-dimmed': isDimmed,
|
|
79
71
|
}}
|
|
80
72
|
style={{
|
|
81
73
|
...style,
|
|
82
74
|
// @ts-expect-error
|
|
83
|
-
[
|
|
84
|
-
[
|
|
85
|
-
[styles.borderRadius.var]: `6px`,
|
|
86
|
-
[styles.borderOpacityPercent.var]: `${borderOpacity}%`,
|
|
75
|
+
['--_border-transparency']: `${borderOpacity}%`,
|
|
76
|
+
['--_compound-transparency']: `${opacity}%`,
|
|
87
77
|
}}
|
|
88
78
|
{...rest}
|
|
89
79
|
>
|
|
90
|
-
{isTransparent && data.style.border !== 'none' && (
|
|
91
|
-
<div
|
|
92
|
-
className={classes.compoundBorder}
|
|
93
|
-
style={{
|
|
94
|
-
borderStyle: data.style.border ?? 'dashed',
|
|
95
|
-
}}
|
|
96
|
-
/>
|
|
97
|
-
)}
|
|
98
|
-
<svg className={classes.indicatorSvg}>
|
|
99
|
-
<rect
|
|
100
|
-
className={classes.indicatorRect}
|
|
101
|
-
x={0}
|
|
102
|
-
y={0}
|
|
103
|
-
width={'100%'}
|
|
104
|
-
height={'100%'}
|
|
105
|
-
rx={6}
|
|
106
|
-
/>
|
|
107
|
-
</svg>
|
|
108
80
|
{children}
|
|
109
81
|
</m.div>
|
|
110
82
|
)
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import type { DiagramNode } from '@likec4/core/types'
|
|
2
|
-
import { css, cx } from '@likec4/styles/css'
|
|
3
|
-
import { Box } from '@likec4/styles/jsx'
|
|
4
2
|
import { Text } from '@mantine/core'
|
|
5
3
|
import { IconRenderer } from '../../../context'
|
|
6
4
|
import type { NodeProps } from '../../types'
|
|
@@ -15,72 +13,6 @@ type Data = Pick<
|
|
|
15
13
|
|
|
16
14
|
type CompoundTitleProps = NodeProps<Data>
|
|
17
15
|
|
|
18
|
-
const titleContainer = css({
|
|
19
|
-
position: 'absolute',
|
|
20
|
-
display: 'flex',
|
|
21
|
-
alignItems: 'center',
|
|
22
|
-
gap: '1.5', // 6px
|
|
23
|
-
left: '[14px]',
|
|
24
|
-
top: '[4px]',
|
|
25
|
-
right: '[30px]',
|
|
26
|
-
width: 'auto',
|
|
27
|
-
minHeight: '30px',
|
|
28
|
-
[`:where(.react-flow__node.draggable) &`]: {
|
|
29
|
-
pointerEvents: 'all',
|
|
30
|
-
cursor: 'grab',
|
|
31
|
-
},
|
|
32
|
-
[`.likec4-compound-node:has(.compound-action) &`]: {
|
|
33
|
-
paddingLeft: '[22px]',
|
|
34
|
-
},
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
const titleText = css({
|
|
38
|
-
flex: '1',
|
|
39
|
-
fontFamily: 'likec4.compound',
|
|
40
|
-
fontWeight: 600,
|
|
41
|
-
fontSize: '15px',
|
|
42
|
-
textTransform: 'uppercase',
|
|
43
|
-
letterSpacing: '0.2px',
|
|
44
|
-
color: 'var(--likec4-palette-loContrast)',
|
|
45
|
-
'[data-compound-title-inverse] &': {
|
|
46
|
-
color: {
|
|
47
|
-
base: '[color-mix(in srgb, var(--likec4-palette-loContrast) 60%, var(--likec4-palette-fill))]',
|
|
48
|
-
_light: 'var(--likec4-palette-stroke)',
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
const iconSize = '20px'
|
|
54
|
-
const cssIcon = css({
|
|
55
|
-
flex: `0 0 ${iconSize}`,
|
|
56
|
-
height: `${iconSize}`,
|
|
57
|
-
width: `${iconSize}`,
|
|
58
|
-
display: 'flex',
|
|
59
|
-
alignItems: 'center',
|
|
60
|
-
justifyContent: 'center',
|
|
61
|
-
mixBlendMode: {
|
|
62
|
-
base: 'hard-light',
|
|
63
|
-
_reduceGraphicsOnPan: 'normal',
|
|
64
|
-
},
|
|
65
|
-
[`& svg, & img`]: {
|
|
66
|
-
width: '100%',
|
|
67
|
-
height: 'auto',
|
|
68
|
-
maxHeight: '100%',
|
|
69
|
-
pointerEvents: 'none',
|
|
70
|
-
filter: {
|
|
71
|
-
base: [
|
|
72
|
-
'drop-shadow(0 0 3px rgb(0 0 0 / 12%))',
|
|
73
|
-
'drop-shadow(0 1px 8px rgb(0 0 0 / 8%))',
|
|
74
|
-
'drop-shadow(1px 1px 16px rgb(0 0 0 / 3%))',
|
|
75
|
-
],
|
|
76
|
-
_reduceGraphicsOnPan: 'none',
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
[`& img`]: {
|
|
80
|
-
objectFit: 'contain',
|
|
81
|
-
},
|
|
82
|
-
})
|
|
83
|
-
|
|
84
16
|
export function CompoundTitle({ id, data }: CompoundTitleProps) {
|
|
85
17
|
const elementIcon = IconRenderer({
|
|
86
18
|
element: {
|
|
@@ -88,19 +20,15 @@ export function CompoundTitle({ id, data }: CompoundTitleProps) {
|
|
|
88
20
|
title: data.title,
|
|
89
21
|
icon: data.icon,
|
|
90
22
|
},
|
|
91
|
-
className:
|
|
23
|
+
className: 'likec4-compound-icon',
|
|
92
24
|
})
|
|
93
25
|
|
|
94
26
|
return (
|
|
95
|
-
<
|
|
96
|
-
className={cx(
|
|
97
|
-
titleContainer,
|
|
98
|
-
'likec4-compound-title',
|
|
99
|
-
)}>
|
|
27
|
+
<div className={'likec4-compound-title-container'}>
|
|
100
28
|
{elementIcon}
|
|
101
|
-
<Text className={
|
|
29
|
+
<Text component="h3" className={'likec4-compound-title'} truncate="end">
|
|
102
30
|
{data.title}
|
|
103
31
|
</Text>
|
|
104
|
-
</
|
|
32
|
+
</div>
|
|
105
33
|
)
|
|
106
34
|
}
|
|
@@ -3,18 +3,6 @@ import { cva } from '@likec4/styles/css'
|
|
|
3
3
|
export const compoundActionBtn = cva({
|
|
4
4
|
base: {
|
|
5
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
|
-
},
|
|
18
6
|
},
|
|
19
7
|
variants: {
|
|
20
8
|
delay: {
|
|
@@ -27,7 +27,7 @@ export const edgePropsEqual = <P extends Record<string, unknown> = Base.EdgeData
|
|
|
27
27
|
&& eq(prev.data, next.data)
|
|
28
28
|
)
|
|
29
29
|
|
|
30
|
-
export function customEdge<P extends Record<string, unknown> = Base.
|
|
30
|
+
export function customEdge<P extends Record<string, unknown> = Base.EdgeData>(
|
|
31
31
|
Edge: FunctionComponent<EdgeProps<P>>,
|
|
32
32
|
): FunctionComponent<EdgeProps<P>> {
|
|
33
33
|
return memo(Edge, edgePropsEqual)
|
|
@@ -1,33 +1,29 @@
|
|
|
1
1
|
import { deepEqual as eq } from 'fast-equals'
|
|
2
2
|
import { type FunctionComponent, memo } from 'react'
|
|
3
|
-
import type {
|
|
4
|
-
import { DefaultHandles } from './NodeHandles'
|
|
3
|
+
import type { NodeProps } from '../types'
|
|
5
4
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
)
|
|
5
|
+
export function nodePropsEqual<P extends NodeProps<any, any>>(prev: P, next: P) {
|
|
6
|
+
return (
|
|
7
|
+
prev.id === next.id
|
|
8
|
+
&& eq(prev.selected ?? false, next.selected ?? false)
|
|
9
|
+
&& eq(prev.dragging ?? false, next.dragging ?? false)
|
|
10
|
+
&& eq(prev.width ?? 0, next.width ?? 0)
|
|
11
|
+
&& eq(prev.height ?? 0, next.height ?? 0)
|
|
12
|
+
&& eq(prev.zIndex ?? 0, next.zIndex ?? 0)
|
|
13
|
+
// we can ignore position, as custom nodes positioned relative to it's NodeRenderer
|
|
14
|
+
// && eq(prev.positionAbsoluteX, next.positionAbsoluteX)
|
|
15
|
+
// && eq(prev.positionAbsoluteY, next.positionAbsoluteY)
|
|
16
|
+
&& eq(prev.data, next.data)
|
|
17
|
+
)
|
|
18
|
+
}
|
|
21
19
|
|
|
22
20
|
export function customNode<P extends Record<string, unknown> = {}, NodeType extends string = string>(
|
|
23
21
|
Node: FunctionComponent<NodeProps<P, NodeType>>,
|
|
24
|
-
) {
|
|
25
|
-
const NodeComponent = memo(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
</>
|
|
30
|
-
), nodePropsEqual)
|
|
22
|
+
): FunctionComponent<NodeProps<P, NodeType>> {
|
|
23
|
+
const NodeComponent = memo(
|
|
24
|
+
Node,
|
|
25
|
+
(prev, next) => nodePropsEqual(prev as NodeProps, next as NodeProps),
|
|
26
|
+
)
|
|
31
27
|
NodeComponent.displayName = 'Node'
|
|
32
28
|
return NodeComponent
|
|
33
29
|
}
|