@principal-ai/subsystems-react 0.24.0 → 0.24.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.
Files changed (46) hide show
  1. package/dist/index.d.ts +7 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +4 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/subsystem/ComponentDeclaration.d.ts +3 -1
  6. package/dist/subsystem/ComponentDeclaration.d.ts.map +1 -1
  7. package/dist/subsystem/ComponentDeclaration.js +2 -2
  8. package/dist/subsystem/ComponentDeclaration.js.map +1 -1
  9. package/dist/subsystem/ConstructsCatalog.d.ts +30 -0
  10. package/dist/subsystem/ConstructsCatalog.d.ts.map +1 -0
  11. package/dist/subsystem/ConstructsCatalog.js +329 -0
  12. package/dist/subsystem/ConstructsCatalog.js.map +1 -0
  13. package/dist/subsystem/DiagnosticToggle.d.ts +46 -0
  14. package/dist/subsystem/DiagnosticToggle.d.ts.map +1 -0
  15. package/dist/subsystem/DiagnosticToggle.js +95 -0
  16. package/dist/subsystem/DiagnosticToggle.js.map +1 -0
  17. package/dist/subsystem/IssueList.d.ts +103 -0
  18. package/dist/subsystem/IssueList.d.ts.map +1 -0
  19. package/dist/subsystem/IssueList.js +310 -0
  20. package/dist/subsystem/IssueList.js.map +1 -0
  21. package/dist/subsystem/SubsystemComponentGraph.d.ts +28 -0
  22. package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
  23. package/dist/subsystem/SubsystemComponentGraph.js +81 -58
  24. package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
  25. package/dist/subsystem/SubsystemFileTree.js +2 -2
  26. package/dist/subsystem/SubsystemFileTree.js.map +1 -1
  27. package/dist/subsystem/model.d.ts +13 -2
  28. package/dist/subsystem/model.d.ts.map +1 -1
  29. package/dist/subsystem/model.js +12 -0
  30. package/dist/subsystem/model.js.map +1 -1
  31. package/dist/subsystem/nodes.js +5 -5
  32. package/dist/subsystem/nodes.js.map +1 -1
  33. package/package.json +1 -1
  34. package/src/index.ts +37 -0
  35. package/src/stories/Subsystem/ComponentGraph/Constructs.stories.tsx +287 -0
  36. package/src/stories/Subsystem/ComponentGraph/Diagnostics.stories.tsx +138 -0
  37. package/src/stories/Subsystem/ComponentGraph/Issues.stories.tsx +130 -0
  38. package/src/subsystem/ComponentDeclaration.tsx +4 -1
  39. package/src/subsystem/ConstructsCatalog.tsx +604 -0
  40. package/src/subsystem/DiagnosticToggle.tsx +160 -0
  41. package/src/subsystem/IssueList.tsx +519 -0
  42. package/src/subsystem/SubsystemComponentGraph.tsx +119 -38
  43. package/src/subsystem/SubsystemFileTree.tsx +2 -2
  44. package/src/subsystem/model.test.ts +34 -0
  45. package/src/subsystem/model.ts +18 -2
  46. package/src/subsystem/nodes.tsx +5 -5
@@ -7,6 +7,9 @@
7
7
  * inside one labeled boundary frame; nodes without one sit outside every
8
8
  * boundary. Clicking a component invokes `onSelect`.
9
9
  *
10
+ * When the model has components but no topology or walkthrough edges, the
11
+ * canvas is a constructs catalog (list + signature) instead of a graph.
12
+ *
10
13
  * This is a focused fork of the package's `GraphRenderer` pipeline (same ELK
11
14
  * edge routing, delayed fitView, Background/Controls/MiniMap, node/edge type
12
15
  * injection, onNodeClick) adapted to the subsystem model — read-only.
