@likec4/diagram 1.5.0 → 1.6.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/LICENSE +1 -1
- package/dist/LikeC4Diagram.d.ts +1 -1
- package/dist/LikeC4Diagram.props.d.ts +18 -3
- package/dist/StaticLikeC4Diagram.d.ts +1 -1
- package/dist/index.mjs +3097 -3090
- package/dist/state/DiagramContext.d.ts +18 -9
- package/dist/state/diagramStore.d.ts +12 -2
- package/dist/style.css +149 -85
- package/dist/xyflow/nodes/element/ElementShapeSvg.d.ts +5 -0
- package/dist/xyflow/nodes/element/element.css.d.ts +4 -2
- package/package.json +13 -13
- package/src/LikeC4Diagram.props.ts +21 -3
- package/src/LikeC4Diagram.tsx +4 -1
- package/src/StaticLikeC4Diagram.tsx +1 -0
- package/src/state/DiagramContext.tsx +1 -1
- package/src/state/diagramStore.ts +8 -1
- package/src/ui/BackwardForwardPanel.tsx +1 -1
- package/src/xyflow/FitviewOnDiagramChange.tsx +1 -1
- package/src/xyflow/SelectEdgesOnNodeFocus.tsx +1 -1
- package/src/xyflow/SyncWithDiagram.tsx +1 -1
- package/src/xyflow/XYFlow.tsx +2 -1
- package/src/xyflow/XYFlowEvents.tsx +1 -1
- package/src/xyflow/XYFlowInner.tsx +1 -1
- package/src/xyflow/edges/RelationshipEdge.tsx +3 -3
- package/src/xyflow/edges/edges.css.ts +6 -6
- package/src/xyflow/hooks/useLayoutConstraints.ts +1 -1
- package/src/xyflow/nodes/compound/CompoundNode.tsx +1 -1
- package/src/xyflow/nodes/element/ElementLink.tsx +2 -1
- package/src/xyflow/nodes/element/ElementNode.tsx +70 -22
- package/src/xyflow/nodes/element/ElementShapeSvg.tsx +2 -2
- package/src/xyflow/nodes/element/element.css.ts +126 -54
- package/src/xyflow/nodes/shared/NavigateToBtn.tsx +1 -1
- package/dist/xyflow/nodes/element/ElementIcon.d.ts +0 -7
- package/src/xyflow/nodes/element/ElementIcon.tsx +0 -33
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import { rem } from '@mantine/core'
|
|
2
2
|
import { createVar, fallbackVar, globalStyle, keyframes, style } from '@vanilla-extract/css'
|
|
3
|
-
import { calc } from '@vanilla-extract/css-utils'
|
|
4
3
|
import { mantine } from '../../../mantine.css'
|
|
5
4
|
import { vars } from '../../../theme.css'
|
|
6
5
|
|
|
7
6
|
export const stokeFillMix = createVar('stroke-fill-mix')
|
|
8
|
-
const elPadding = createVar('el-padding')
|
|
9
|
-
// assignVars
|
|
10
7
|
|
|
11
8
|
export const container = style({
|
|
12
9
|
width: '100%',
|
|
13
10
|
height: '100%',
|
|
14
11
|
padding: 0,
|
|
15
12
|
margin: 0,
|
|
13
|
+
flex: '1',
|
|
16
14
|
display: 'flex',
|
|
17
|
-
alignItems: '
|
|
15
|
+
alignItems: 'center',
|
|
16
|
+
justifyContent: 'center',
|
|
18
17
|
vars: {
|
|
19
18
|
[stokeFillMix]: `color-mix(in srgb, ${vars.element.stroke} 90%, ${vars.element.fill})`
|
|
20
19
|
},
|
|
@@ -50,10 +49,10 @@ globalStyle(`.react-flow__node-element:has(${dimmed})`, {
|
|
|
50
49
|
|
|
51
50
|
const indicatorKeyframes = keyframes({
|
|
52
51
|
'from': {
|
|
53
|
-
|
|
52
|
+
strokeOpacity: 0.8
|
|
54
53
|
},
|
|
55
54
|
'to': {
|
|
56
|
-
|
|
55
|
+
strokeOpacity: 0.5
|
|
57
56
|
}
|
|
58
57
|
})
|
|
59
58
|
|
|
@@ -70,10 +69,10 @@ export const indicator = style({
|
|
|
70
69
|
fill: 'none',
|
|
71
70
|
transformOrigin: 'center center',
|
|
72
71
|
strokeWidth: 6,
|
|
73
|
-
animationDuration: '
|
|
72
|
+
animationDuration: '1s',
|
|
74
73
|
animationIterationCount: 'infinite',
|
|
75
74
|
animationDirection: 'alternate',
|
|
76
|
-
|
|
75
|
+
strokeOpacity: 0.8,
|
|
77
76
|
visibility: 'hidden',
|
|
78
77
|
vars: {
|
|
79
78
|
[indicatorStroke]: vars.element.loContrast
|
|
@@ -93,7 +92,7 @@ export const indicator = style({
|
|
|
93
92
|
},
|
|
94
93
|
[`:where([data-mantine-color-scheme='light']) &`]: {
|
|
95
94
|
vars: {
|
|
96
|
-
[indicatorStroke]: `color-mix(in srgb, ${vars.element.fill}
|
|
95
|
+
[indicatorStroke]: `color-mix(in srgb, ${vars.element.fill} 50%, #3c3c3c)`
|
|
97
96
|
}
|
|
98
97
|
},
|
|
99
98
|
[`${dimmed} &`]: {
|
|
@@ -115,15 +114,20 @@ export const fillMixStroke = style({
|
|
|
115
114
|
fill: stokeFillMix
|
|
116
115
|
})
|
|
117
116
|
|
|
117
|
+
export const hasIcon = style({})
|
|
118
|
+
|
|
119
|
+
const textAlign = createVar('text-align')
|
|
120
|
+
const iconSize = createVar('icon-size')
|
|
121
|
+
|
|
118
122
|
export const title = style({
|
|
119
123
|
flex: '0 0 auto',
|
|
120
124
|
fontFamily: vars.element.font,
|
|
121
125
|
fontOpticalSizing: 'auto',
|
|
122
126
|
fontStyle: 'normal',
|
|
123
|
-
textAlign:
|
|
127
|
+
textAlign: textAlign,
|
|
124
128
|
fontWeight: 500,
|
|
125
|
-
fontSize:
|
|
126
|
-
lineHeight: 1.
|
|
129
|
+
fontSize: 19,
|
|
130
|
+
lineHeight: 1.15,
|
|
127
131
|
textWrap: 'balance',
|
|
128
132
|
color: vars.element.hiContrast
|
|
129
133
|
})
|
|
@@ -134,14 +138,19 @@ export const description = style({
|
|
|
134
138
|
fontOpticalSizing: 'auto',
|
|
135
139
|
fontStyle: 'normal',
|
|
136
140
|
fontWeight: 400,
|
|
137
|
-
fontSize:
|
|
138
|
-
lineHeight: 1.
|
|
139
|
-
textAlign:
|
|
141
|
+
fontSize: 14,
|
|
142
|
+
lineHeight: 1.2,
|
|
143
|
+
textAlign: textAlign,
|
|
140
144
|
textWrap: 'pretty',
|
|
141
145
|
color: vars.element.loContrast,
|
|
142
146
|
whiteSpaceCollapse: 'preserve-breaks',
|
|
143
147
|
textOverflow: 'ellipsis',
|
|
144
|
-
overflow: 'hidden'
|
|
148
|
+
overflow: 'hidden',
|
|
149
|
+
selectors: {
|
|
150
|
+
[`:where(${hasIcon}) &`]: {
|
|
151
|
+
textWrap: 'wrap'
|
|
152
|
+
}
|
|
153
|
+
}
|
|
145
154
|
})
|
|
146
155
|
|
|
147
156
|
export const technology = style({
|
|
@@ -150,9 +159,9 @@ export const technology = style({
|
|
|
150
159
|
fontOpticalSizing: 'auto',
|
|
151
160
|
fontStyle: 'normal',
|
|
152
161
|
fontWeight: 400,
|
|
153
|
-
fontSize:
|
|
162
|
+
fontSize: 12,
|
|
154
163
|
lineHeight: 1.125,
|
|
155
|
-
textAlign:
|
|
164
|
+
textAlign: textAlign,
|
|
156
165
|
textWrap: 'balance',
|
|
157
166
|
opacity: 0.92,
|
|
158
167
|
color: vars.element.loContrast,
|
|
@@ -163,68 +172,131 @@ export const technology = style({
|
|
|
163
172
|
}
|
|
164
173
|
})
|
|
165
174
|
|
|
166
|
-
export const
|
|
175
|
+
export const elementDataContainer = style({
|
|
167
176
|
flex: '1',
|
|
168
|
-
|
|
177
|
+
height: 'fit-content',
|
|
169
178
|
display: 'flex',
|
|
170
|
-
|
|
171
|
-
alignItems: 'stretch',
|
|
179
|
+
alignItems: 'center',
|
|
172
180
|
justifyContent: 'center',
|
|
181
|
+
flexDirection: 'row',
|
|
182
|
+
padding: rem(24),
|
|
173
183
|
overflow: 'hidden',
|
|
174
|
-
gap: rem(
|
|
175
|
-
|
|
176
|
-
[
|
|
184
|
+
gap: rem(10),
|
|
185
|
+
vars: {
|
|
186
|
+
[iconSize]: '48px'
|
|
177
187
|
},
|
|
178
188
|
selectors: {
|
|
179
|
-
[`&:has(${description}):has(${technology})`]: {
|
|
180
|
-
gap: rem(6)
|
|
181
|
-
},
|
|
182
189
|
':where([data-likec4-shape="queue"], [data-likec4-shape="mobile"]) &': {
|
|
183
|
-
paddingLeft:
|
|
184
|
-
paddingRight:
|
|
190
|
+
paddingLeft: 40,
|
|
191
|
+
paddingRight: 20
|
|
185
192
|
},
|
|
186
193
|
':where([data-likec4-shape="cylinder"], [data-likec4-shape="storage"]) &': {
|
|
187
|
-
paddingTop:
|
|
194
|
+
paddingTop: 30
|
|
188
195
|
},
|
|
189
196
|
':where([data-likec4-shape="browser"]) &': {
|
|
190
|
-
paddingTop:
|
|
191
|
-
paddingBottom:
|
|
197
|
+
paddingTop: 32,
|
|
198
|
+
paddingBottom: 28
|
|
199
|
+
},
|
|
200
|
+
[`&:is(${hasIcon})`]: {
|
|
201
|
+
paddingRight: 20
|
|
202
|
+
},
|
|
203
|
+
[`${container}:not(:is([data-likec4-shape="queue"],[data-likec4-shape="mobile"])) &:is(${hasIcon})`]: {
|
|
204
|
+
paddingLeft: 20
|
|
205
|
+
},
|
|
206
|
+
[`&:has(${description}, ${technology})`]: {
|
|
207
|
+
alignItems: 'flex-start',
|
|
208
|
+
gap: rem(16),
|
|
209
|
+
vars: {
|
|
210
|
+
[iconSize]: '60px'
|
|
211
|
+
}
|
|
192
212
|
}
|
|
193
213
|
}
|
|
194
214
|
})
|
|
195
215
|
|
|
196
|
-
export const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
overflow: 'visible',
|
|
207
|
-
mixBlendMode: 'hard-light',
|
|
216
|
+
export const elementTextData = style({
|
|
217
|
+
height: 'fit-content',
|
|
218
|
+
width: 'max-content',
|
|
219
|
+
display: 'flex',
|
|
220
|
+
flexDirection: 'column',
|
|
221
|
+
alignItems: 'stretch',
|
|
222
|
+
justifyContent: 'center',
|
|
223
|
+
flexWrap: 'nowrap',
|
|
224
|
+
overflow: 'hidden',
|
|
225
|
+
gap: rem(8),
|
|
208
226
|
'vars': {
|
|
209
|
-
[
|
|
227
|
+
[textAlign]: 'center'
|
|
228
|
+
},
|
|
229
|
+
selectors: {
|
|
230
|
+
[`&:has(${description}):has(${technology})`]: {
|
|
231
|
+
gap: rem(6)
|
|
232
|
+
},
|
|
233
|
+
[`:where(${hasIcon}) &`]: {
|
|
234
|
+
minWidth: 'calc(100% - 160px)',
|
|
235
|
+
alignItems: 'flex-start',
|
|
236
|
+
'vars': {
|
|
237
|
+
[textAlign]: 'left'
|
|
238
|
+
}
|
|
239
|
+
}
|
|
210
240
|
}
|
|
211
241
|
})
|
|
212
242
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
243
|
+
export const elementIcon = style({
|
|
244
|
+
flex: `0 0 ${iconSize}`,
|
|
245
|
+
height: iconSize,
|
|
246
|
+
width: iconSize,
|
|
247
|
+
display: 'flex',
|
|
248
|
+
alignItems: 'center',
|
|
249
|
+
justifyContent: 'center',
|
|
250
|
+
mixBlendMode: 'hard-light'
|
|
251
|
+
})
|
|
252
|
+
globalStyle(`${elementIcon} svg, ${elementIcon} img`, {
|
|
217
253
|
width: '100%',
|
|
218
254
|
height: 'auto',
|
|
219
|
-
|
|
220
|
-
|
|
255
|
+
maxHeight: '100%',
|
|
256
|
+
pointerEvents: 'none',
|
|
257
|
+
filter: `
|
|
258
|
+
drop-shadow(0 0 3px rgb(0 0 0 / 12%))
|
|
259
|
+
drop-shadow(0 1px 8px rgb(0 0 0 / 8%))
|
|
260
|
+
drop-shadow(1px 1px 16px rgb(0 0 0 / 3%))
|
|
261
|
+
`
|
|
262
|
+
})
|
|
263
|
+
globalStyle(`${elementIcon} img`, {
|
|
264
|
+
objectFit: 'contain'
|
|
221
265
|
})
|
|
222
266
|
|
|
223
267
|
const filterShadow = createVar('filter-shadow')
|
|
224
268
|
|
|
269
|
+
export const cssShapeSvgMultiple = style({
|
|
270
|
+
top: 0,
|
|
271
|
+
left: 0,
|
|
272
|
+
position: 'absolute',
|
|
273
|
+
pointerEvents: 'none',
|
|
274
|
+
transformOrigin: '50% 50%',
|
|
275
|
+
fill: vars.element.fill,
|
|
276
|
+
stroke: 'none',
|
|
277
|
+
zIndex: -1,
|
|
278
|
+
transition: 'opacity 500ms ease-out',
|
|
279
|
+
transform: 'translate(8px,10px)',
|
|
280
|
+
opacity: 0.5,
|
|
281
|
+
selectors: {
|
|
282
|
+
[`:where(.react-flow__node.selected, .react-flow__node:focus-visible, ${container}:focus-visible) &`]: {
|
|
283
|
+
visibility: 'hidden'
|
|
284
|
+
},
|
|
285
|
+
':where([data-likec4-shape="cylinder"], [data-likec4-shape="storage"]) &': {
|
|
286
|
+
transform: 'translate(8px,8px)'
|
|
287
|
+
},
|
|
288
|
+
':where([data-likec4-shape="queue"]) &': {
|
|
289
|
+
transform: 'translate(-10px,8px)'
|
|
290
|
+
},
|
|
291
|
+
':where([data-hovered="true"]) &': {
|
|
292
|
+
transition: 'opacity 300ms ease-in',
|
|
293
|
+
opacity: 0.2
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
})
|
|
225
297
|
export const cssShapeSvg = style({
|
|
226
|
-
top:
|
|
227
|
-
left:
|
|
298
|
+
top: 0,
|
|
299
|
+
left: 0,
|
|
228
300
|
position: 'absolute',
|
|
229
301
|
pointerEvents: 'none',
|
|
230
302
|
fill: vars.element.fill,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ActionIcon } from '@mantine/core'
|
|
2
2
|
import { IconZoomScan } from '@tabler/icons-react'
|
|
3
3
|
import clsx from 'clsx'
|
|
4
|
-
import { useDiagramStoreApi } from '../../../state/
|
|
4
|
+
import { useDiagramStoreApi } from '../../../state/useDiagramStore'
|
|
5
5
|
|
|
6
6
|
export type NavigateToBtnProps = {
|
|
7
7
|
xynodeId: string
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { XYFlowNode } from '../../types';
|
|
2
|
-
|
|
3
|
-
type ElementIconProps = {
|
|
4
|
-
node: XYFlowNode['data']['element'];
|
|
5
|
-
};
|
|
6
|
-
export declare function ElementIcon({ node: { icon, title, labelBBox } }: ElementIconProps): import("react/jsx-runtime").JSX.Element | null;
|
|
7
|
-
export {};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { assignInlineVars } from '@vanilla-extract/dynamic'
|
|
2
|
-
import clsx from 'clsx'
|
|
3
|
-
import type { XYFlowNode } from '../../types'
|
|
4
|
-
import { elementIcon, iconOffsetY } from './element.css'
|
|
5
|
-
|
|
6
|
-
type ElementIconProps = {
|
|
7
|
-
node: XYFlowNode['data']['element']
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function ElementIcon({
|
|
11
|
-
node: {
|
|
12
|
-
icon,
|
|
13
|
-
title,
|
|
14
|
-
labelBBox
|
|
15
|
-
}
|
|
16
|
-
}: ElementIconProps) {
|
|
17
|
-
if (!icon) {
|
|
18
|
-
return null
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<div
|
|
23
|
-
className={clsx(elementIcon, 'likec4-element-icon')}
|
|
24
|
-
style={assignInlineVars({ iconOffsetY }, {
|
|
25
|
-
iconOffsetY: labelBBox.y + 'px'
|
|
26
|
-
})}>
|
|
27
|
-
<img
|
|
28
|
-
src={icon}
|
|
29
|
-
alt={title}
|
|
30
|
-
/>
|
|
31
|
-
</div>
|
|
32
|
-
)
|
|
33
|
-
}
|