@principal-ai/subsystems-react 0.23.1 → 0.23.2
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/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/pierre/constructColors.d.ts +2 -3
- package/dist/pierre/constructColors.d.ts.map +1 -1
- package/dist/pierre/constructColors.js +31 -21
- package/dist/pierre/constructColors.js.map +1 -1
- package/dist/subsystem/model.d.ts +69 -23
- package/dist/subsystem/model.d.ts.map +1 -1
- package/dist/subsystem/model.js +184 -40
- package/dist/subsystem/model.js.map +1 -1
- package/dist/subsystem/nodes.d.ts.map +1 -1
- package/dist/subsystem/nodes.js +53 -25
- package/dist/subsystem/nodes.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/pierre/constructColors.test.ts +2 -2
- package/src/pierre/constructColors.ts +41 -23
- package/src/stories/Subsystem/ComponentGraph/Packages.stories.tsx +242 -0
- package/src/subsystem/model.test.ts +167 -0
- package/src/subsystem/model.ts +236 -46
- package/src/subsystem/nodes.tsx +55 -26
package/src/subsystem/nodes.tsx
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
MECHANISM_COLOR,
|
|
21
21
|
MECHANISM_STYLE,
|
|
22
22
|
PROPOSED_COLOR,
|
|
23
|
+
constructBadgeColor,
|
|
23
24
|
constructBadgeLabel,
|
|
24
25
|
rightBadgeLabel,
|
|
25
26
|
rightBadgeColor,
|
|
@@ -88,6 +89,9 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
|
|
|
88
89
|
// shows as the hover badge, not as color — for now; a role glyph/accent may
|
|
89
90
|
// come later. A component-authored `color` override wins over the construct.
|
|
90
91
|
const color = componentColor(c, resolvePierreSyntaxThemeName(mode));
|
|
92
|
+
// Left badge: framework brand (e.g. React cyan) when the label is a
|
|
93
|
+
// framework stereotype; otherwise the same construct color as the border.
|
|
94
|
+
const badgeColor = constructBadgeColor(c) ?? color;
|
|
91
95
|
const [hover, setHover] = useState(false);
|
|
92
96
|
const configuredMax = SUBSYSTEM_CALLBACKS.maxNodeWidth;
|
|
93
97
|
const maxWidth = configuredMax ?? 300;
|
|
@@ -114,6 +118,10 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
|
|
|
114
118
|
// Selection is stamped into data by the graph component — React Flow's own
|
|
115
119
|
// `selected` never updates because the node stops click propagation.
|
|
116
120
|
const isSelected = selected || (data.isSelected as boolean | undefined) === true;
|
|
121
|
+
// Externals are "outside" the system — square corners on the node + badges.
|
|
122
|
+
const isExternal = c.construct === 'external';
|
|
123
|
+
const nodeRadius = isExternal ? 0 : 8;
|
|
124
|
+
const badgeRadius = isExternal ? 0 : 4;
|
|
117
125
|
|
|
118
126
|
return (
|
|
119
127
|
<div
|
|
@@ -141,7 +149,7 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
|
|
|
141
149
|
minWidth: badgeMinWidth,
|
|
142
150
|
maxWidth,
|
|
143
151
|
padding: '6px 10px',
|
|
144
|
-
borderRadius:
|
|
152
|
+
borderRadius: nodeRadius,
|
|
145
153
|
background: theme.colors.backgroundSecondary ?? theme.colors.background,
|
|
146
154
|
// Selected / file-matched nodes get a thicker border. Proposed nodes
|
|
147
155
|
// use a dashed goldenrod border; left construct badge keeps construct color.
|
|
@@ -157,11 +165,12 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
|
|
|
157
165
|
>
|
|
158
166
|
{/* Construct / stereotype badge — prefers framework stereotype so a
|
|
159
167
|
React UI unit reads as "react · component" instead of "function".
|
|
160
|
-
Persistent; pointer-events none so clicks pass through to the node.
|
|
168
|
+
Persistent; pointer-events none so clicks pass through to the node.
|
|
169
|
+
Framework badges use brand color; border stays construct-colored. */}
|
|
161
170
|
<div
|
|
162
171
|
style={{
|
|
163
172
|
position: 'absolute',
|
|
164
|
-
top: -
|
|
173
|
+
top: -11,
|
|
165
174
|
left: BADGE_EDGE_INSET,
|
|
166
175
|
zIndex: 1,
|
|
167
176
|
fontFamily: theme.fonts.monospace,
|
|
@@ -170,11 +179,11 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
|
|
|
170
179
|
textTransform: 'uppercase',
|
|
171
180
|
lineHeight: '17px',
|
|
172
181
|
whiteSpace: 'nowrap',
|
|
173
|
-
color,
|
|
182
|
+
color: badgeColor,
|
|
174
183
|
background: theme.colors.backgroundSecondary ?? theme.colors.background,
|
|
175
|
-
border: `
|
|
176
|
-
borderRadius:
|
|
177
|
-
padding: '
|
|
184
|
+
border: `2px solid ${badgeColor}`,
|
|
185
|
+
borderRadius: badgeRadius,
|
|
186
|
+
padding: '2px 8px',
|
|
178
187
|
}}
|
|
179
188
|
>
|
|
180
189
|
{constructBadgeLabel(c)}
|
|
@@ -187,7 +196,7 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
|
|
|
187
196
|
<div
|
|
188
197
|
style={{
|
|
189
198
|
position: 'absolute',
|
|
190
|
-
top: -
|
|
199
|
+
top: -11,
|
|
191
200
|
right: BADGE_EDGE_INSET,
|
|
192
201
|
zIndex: 1,
|
|
193
202
|
display: 'flex',
|
|
@@ -205,9 +214,9 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
|
|
|
205
214
|
lineHeight: '17px',
|
|
206
215
|
color: storageColor,
|
|
207
216
|
background: theme.colors.backgroundSecondary ?? theme.colors.background,
|
|
208
|
-
border: `
|
|
209
|
-
borderRadius:
|
|
210
|
-
padding: '
|
|
217
|
+
border: `2px solid ${storageColor}`,
|
|
218
|
+
borderRadius: badgeRadius,
|
|
219
|
+
padding: '2px 8px',
|
|
211
220
|
}}
|
|
212
221
|
>
|
|
213
222
|
{storageLabel}
|
|
@@ -223,9 +232,9 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
|
|
|
223
232
|
lineHeight: '17px',
|
|
224
233
|
color: topRightColor,
|
|
225
234
|
background: theme.colors.backgroundSecondary ?? theme.colors.background,
|
|
226
|
-
border: `
|
|
227
|
-
borderRadius:
|
|
228
|
-
padding: '
|
|
235
|
+
border: `2px solid ${topRightColor}`,
|
|
236
|
+
borderRadius: badgeRadius,
|
|
237
|
+
padding: '2px 8px',
|
|
229
238
|
}}
|
|
230
239
|
>
|
|
231
240
|
{topRightLabel}
|
|
@@ -241,7 +250,7 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
|
|
|
241
250
|
<div
|
|
242
251
|
style={{
|
|
243
252
|
position: 'absolute',
|
|
244
|
-
bottom: -
|
|
253
|
+
bottom: -14,
|
|
245
254
|
left: '50%',
|
|
246
255
|
transform: 'translateX(-50%)',
|
|
247
256
|
zIndex: 1,
|
|
@@ -254,9 +263,9 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
|
|
|
254
263
|
// borders and badges, not the file name
|
|
255
264
|
color: theme.colors.text ?? theme.colors.textSecondary,
|
|
256
265
|
background: theme.colors.backgroundSecondary ?? theme.colors.background,
|
|
257
|
-
border: `
|
|
258
|
-
borderRadius:
|
|
259
|
-
padding: '
|
|
266
|
+
border: `2px solid ${color}`,
|
|
267
|
+
borderRadius: badgeRadius,
|
|
268
|
+
padding: '2px 8px',
|
|
260
269
|
cursor: 'pointer',
|
|
261
270
|
}}
|
|
262
271
|
onClick={(e) => {
|
|
@@ -341,8 +350,21 @@ export function SubsystemGroupNode(props: NodeProps<Node<SubsystemGroupNodeData,
|
|
|
341
350
|
const color = packageColor(region?.key ?? 'process');
|
|
342
351
|
const dimmed = data.dimmed === true;
|
|
343
352
|
const hidden = (data as { hidden?: boolean }).hidden === true;
|
|
344
|
-
|
|
345
|
-
|
|
353
|
+
// Label is the region identity alone (path / process key / owner/name).
|
|
354
|
+
// Kind is carried by frame chrome (square = process; rounded = module/package)
|
|
355
|
+
// — don't prefix `module ·` / `package ·` or the path reads twice.
|
|
356
|
+
const label = region?.label ?? '';
|
|
357
|
+
// Process frames match external nodes — square corners (outside the soft
|
|
358
|
+
// component language). Module / package frames keep the rounded look.
|
|
359
|
+
const isProcess = region?.kind === 'process';
|
|
360
|
+
const frameRadius = isProcess ? 0 : 12;
|
|
361
|
+
const badgeRadius = isProcess ? 0 : 4;
|
|
362
|
+
// Processes are deployment units — solid frame. Modules/packages stay dashed
|
|
363
|
+
// until selected.
|
|
364
|
+
const frameStyle = isProcess || selected ? 'solid' : 'dashed';
|
|
365
|
+
// Process keeps a tinted fill; module / package bodies stay transparent so
|
|
366
|
+
// nested frames don't stack washes.
|
|
367
|
+
const frameFill = isProcess ? `${color}14` : 'transparent';
|
|
346
368
|
|
|
347
369
|
if (!region) return null;
|
|
348
370
|
|
|
@@ -353,9 +375,9 @@ export function SubsystemGroupNode(props: NodeProps<Node<SubsystemGroupNodeData,
|
|
|
353
375
|
width: width ?? 400,
|
|
354
376
|
height: height ?? 300,
|
|
355
377
|
boxSizing: 'border-box',
|
|
356
|
-
borderRadius:
|
|
357
|
-
border: `2px ${
|
|
358
|
-
background:
|
|
378
|
+
borderRadius: frameRadius,
|
|
379
|
+
border: `2px ${frameStyle} ${color}`,
|
|
380
|
+
background: frameFill,
|
|
359
381
|
opacity: hidden ? 0 : dimmed ? 0.35 : 1,
|
|
360
382
|
transition: 'opacity 150ms ease',
|
|
361
383
|
pointerEvents: 'none',
|
|
@@ -364,8 +386,14 @@ export function SubsystemGroupNode(props: NodeProps<Node<SubsystemGroupNodeData,
|
|
|
364
386
|
<div
|
|
365
387
|
style={{
|
|
366
388
|
position: 'absolute',
|
|
367
|
-
|
|
368
|
-
|
|
389
|
+
// Process: badge fill starts with the process fill (inside the
|
|
390
|
+
// frame border); no top badge border so widths don't fight.
|
|
391
|
+
// Module/package sit astride the top edge like component badges.
|
|
392
|
+
// Always set left/transform/borderTop explicitly — React Flow reuses
|
|
393
|
+
// group DOM nodes and `undefined` does not clear a prior value.
|
|
394
|
+
top: isProcess ? 0 : -19,
|
|
395
|
+
left: isProcess ? '50%' : 12,
|
|
396
|
+
transform: isProcess ? 'translateX(-50%)' : 'none',
|
|
369
397
|
fontFamily: theme.fonts.monospace,
|
|
370
398
|
fontSize: theme.fontSizes[3],
|
|
371
399
|
fontWeight: 700,
|
|
@@ -373,7 +401,8 @@ export function SubsystemGroupNode(props: NodeProps<Node<SubsystemGroupNodeData,
|
|
|
373
401
|
color,
|
|
374
402
|
background: theme.colors.backgroundSecondary ?? theme.colors.background,
|
|
375
403
|
border: `1px solid ${color}`,
|
|
376
|
-
|
|
404
|
+
borderTopWidth: isProcess ? 0 : 1,
|
|
405
|
+
borderRadius: badgeRadius,
|
|
377
406
|
padding: '1px 7px',
|
|
378
407
|
whiteSpace: 'nowrap',
|
|
379
408
|
}}
|