@@ -37,6 +40,7 @@ import { IndustryMarkdownSlide } from 'themed-markdown';
37
40
  import {
38
41
  buildSubsystemGraph,
39
42
  deriveGraphEdges,
43
+ isConstructsOnlyModel,
40
44
  isRelationMechanism,
41
45
  isWalkthroughMechanism,
42
46
  MECHANISM_COLOR,
@@ -50,8 +54,11 @@ import {
50
54
  type SubsystemRelation,
51
55
  type SubsystemWalkthrough,
52
56
  } from './model';
57
+ import { ConstructsCatalog } from './ConstructsCatalog';
53
58
  import type { SubsystemOpenFileOptions } from './declarationRef';
54
59
  import { SubsystemComponentNode, SubsystemGroupNode, SubsystemEdge, SUBSYSTEM_CALLBACKS, hexWithAlpha, EDGE_DIM_ALPHA, fileMatchForNode, flowElementVisibility } from './nodes';
60
+ import { SubsystemDiagnosticToggle, type SubsystemDiagnostic } from './DiagnosticToggle';
61
+ import { SubsystemIssueList, type SubsystemIssue } from './IssueList';
55
62
  import { SubsystemFileTree } from './SubsystemFileTree';
56
63
  import { GraphLayoutCover } from './GraphLayoutCover';
57
64
  import { ComponentDeclaration } from './ComponentDeclaration';
@@ -160,6 +167,29 @@ export interface SubsystemComponentGraphProps {
160
167
  sidebarExtra?: ReactNode;
161
168
  /** Rendered in the sidebar under the description (e.g. selection inspector). */
162
169
  sidebarAfterDescription?: ReactNode;
170
+ /**
171
+ * Diagnostics status chip in the sidebar title row (beside the description
172
+ * toggle). Shows the last verification pass's state as an icon color + count;
173
+ * `onOpen` opens the full report. Omit to hide the chip.
174
+ */
175
+ diagnostic?: SubsystemDiagnostic;
176
+ /**
177
+ * Verification issues for this graph (audit findings). When diagnostics are
178
+ * active (see `showIssues`) the sidebar's bottom panel becomes the issue
179
+ * list instead of the file tree / walkthroughs.
180
+ */
181
+ issues?: SubsystemIssue[];
182
+ /**
183
+ * Force the sidebar into diagnostics mode. Defaults to `true` whenever
184
+ * `issues` is non-empty (and nothing else has been forced).
185
+ */
186
+ showIssues?: boolean;
187
+ /** Click an issue — focus its target on the graph / open detail. */
188
+ onSelectIssue?: (issue: SubsystemIssue) => void;
189
+ /** Apply an issue's deterministic fix. */
190
+ onApplyIssueFix?: (issue: SubsystemIssue) => void;
191
+ /** Hover an issue — transiently highlight its target (null on leave). */
192
+ onHoverIssue?: (issue: SubsystemIssue | null) => void;
163
193
  /**
164
194
  * Host-injected reader/renderer for the bottom file drawer, keyed by
165
195
  * repo-root-relative path. Opening happens on declaration/file-tree clicks.
@@ -274,7 +304,7 @@ interface InnerProps extends SubsystemComponentGraphProps {
274
304
  measured: { w: number; h: number } | null;
275
305
  }
276
306
 
277
- function Inner({ components, relations, walkthroughs, onSelect, onEdgeSelect, measured: _measured, maxNodeWidth, showEdgeLabels, edgeView, title, hideSidebar, walkthroughStepMode = 'focus', autoPlayWalkthroughs = false, walkthroughAutoPlayIntervalMs = WALKTHROUGH_PLAY_PAUSE_MS, zoomOnWalkthroughFocus = true, graphTitle, showWalkthroughTitle = false, description, canvasOverlay, sidebarExtra, sidebarAfterDescription, renderFileView, renderFileViewer, renderWalkthroughViewer, onFileSelect, onVerifyComponent, componentVerification }: InnerProps) {
307
+ function Inner({ components, relations, walkthroughs, onSelect, onEdgeSelect, measured: _measured, maxNodeWidth, showEdgeLabels, edgeView, title, hideSidebar, walkthroughStepMode = 'focus', autoPlayWalkthroughs = false, walkthroughAutoPlayIntervalMs = WALKTHROUGH_PLAY_PAUSE_MS, zoomOnWalkthroughFocus = true, graphTitle, showWalkthroughTitle = false, description, canvasOverlay, sidebarExtra, sidebarAfterDescription, diagnostic, issues, showIssues, onSelectIssue, onApplyIssueFix, onHoverIssue, renderFileView, renderFileViewer, renderWalkthroughViewer, onFileSelect, onVerifyComponent, componentVerification }: InnerProps) {
278
308
  const { theme } = useTheme();
279
309
  const { fitView } = useReactFlow();
280
310
  const viewport = useViewport();
@@ -935,6 +965,10 @@ function Inner({ components, relations, walkthroughs, onSelect, onEdgeSelect, me
935
965
  // own owner-avatar header. Clicking a header collapses that repo's tree.
936
966
  const repoGroups = useMemo(() => buildRepoGroups(components), [components]);
937
967
  const hasWalkthroughs = useMemo(() => (walkthroughs?.length ?? 0) > 0, [walkthroughs]);
968
+ // Diagnostics mode: the bottom panel shows the issue list instead of the
969
+ // file tree / walkthroughs. Explicit `showIssues` wins; otherwise any issues
970
+ // present turn it on.
971
+ const issuesActive = showIssues ?? (issues?.length ?? 0) > 0;
938
972
  const [collapsedRepos, setCollapsedRepos] = useState<Set<string>>(new Set());
939
973
  const toggleRepoCollapsed = useCallback((key: string) => {
940
974
  setCollapsedRepos((prev) => {
@@ -1426,7 +1460,7 @@ function Inner({ components, relations, walkthroughs, onSelect, onEdgeSelect, me
1426
1460
  {/* Sidebar: scrollable title/description on top, files or flows pinned below.
1427
1461
  The description hides by default so files/flows get the room; the
1428
1462
  title-row toggle reveals it, and the lower panel yields back to 50%. */}
1429
- {!hideSidebar && (title || description || sidebarExtra || sidebarAfterDescription || treeFilePaths.length > 0 || hasWalkthroughs) && (
1463
+ {!hideSidebar && (title || description || diagnostic || issuesActive || sidebarExtra || sidebarAfterDescription || treeFilePaths.length > 0 || hasWalkthroughs) && (
1430
1464
  <div
1431
1465
  style={{
1432
1466
  width: sidebarWidth,
@@ -1450,7 +1484,7 @@ function Inner({ components, relations, walkthroughs, onSelect, onEdgeSelect, me
1450
1484
  }}
1451
1485
  >
1452
1486
  {sidebarExtra}
1453
- {(title || description) && (
1487
+ {(title || description || diagnostic) && (
1454
1488
  <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8 }}>
1455
1489
  {title && (
1456
1490
  <h2
@@ -1467,34 +1501,47 @@ function Inner({ components, relations, walkthroughs, onSelect, onEdgeSelect, me
1467
1501
  {title}
1468
1502
  </h2>
1469
1503
  )}
1470
- {description && (
1471
- <button
1472
- type="button"
1473
- aria-expanded={descriptionVisible}
1474
- aria-label={descriptionVisible ? 'Hide description' : 'Show description'}
1475
- title={descriptionVisible ? 'Hide description' : 'Show description'}
1476
- onMouseEnter={() => setDescToggleHover(true)}
1477
- onMouseLeave={() => setDescToggleHover(false)}
1478
- onClick={() => setDescriptionVisible((v) => !v)}
1479
- style={{
1480
- display: 'inline-flex',
1481
- alignItems: 'center',
1482
- justifyContent: 'center',
1483
- flexShrink: 0,
1484
- width: 22,
1485
- height: 22,
1486
- padding: 0,
1487
- border: 'none',
1488
- borderRadius: 4,
1489
- background: descToggleHover ? theme.colors.border : 'transparent',
1490
- color: descToggleHover ? theme.colors.text : (theme.colors.textMuted ?? theme.colors.textSecondary),
1491
- cursor: 'pointer',
1492
- transition: 'background 120ms ease, color 120ms ease',
1493
- }}
1494
- >
1495
- {descriptionVisible ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
1496
- </button>
1497
- )}
1504
+ <div
1505
+ style={{
1506
+ display: 'flex',
1507
+ alignItems: 'center',
1508
+ gap: 4,
1509
+ flexShrink: 0,
1510
+ // Title's flex:1 already pushes this cluster right; without a
1511
+ // title, keep the actions flush right instead of flush-left.
1512
+ marginLeft: title ? undefined : 'auto',
1513
+ }}
1514
+ >
1515
+ {diagnostic && <SubsystemDiagnosticToggle {...diagnostic} />}
1516
+ {description && (
1517
+ <button
1518
+ type="button"
1519
+ aria-expanded={descriptionVisible}
1520
+ aria-label={descriptionVisible ? 'Hide description' : 'Show description'}
1521
+ title={descriptionVisible ? 'Hide description' : 'Show description'}
1522
+ onMouseEnter={() => setDescToggleHover(true)}
1523
+ onMouseLeave={() => setDescToggleHover(false)}
1524
+ onClick={() => setDescriptionVisible((v) => !v)}
1525
+ style={{
1526
+ display: 'inline-flex',
1527
+ alignItems: 'center',
1528
+ justifyContent: 'center',
1529
+ flexShrink: 0,
1530
+ width: 22,
1531
+ height: 22,
1532
+ padding: 0,
1533
+ border: 'none',
1534
+ borderRadius: 4,
1535
+ background: descToggleHover ? theme.colors.border : 'transparent',
1536
+ color: descToggleHover ? theme.colors.text : (theme.colors.textMuted ?? theme.colors.textSecondary),
1537
+ cursor: 'pointer',
1538
+ transition: 'background 120ms ease, color 120ms ease',
1539
+ }}
1540
+ >
1541
+ {descriptionVisible ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
1542
+ </button>
1543
+ )}
1544
+ </div>
1498
1545
  </div>
1499
1546
  )}
1500
1547
  {description && descriptionVisible && (
@@ -1507,7 +1554,6 @@ function Inner({ components, relations, walkthroughs, onSelect, onEdgeSelect, me
1507
1554
  theme={theme}
1508
1555
  disableScroll={true}
1509
1556
  disableBasePadding
1510
- fontSizeScale={0.9}
1511
1557
  enableKeyboardScrolling={false}
1512
1558
  autoFocusOnVisible={false}
1513
1559
  />
@@ -1515,7 +1561,7 @@ function Inner({ components, relations, walkthroughs, onSelect, onEdgeSelect, me
1515
1561
  )}
1516
1562
  {sidebarAfterDescription}
1517
1563
  </div>
1518
- {(treeFilePaths.length > 0 || hasWalkthroughs) && (
1564
+ {(treeFilePaths.length > 0 || hasWalkthroughs || issuesActive) && (
1519
1565
  <div
1520
1566
  style={{
1521
1567
  ...(showDesc ? { height: '50%' as const } : { flex: 1, minHeight: 0 }),
@@ -1527,6 +1573,15 @@ function Inner({ components, relations, walkthroughs, onSelect, onEdgeSelect, me
1527
1573
  overflow: 'hidden',
1528
1574
  }}
1529
1575
  >
1576
+ {issuesActive ? (
1577
+ <SubsystemIssueList
1578
+ issues={issues ?? []}
1579
+ onSelectIssue={onSelectIssue}
1580
+ onApplyFix={onApplyIssueFix}
1581
+ onHoverIssue={onHoverIssue}
1582
+ />
1583
+ ) : (
1584
+ <>
1530
1585
  {hasWalkthroughs && (
1531
1586
  <div
1532
1587
  role="tablist"
@@ -1640,13 +1695,15 @@ function Inner({ components, relations, walkthroughs, onSelect, onEdgeSelect, me
1640
1695
  })}
1641
1696
  </>
1642
1697
  ) : null}
1698
+ </>
1699
+ )}
1643
1700
  </div>
1644
1701
  )}
1645
1702
  </div>
1646
1703
  )}
1647
1704
 
1648
1705
  {/* Drag handle between sidebar and canvas — resize the left panel. */}
1649
- {!hideSidebar && (title || description || sidebarExtra || sidebarAfterDescription || treeFilePaths.length > 0 || hasWalkthroughs) && (
1706
+ {!hideSidebar && (title || description || diagnostic || issuesActive || sidebarExtra || sidebarAfterDescription || treeFilePaths.length > 0 || hasWalkthroughs) && (
1650
1707
  <div
1651
1708
  onMouseDown={onSidebarResizeStart}
1652
1709
  aria-label="Resize sidebar"
@@ -2352,7 +2409,7 @@ function WalkthroughFlow({
2352
2409
  style={{
2353
2410
  flexShrink: 0,
2354
2411
  width: 14,
2355
- fontSize: theme.fontSizes[0] * 0.8,
2412
+ fontSize: theme.fontSizes[0],
2356
2413
  fontFamily: theme.fonts.monospace,
2357
2414
  color: stepActive ? theme.colors.text : muted,
2358
2415
  }}
@@ -2435,6 +2492,12 @@ export function SubsystemComponentGraph(props: SubsystemComponentGraphProps) {
2435
2492
  return () => ro.disconnect();
2436
2493
  }, []);
2437
2494
 
2495
+ const constructsOnly = isConstructsOnlyModel({
2496
+ components: props.components,
2497
+ relations: props.relations,
2498
+ walkthroughs: props.walkthroughs,
2499
+ });
2500
+
2438
2501
  return (
2439
2502
  <div
2440
2503
  ref={wrapRef}
@@ -2448,9 +2511,27 @@ export function SubsystemComponentGraph(props: SubsystemComponentGraphProps) {
2448
2511
  }}
2449
2512
  >
2450
2513
  <div style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }}>
2451
- <ReactFlowProvider>
2452
- <Inner {...props} measured={size} />
2453
- </ReactFlowProvider>
2514
+ {constructsOnly ? (
2515
+ <ConstructsCatalog
2516
+ components={props.components}
2517
+ onSelect={props.onSelect}
2518
+ title={props.title}
2519
+ hideSidebar={props.hideSidebar}
2520
+ description={props.description}
2521
+ diagnostic={props.diagnostic}
2522
+ sidebarExtra={props.sidebarExtra}
2523
+ sidebarAfterDescription={props.sidebarAfterDescription}
2524
+ renderFileViewer={props.renderFileViewer}
2525
+ renderFileView={props.renderFileView}
2526
+ onFileSelect={props.onFileSelect}
2527
+ onVerifyComponent={props.onVerifyComponent}
2528
+ componentVerification={props.componentVerification}
2529
+ />
2530
+ ) : (
2531
+ <ReactFlowProvider>
2532
+ <Inner {...props} measured={size} />
2533
+ </ReactFlowProvider>
2534
+ )}
2454
2535
  </div>
2455
2536
  </div>
2456
2537
  );
@@ -153,7 +153,7 @@ export function SubsystemFileTree({ files, selectedFile, hoveredFile, onSelectFi
153
153
  >
154
154
  <span
155
155
  style={{
156
- fontSize: theme.fontSizes[0] * 0.8,
156
+ fontSize: theme.fontSizes[0],
157
157
  fontFamily: theme.fonts.monospace,
158
158
  textTransform: 'uppercase',
159
159
  color: muted,
@@ -162,7 +162,7 @@ export function SubsystemFileTree({ files, selectedFile, hoveredFile, onSelectFi
162
162
  >
163
163
  Files
164
164
  </span>
165
- <span style={{ fontSize: theme.fontSizes[0] * 0.8, fontFamily: theme.fonts.monospace, color: muted }}>
165
+ <span style={{ fontSize: theme.fontSizes[0], fontFamily: theme.fonts.monospace, color: muted }}>
166
166
  {paths.length}
167
167
  </span>
168
168
  </div>
@@ -13,6 +13,7 @@ import {
13
13
  buildSubsystemGraph,
14
14
  componentPackageKey,
15
15
  deriveNameFromSymbol,
16
+ isConstructsOnlyModel,
16
17
  constructBadgeLabel,
17
18
  constructBadgeColor,
18
19
  FRAMEWORK_BADGE_COLOR,
@@ -642,3 +643,36 @@ describe('subsystem graph model', () => {
642
643
  expect(subsystemGraphLayoutKey(base)).toBe(subsystemGraphLayoutKey(withRef));
643
644
  });
644
645
  });
646
+
647
+ describe('isConstructsOnlyModel', () => {
648
+ test('true when components exist and there are no edges', () => {
649
+ expect(isConstructsOnlyModel({ components: comps, relations: [], walkthroughs: [] })).toBe(true);
650
+ expect(isConstructsOnlyModel({ components: comps })).toBe(true);
651
+ });
652
+
653
+ test('false when empty, or when relations or walkthrough hops exist', () => {
654
+ expect(isConstructsOnlyModel({ components: [], relations: [] })).toBe(false);
655
+ expect(isConstructsOnlyModel({ components: comps, relations })).toBe(false);
656
+ expect(
657
+ isConstructsOnlyModel({
658
+ components: comps,
659
+ relations: [],
660
+ walkthroughs: [
661
+ {
662
+ id: 'wt',
663
+ title: 'flow',
664
+ steps: [
665
+ {
666
+ from: 'transcript',
667
+ to: 'reader',
668
+ mechanism: 'calls',
669
+ file: 'transcript.ts',
670
+ line: 1,
671
+ },
672
+ ],
673
+ },
674
+ ],
675
+ }),
676
+ ).toBe(false);
677
+ });
678
+ });
@@ -331,8 +331,8 @@ export function walkthroughStepGraphEdgeId(
331
331
  }
332
332
 
333
333
  export function deriveGraphEdges(doc: {
334
- relations?: SubsystemRelation[];
335
- walkthroughs?: SubsystemWalkthrough[];
334
+ relations?: readonly SubsystemRelation[];
335
+ walkthroughs?: readonly SubsystemWalkthrough[];
336
336
  }): SubsystemComponentEdge[] {
337
337
  const byId = new Map<string, SubsystemComponentEdge>();
338
338
  for (const r of doc.relations ?? []) {
@@ -363,6 +363,22 @@ export function deriveGraphEdges(doc: {
363
363
  return [...byId.values()];
364
364
  }
365
365
 
366
+ /**
367
+ * True when the model has components but no topology or walkthrough edges.
368
+ * Those snapshots are a catalog of declarations, not a graph.
369
+ */
370
+ export function isConstructsOnlyModel(doc: {
371
+ components: readonly { id: string }[];
372
+ relations?: readonly SubsystemRelation[];
373
+ walkthroughs?: readonly SubsystemWalkthrough[];
374
+ }): boolean {
375
+ if (doc.components.length === 0) return false;
376
+ return deriveGraphEdges({
377
+ relations: doc.relations,
378
+ walkthroughs: doc.walkthroughs,
379
+ }).length === 0;
380
+ }
381
+
366
382
  /**
367
383
  * Derive a consistent display `name` from a code `symbol` + construct.
368
384
  *
@@ -174,7 +174,7 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
174
174
  left: BADGE_EDGE_INSET,
175
175
  zIndex: 1,
176
176
  fontFamily: theme.fonts.monospace,
177
- fontSize: theme.fontSizes[0] * 1.1,
177
+ fontSize: theme.fontSizes[1],
178
178
  letterSpacing: 0.5,
179
179
  textTransform: 'uppercase',
180
180
  lineHeight: '17px',
@@ -208,7 +208,7 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
208
208
  <span
209
209
  style={{
210
210
  fontFamily: theme.fonts.monospace,
211
- fontSize: theme.fontSizes[0] * 1.1,
211
+ fontSize: theme.fontSizes[1],
212
212
  letterSpacing: 0.5,
213
213
  textTransform: 'uppercase',
214
214
  lineHeight: '17px',
@@ -226,7 +226,7 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
226
226
  <span
227
227
  style={{
228
228
  fontFamily: theme.fonts.monospace,
229
- fontSize: theme.fontSizes[0] * 1.1,
229
+ fontSize: theme.fontSizes[1],
230
230
  letterSpacing: 0.5,
231
231
  textTransform: 'uppercase',
232
232
  lineHeight: '17px',
@@ -255,7 +255,7 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
255
255
  transform: 'translateX(-50%)',
256
256
  zIndex: 1,
257
257
  fontFamily: theme.fonts.monospace,
258
- fontSize: theme.fontSizes[0] * 1.1,
258
+ fontSize: theme.fontSizes[1],
259
259
  letterSpacing: 0.5,
260
260
  lineHeight: '17px',
261
261
  whiteSpace: 'nowrap',
@@ -311,7 +311,7 @@ export function SubsystemComponentNode(props: NodeProps<Node<SubsystemGraphNodeD
311
311
  .replace(/\(\)$/, '') && (
312
312
  <div
313
313
  style={{
314
- fontSize: theme.fontSizes[0] * 0.82,
314
+ fontSize: theme.fontSizes[0],
315
315
  fontFamily: theme.fonts.monospace,
316
316
  color: color,
317
317
  marginTop: 1,