@principal-ai/subsystems-react 0.37.10 → 0.37.12

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.
@@ -13,7 +13,7 @@ export declare const FILE_DRAWER_HEIGHT_MS = 200;
13
13
  * footprint so the canvas shrinks while open (nothing covered). Stays mounted
14
14
  * so open/close/maximize animate. The header's maximize button (or a
15
15
  * double-click) grows it over the whole graph column for whole-file reading. */
16
- export declare function FileDrawer({ title, onClose, fillHeight, suppressEscape, children, }: {
16
+ export declare function FileDrawer({ title, onClose, fillHeight, suppressEscape, hidden, children, }: {
17
17
  /** Drawer chrome title; `null` closes the drawer. */
18
18
  title: string | null;
19
19
  onClose: () => void;
@@ -21,6 +21,8 @@ export declare function FileDrawer({ title, onClose, fillHeight, suppressEscape,
21
21
  fillHeight?: boolean;
22
22
  /** Skip Escape handling (e.g. while a full-file overlay is on top). */
23
23
  suppressEscape?: boolean;
24
+ /** Suppress the drawer entirely — no spacer, no panel (embeds). */
25
+ hidden?: boolean;
24
26
  children?: ReactNode;
25
27
  }): import("react").JSX.Element;
26
28
  //# sourceMappingURL=FileDrawer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FileDrawer.d.ts","sourceRoot":"","sources":["../../src/subsystem/FileDrawer.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC;2EAC2E;AAC3E,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC;;;;iFAIiF;AACjF,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,OAAO,EACP,UAAkB,EAClB,cAAsB,EACtB,QAAQ,GACT,EAAE;IACD,qDAAqD;IACrD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,wEAAwE;IACxE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,+BAiJA"}
1
+ {"version":3,"file":"FileDrawer.d.ts","sourceRoot":"","sources":["../../src/subsystem/FileDrawer.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC;2EAC2E;AAC3E,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC;;;;iFAIiF;AACjF,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,OAAO,EACP,UAAkB,EAClB,cAAsB,EACtB,MAAc,EACd,QAAQ,GACT,EAAE;IACD,qDAAqD;IACrD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,wEAAwE;IACxE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,mEAAmE;IACnE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,+BAiJA"}
@@ -16,10 +16,10 @@ export const FILE_DRAWER_HEIGHT_MS = 200;
16
16
  * footprint so the canvas shrinks while open (nothing covered). Stays mounted
17
17
  * so open/close/maximize animate. The header's maximize button (or a
18
18
  * double-click) grows it over the whole graph column for whole-file reading. */
19
- export function FileDrawer({ title, onClose, fillHeight = false, suppressEscape = false, children, }) {
19
+ export function FileDrawer({ title, onClose, fillHeight = false, suppressEscape = false, hidden = false, children, }) {
20
20
  const { theme } = useTheme();
21
21
  const muted = theme.colors.textMuted ?? theme.colors.textSecondary;
22
- const open = title !== null;
22
+ const open = title !== null && !hidden;
23
23
  const [closeHover, setCloseHover] = useState(false);
24
24
  const [maxHover, setMaxHover] = useState(false);
25
25
  // Full-height mode: the maximize button or double-clicking the header.
@@ -1 +1 @@
1
- {"version":3,"file":"FileDrawer.js","sourceRoot":"","sources":["../../src/subsystem/FileDrawer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FileDrawer.js","sourceRoot":"","sources":["../../src/subsystem/FileDrawer.tsx"],"names":[],"mappings":"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"}
@@ -129,6 +129,12 @@ export interface SubsystemComponentGraphProps {
129
129
  * @default true
130
130
  */
131
131
  zoomOnWalkthroughFocus?: boolean;
132
+ /**
133
+ * Duration (ms) of the camera pan/zoom when a walkthrough step or flow is
134
+ * focused. Higher = a slower, more legible flight between steps.
135
+ * @default 300
136
+ */
137
+ walkthroughFocusDurationMs?: number;
132
138
  /**
133
139
  * Subsystem title rendered as a non-interactive overlay chip on the graph
134
140
  * canvas (top-center). Does not trigger the sidebar — for graph-only
@@ -197,6 +203,13 @@ export interface SubsystemComponentGraphProps {
197
203
  * updates it as the focused step changes.
198
204
  */
199
205
  renderWalkthroughViewer?: (ctx: WalkthroughViewerContext) => ReactNode;
206
+ /**
207
+ * Suppress the bottom file/walkthrough drawer entirely. Focusing a step then
208
+ * only frames it on the canvas (and dims the rest) without dropping a snippet
209
+ * panel below — for embeds that want the camera to tell the story. Defaults
210
+ * to false.
211
+ */
212
+ hideDrawer?: boolean;
200
213
  /**
201
214
  * Legacy component-keyed variant, kept for backward compatibility. When
202
215
  * `renderFileViewer` is absent, drawer content resolves via the first
@@ -1 +1 @@
1
- {"version":3,"file":"SubsystemComponentGraph.d.ts","sourceRoot":"","sources":["../../src/subsystem/SubsystemComponentGraph.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SubsystemComponentGraph.d.ts","sourceRoot":"","sources":["../../src/subsystem/SubsystemComponentGraph.tsx"],"names":[],"mappings":"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"}
@@ -120,9 +120,9 @@ const WalkthroughDrawerContent = memo(function WalkthroughDrawerContent({ render
120
120
  onSymbolClick,
121
121
  }) }));
122
122
  });
123
- function Inner({ components, relations, walkthroughs, initialWalkthroughId, onReorderWalkthroughs, onSelect, onEdgeSelect, measured: _measured, maxNodeWidth, showEdgeLabels, showSingletonFrames = true, edgeView, title, hideSidebar, walkthroughStepMode = 'focus', autoPlayWalkthroughs = false, walkthroughAutoPlayIntervalMs = WALKTHROUGH_PLAY_PAUSE_MS, zoomOnWalkthroughFocus = true, graphTitle, showWalkthroughTitle = false, description, canvasOverlay, sidebarExtra, sidebarAfterDescription, diagnostic, issues, showIssues, focusIssueCategory, onSelectIssue, onApplyIssueFix, onHoverIssue, renderFileView, renderFileViewer, renderWalkthroughViewer, onFileSelect, componentVerification, onInspectSymbol, boundaryColors, persistKey }) {
123
+ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onReorderWalkthroughs, onSelect, onEdgeSelect, measured: _measured, maxNodeWidth, showEdgeLabels, showSingletonFrames = true, edgeView, title, hideSidebar, walkthroughStepMode = 'focus', autoPlayWalkthroughs = false, walkthroughAutoPlayIntervalMs = WALKTHROUGH_PLAY_PAUSE_MS, zoomOnWalkthroughFocus = true, walkthroughFocusDurationMs = 300, graphTitle, showWalkthroughTitle = false, description, canvasOverlay, sidebarExtra, sidebarAfterDescription, diagnostic, issues, showIssues, focusIssueCategory, onSelectIssue, onApplyIssueFix, onHoverIssue, renderFileView, renderFileViewer, renderWalkthroughViewer, onFileSelect, componentVerification, onInspectSymbol, boundaryColors, hideDrawer = false, persistKey }) {
124
124
  const { theme } = useTheme();
125
- const { fitView } = useReactFlow();
125
+ const { fitView, fitBounds } = useReactFlow();
126
126
  const viewport = useViewport();
127
127
  // Restored once per mount from `localStorage` (see `readViewState`). Each
128
128
  // graph is its own tab/mount, so `persistKey` is stable for a mount.
@@ -131,6 +131,7 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
131
131
  const [built, setBuilt] = useState({
132
132
  nodes: [],
133
133
  edges: [],
134
+ absoluteRects: new Map(),
134
135
  });
135
136
  const [layoutReady, setLayoutReady] = useState(false);
136
137
  const [selected, setSelected] = useState(null);
@@ -262,15 +263,24 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
262
263
  return null;
263
264
  return walkthroughs.find((t) => t.id === drawerTarget.walkthroughId) ?? null;
264
265
  }, [drawerTarget, walkthroughs]);
266
+ // Autoplay focus: a sidebar-less embed has no expanded flow to "open", so
267
+ // branding every step as a selection would hide all other nodes. Instead the
268
+ // autoplay sets this (flow id + step) to frame the hop and dim the rest —
269
+ // same treatment as hover — without hiding anything. Declared before the
270
+ // overlay memos, which read it to title the canvas chip + step bar.
271
+ const [autoPlayFocus, setAutoPlayFocus] = useState(null);
265
272
  // Ref mirror of the drawer's walkthrough id so the symbol resolver stays
266
273
  // stable across graph re-renders (the drawer is memoized on callback identity).
267
274
  const drawerWalkthroughIdRef = useRef(null);
268
275
  drawerWalkthroughIdRef.current = focusedWalkthrough?.id ?? null;
269
- // Walkthrough shown on the canvas title chip (focus or hover/autoplay highlight).
276
+ // Walkthrough shown on the canvas title chip (focus, hover highlight, or
277
+ // autoplay focus).
270
278
  const overlayWalkthroughTitle = useMemo(() => {
271
279
  if (!showWalkthroughTitle || !walkthroughs?.length)
272
280
  return null;
273
- const id = focusedWalkthroughId ?? hoveredWalkthroughStep?.walkthroughId;
281
+ const id = focusedWalkthroughId ??
282
+ autoPlayFocus?.walkthroughId ??
283
+ hoveredWalkthroughStep?.walkthroughId;
274
284
  if (!id)
275
285
  return null;
276
286
  return walkthroughs.find((t) => t.id === id)?.title ?? null;
@@ -278,17 +288,24 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
278
288
  showWalkthroughTitle,
279
289
  walkthroughs,
280
290
  focusedWalkthroughId,
291
+ autoPlayFocus,
281
292
  hoveredWalkthroughStep,
282
293
  ]);
283
294
  // Active step for the bottom-of-title progress + annotation chip.
284
295
  const overlayWalkthroughStep = useMemo(() => {
285
296
  if (!showWalkthroughTitle || !walkthroughs?.length)
286
297
  return null;
287
- const tlId = focusedWalkthroughId ?? hoveredWalkthroughStep?.walkthroughId ?? null;
298
+ const tlId = focusedWalkthroughId ??
299
+ autoPlayFocus?.walkthroughId ??
300
+ hoveredWalkthroughStep?.walkthroughId ??
301
+ null;
288
302
  let stepIndex = null;
289
303
  if (focusedWalkthroughId != null) {
290
304
  stepIndex = focusedStepIndex;
291
305
  }
306
+ else if (autoPlayFocus != null) {
307
+ stepIndex = autoPlayFocus.stepIndex;
308
+ }
292
309
  else if (hoveredWalkthroughStep != null) {
293
310
  stepIndex = hoveredWalkthroughStep.stepIndex;
294
311
  }
@@ -308,6 +325,7 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
308
325
  walkthroughs,
309
326
  focusedWalkthroughId,
310
327
  focusedStepIndex,
328
+ autoPlayFocus,
311
329
  hoveredWalkthroughStep,
312
330
  ]);
313
331
  const drawerTitle = useMemo(() => {
@@ -369,7 +387,7 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
369
387
  showEdgeLabels,
370
388
  showSingletonFrames,
371
389
  })
372
- .then(({ nodes, edges: e }) => {
390
+ .then(({ nodes, edges: e, absoluteRects }) => {
373
391
  if (!alive)
374
392
  return;
375
393
  // Prune dims for removed leaves; keep measurements for stable ids so a
@@ -379,7 +397,7 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
379
397
  if (!leafIds.has(id))
380
398
  measuredDimsRef.current.delete(id);
381
399
  }
382
- setBuilt({ nodes, edges: e });
400
+ setBuilt({ nodes, edges: e, absoluteRects });
383
401
  setLayoutReady(false);
384
402
  })
385
403
  .catch((err) => {
@@ -387,7 +405,7 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
387
405
  if (!alive)
388
406
  return;
389
407
  // Reveal the cover even on failure so the UI is not stuck forever.
390
- setBuilt({ nodes: [], edges: [] });
408
+ setBuilt({ nodes: [], edges: [], absoluteRects: new Map() });
391
409
  setLayoutReady(true);
392
410
  });
393
411
  return () => { alive = false; };
@@ -419,10 +437,10 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
419
437
  const measuredHeights = new Map(leafNodes.map((n) => [n.id, dims.get(n.id).height]));
420
438
  const gen = ++pass2GenRef.current;
421
439
  void buildSubsystemGraph({ components, relations, walkthroughs }, { maxNodeWidth, showEdgeLabels, measuredWidths, measuredHeights, showSingletonFrames })
422
- .then(({ nodes, edges: e }) => {
440
+ .then(({ nodes, edges: e, absoluteRects }) => {
423
441
  if (gen !== pass2GenRef.current)
424
442
  return;
425
- setBuilt({ nodes, edges: e });
443
+ setBuilt({ nodes, edges: e, absoluteRects });
426
444
  setLayoutReady(true);
427
445
  })
428
446
  .catch((err) => {
@@ -519,6 +537,11 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
519
537
  // Edge ids in walkthrough focus (an active flow's edge set, or a single
520
538
  // step's edge). Used to frame the camera. `null` = no walkthrough focus.
521
539
  const focusEdgeIds = useMemo(() => {
540
+ if (autoPlayFocus) {
541
+ const tl = walkthroughs?.find((t) => t.id === autoPlayFocus.walkthroughId);
542
+ const step = tl?.steps[autoPlayFocus.stepIndex];
543
+ return step ? new Set([walkthroughStepGraphEdgeId(step)]) : null;
544
+ }
522
545
  if (focusedWalkthroughId == null || !walkthroughs)
523
546
  return null;
524
547
  const tl = walkthroughs.find((t) => t.id === focusedWalkthroughId);
@@ -529,7 +552,7 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
529
552
  return step ? new Set([walkthroughStepGraphEdgeId(step)]) : null;
530
553
  }
531
554
  return new Set(tl.steps.map((s) => walkthroughStepGraphEdgeId(s)));
532
- }, [walkthroughs, focusedWalkthroughId, focusedStepIndex]);
555
+ }, [walkthroughs, focusedWalkthroughId, focusedStepIndex, autoPlayFocus]);
533
556
  // 1-based step numbers per edge of the active flow (focused or
534
557
  // hover/autoplay-highlighted). An edge can appear in more than one step.
535
558
  const selectedFlowStepNos = useMemo(() => {
@@ -589,15 +612,21 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
589
612
  // selected + hovered participants. Whole-flow focus (or no focus) keeps
590
613
  // the old hover-replace preview so a step hover still dims the rest.
591
614
  const previewEdgeIds = useMemo(() => {
615
+ // Autoplay drives focus without a hover, so its hop is the preview set.
616
+ if (autoPlayFocus)
617
+ return focusEdgeIds;
592
618
  if (!hoverEdgeIds)
593
619
  return null;
620
+ // While hovering with a *step* already selected, brighten the union of
621
+ // selected + hovered participants; whole-flow focus keeps the old
622
+ // hover-replace preview so a step hover still dims the rest.
594
623
  if (focusedStepIndex == null || !focusEdgeIds)
595
624
  return hoverEdgeIds;
596
625
  const ids = new Set(hoverEdgeIds);
597
626
  for (const id of focusEdgeIds)
598
627
  ids.add(id);
599
628
  return ids;
600
- }, [hoverEdgeIds, focusEdgeIds, focusedStepIndex]);
629
+ }, [hoverEdgeIds, focusEdgeIds, focusedStepIndex, autoPlayFocus]);
601
630
  const previewNodeIds = useMemo(() => endpointsOf(previewEdgeIds),
602
631
  // eslint-disable-next-line react-hooks/exhaustive-deps
603
632
  [baseEdges, previewEdgeIds]);
@@ -633,22 +662,26 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
633
662
  // While a step/flow is hovered, selected + hovered participants stay
634
663
  // bright; everything else among the currently-visible (opened-walkthrough)
635
664
  // nodes is dimmed. Nodes outside the opened-walkthrough set stay hidden.
665
+ // Exception: with no expanded flow at all (a sidebar-less embed), there is
666
+ // nothing to hide toward — everything shows, and focus/hover only dims.
667
+ const noOpenedFlow = openedEdgeIds == null;
636
668
  return xyflowNodesBase.map((n) => {
637
669
  // Boundary frames follow their members: hidden when no member is
638
670
  // visible, dimmed when members are dimmed. Never selectable.
639
671
  if (n.type === 'subsystem-group') {
640
672
  const region = n.data?.region;
641
673
  const memberAliases = region?.memberAliases ?? [];
674
+ // Hover/autoplay dim-only: never hide a frame (see the node branch).
642
675
  const vis = flowElementVisibility({
643
676
  inOpened: memberAliases.some((alias) => openedNodeIds?.has(alias) === true),
644
677
  inSelected: memberAliases.some((alias) => brightNodeIds?.has(alias) === true),
645
678
  anyOpened: openedNodeIds != null,
646
- anySelected: brightNodeIds != null,
679
+ anySelected: brightNodeIds != null || previewNodeIds != null,
647
680
  });
648
681
  const dimmed = previewNodeIds
649
682
  ? vis.hidden || !memberAliases.some((alias) => previewNodeIds.has(alias))
650
683
  : vis.dimmed;
651
- const hidden = vis.hidden;
684
+ const hidden = noOpenedFlow ? false : vis.hidden;
652
685
  // Host override wins over the library's derived frame color.
653
686
  const color = region?.key != null ? boundaryColors?.[region.key] : undefined;
654
687
  return {
@@ -664,15 +697,19 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
664
697
  }
665
698
  const comp = n.data?.component;
666
699
  const fileMatch = fileMatchForNode(comp?.file, openFile, focusNodeIds?.has(n.id) === true);
700
+ // Hover/autoplay is a dim-only signal: never hide non-participants (there
701
+ // may be no "opened" flow to reveal them, e.g. a sidebar-less autoplay
702
+ // embed), only dim them. Bases selection on the focused step, not the
703
+ // hover preview, so hovering doesn't strip the frame's `isSelected`.
667
704
  const isSelected = selected?.alias !== undefined && comp?.alias === selected.alias;
668
705
  const vis = flowElementVisibility({
669
706
  inOpened: openedNodeIds?.has(n.id) === true,
670
707
  inSelected: brightNodeIds?.has(n.id) === true,
671
708
  anyOpened: openedNodeIds != null,
672
- anySelected: brightNodeIds != null,
709
+ anySelected: brightNodeIds != null || previewNodeIds != null,
673
710
  });
674
711
  const dimmed = previewNodeIds ? (vis.hidden || !previewNodeIds.has(n.id)) : vis.dimmed;
675
- const hidden = vis.hidden;
712
+ const hidden = noOpenedFlow ? false : vis.hidden;
676
713
  if (fileMatch === undefined && !isSelected && !dimmed) {
677
714
  const { fileMatch: _f, isSelected: _s, dimmed: _d, ...rest } = n.data;
678
715
  return { ...n, hidden, data: rest };
@@ -911,28 +948,73 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
911
948
  window.addEventListener('keydown', onKey);
912
949
  return () => window.removeEventListener('keydown', onKey);
913
950
  }, [fileOverlayOpen, closeFileOverlay]);
914
- // Camera helper shared by the walkthrough interactions: frames the focused
915
- // edges' endpoint nodes via `fitView({ nodes })`, which uses the store's
916
- // live positions + measured dims — so the frame always includes BOTH
917
- // components the edge attaches to (and therefore the edge line between them).
951
+ // Camera helper shared by the walkthrough interactions. Fits the union of
952
+ // the focused edges' endpoint rects AND their routed waypoints — the edge
953
+ // carries its full polyline (`elkPathPoints`, absolute flow coords), so the
954
+ // frame is the line the hop actually traces. That keeps a hop whose route
955
+ // bulges out around intervening nodes from being clipped at the viewport
956
+ // edge, and it is the edge's own geometry doing the guiding, not fudge
957
+ // padding.
918
958
  const fitFocusBounds = useCallback((ids) => {
919
959
  if (!zoomOnWalkthroughFocus)
920
960
  return;
921
961
  const nodeIds = new Set();
962
+ const points = [];
922
963
  for (const e of baseEdges) {
923
964
  if (!ids.has(e.id))
924
965
  continue;
925
966
  nodeIds.add(e.source);
926
967
  nodeIds.add(e.target);
968
+ const pts = e.data
969
+ ?.elkPathPoints;
970
+ if (pts?.length)
971
+ points.push(...pts);
927
972
  }
928
973
  if (nodeIds.size === 0)
929
974
  return;
930
- fitView({
931
- nodes: [...nodeIds].map((id) => ({ id })),
932
- padding: 0.25,
933
- duration: 300,
975
+ // Box the focused edge(s): endpoint node rects UNION the routed line's
976
+ // waypoints. Both come from the layout in absolute flow coords, so no
977
+ // coordinate-space mixing (React Flow's grouped child `position`s are
978
+ // parent-relative and would skew the box).
979
+ const rects = built.absoluteRects;
980
+ let minX = Infinity;
981
+ let minY = Infinity;
982
+ let maxX = -Infinity;
983
+ let maxY = -Infinity;
984
+ for (const id of nodeIds) {
985
+ const r = rects.get(id);
986
+ if (!r)
987
+ continue;
988
+ minX = Math.min(minX, r.x);
989
+ minY = Math.min(minY, r.y);
990
+ maxX = Math.max(maxX, r.x + r.width);
991
+ maxY = Math.max(maxY, r.y + r.height);
992
+ }
993
+ for (const p of points) {
994
+ minX = Math.min(minX, p.x);
995
+ minY = Math.min(minY, p.y);
996
+ maxX = Math.max(maxX, p.x);
997
+ maxY = Math.max(maxY, p.y);
998
+ }
999
+ if (!Number.isFinite(minX) || !Number.isFinite(minY))
1000
+ return;
1001
+ const bounds = {
1002
+ x: minX,
1003
+ y: minY,
1004
+ width: Math.max(1, maxX - minX),
1005
+ height: Math.max(1, maxY - minY),
1006
+ };
1007
+ fitBounds(bounds, {
1008
+ padding: 0.15,
1009
+ duration: walkthroughFocusDurationMs,
934
1010
  });
935
- }, [baseEdges, fitView, zoomOnWalkthroughFocus]);
1011
+ }, [
1012
+ baseEdges,
1013
+ built.absoluteRects,
1014
+ fitBounds,
1015
+ zoomOnWalkthroughFocus,
1016
+ walkthroughFocusDurationMs,
1017
+ ]);
936
1018
  // Zoom back out to the full diagram after the last expanded walkthrough
937
1019
  // closes (visibility restores non-flow nodes that were hidden).
938
1020
  const fitOverview = useCallback(() => {
@@ -1097,9 +1179,11 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
1097
1179
  prevPreviewEdgeIdsRef.current = previewEdgeIds;
1098
1180
  if (!zoomOnWalkthroughFocus || walkthroughStepMode === 'dim')
1099
1181
  return;
1100
- // Camera follows hover only when a specific step is already focused.
1101
- if (focusedWalkthroughId == null || focusedStepIndex == null)
1182
+ // Camera follows hover only when a specific step is already focused (or
1183
+ // autoplay is driving an auto-focus).
1184
+ if (!autoPlayFocus && (focusedWalkthroughId == null || focusedStepIndex == null)) {
1102
1185
  return;
1186
+ }
1103
1187
  if (previewEdgeIds) {
1104
1188
  fitFocusBounds(previewEdgeIds);
1105
1189
  return;
@@ -1112,46 +1196,93 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
1112
1196
  focusEdgeIds,
1113
1197
  focusedWalkthroughId,
1114
1198
  focusedStepIndex,
1199
+ autoPlayFocus,
1115
1200
  fitFocusBounds,
1116
1201
  zoomOnWalkthroughFocus,
1117
1202
  walkthroughStepMode,
1118
1203
  ]);
1119
- // Graph-only embeds: cycle walkthrough steps with hover-style dimming.
1204
+ // Graph-only embeds: cycle walkthrough steps. In `focus` mode each step is
1205
+ // selected (camera frames it via fitFocusBounds) and, when a walkthrough
1206
+ // viewer is supplied, its snippet drawer opens; in `dim` mode it only
1207
+ // dim-highlights the step (hover-style) with no camera move.
1120
1208
  useEffect(() => {
1121
- if (!autoPlayWalkthroughs || !walkthroughs?.length || !layoutReady)
1209
+ if (!autoPlayWalkthroughs || walkthroughs == null || walkthroughs.length === 0)
1210
+ return;
1211
+ if (!layoutReady)
1122
1212
  return;
1123
1213
  const playable = walkthroughs.filter((tl) => tl.steps.length > 0);
1124
1214
  if (playable.length === 0)
1125
1215
  return;
1216
+ // Only run the cycles that can actually be shown in the current edge view.
1217
+ const inView = playable.filter((tl) => tl.steps.some((s) => resolvedEdgeView === 'relations'
1218
+ ? isRelationMechanism(s.mechanism)
1219
+ : isWalkthroughMechanism(s.mechanism)));
1220
+ if (inView.length === 0)
1221
+ return;
1222
+ const cyc = inView;
1126
1223
  let cancelled = false;
1127
1224
  let tlIdx = 0;
1128
1225
  let stepIdx = 0;
1129
1226
  let timer = null;
1130
1227
  const interval = Math.max(400, walkthroughAutoPlayIntervalMs);
1228
+ const focusMode = walkthroughStepMode !== 'dim';
1229
+ let cleanup = () => { };
1131
1230
  const tick = () => {
1132
1231
  if (cancelled)
1133
1232
  return;
1134
- const tl = playable[tlIdx];
1233
+ const tl = cyc[tlIdx];
1135
1234
  setSelected(null);
1136
1235
  setSelectedEdgeId(null);
1137
- setFocusedWalkthroughId(null);
1138
- setFocusedStepIndex(null);
1139
- setHoveredWalkthroughStep({ walkthroughId: tl.id, stepIndex: stepIdx });
1236
+ if (focusMode) {
1237
+ setHoveredWalkthroughStep(null);
1238
+ setFocusedWalkthroughId(null);
1239
+ setFocusedStepIndex(null);
1240
+ setAutoPlayFocus({ walkthroughId: tl.id, stepIndex: stepIdx });
1241
+ if (!hideDrawer) {
1242
+ const step = tl.steps[stepIdx];
1243
+ if (step) {
1244
+ if (renderWalkthroughViewer) {
1245
+ setDrawerTarget({ kind: 'walkthrough', walkthroughId: tl.id, stepIndex: stepIdx });
1246
+ }
1247
+ else {
1248
+ setDrawerTarget({ kind: 'file', file: step.file, startLine: step.line });
1249
+ }
1250
+ }
1251
+ }
1252
+ }
1253
+ else {
1254
+ setAutoPlayFocus(null);
1255
+ setFocusedWalkthroughId(null);
1256
+ setFocusedStepIndex(null);
1257
+ setHoveredWalkthroughStep({ walkthroughId: tl.id, stepIndex: stepIdx });
1258
+ }
1140
1259
  stepIdx += 1;
1141
1260
  if (stepIdx >= tl.steps.length) {
1142
1261
  stepIdx = 0;
1143
- tlIdx = (tlIdx + 1) % playable.length;
1262
+ tlIdx = (tlIdx + 1) % cyc.length;
1144
1263
  }
1145
1264
  timer = window.setTimeout(tick, interval);
1146
1265
  };
1147
1266
  tick();
1148
- return () => {
1267
+ cleanup = () => {
1149
1268
  cancelled = true;
1150
1269
  if (timer != null)
1151
1270
  window.clearTimeout(timer);
1152
1271
  setHoveredWalkthroughStep(null);
1272
+ setFocusedWalkthroughId(null);
1273
+ setFocusedStepIndex(null);
1274
+ setAutoPlayFocus(null);
1153
1275
  };
1154
- }, [autoPlayWalkthroughs, walkthroughs, walkthroughAutoPlayIntervalMs, layoutReady]);
1276
+ return cleanup;
1277
+ }, [
1278
+ autoPlayWalkthroughs,
1279
+ walkthroughs,
1280
+ walkthroughAutoPlayIntervalMs,
1281
+ layoutReady,
1282
+ walkthroughStepMode,
1283
+ renderWalkthroughViewer,
1284
+ hideDrawer,
1285
+ ]);
1155
1286
  // Arrow keys step through the focused walkthrough once a step is active
1156
1287
  // (sidebar click or drawer open). Ignores typing targets and chords.
1157
1288
  useEffect(() => {
@@ -1606,7 +1737,7 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
1606
1737
  drawerTarget.startLine != null &&
1607
1738
  !!selected.file &&
1608
1739
  selected.file === drawerTarget.file &&
1609
- selected.declarationRef?.startLine === drawerTarget.startLine }) }))] }), _jsx(FileDrawer, { title: drawerTitle, onClose: closeDrawer, fillHeight: drawerFillHeight, suppressEscape: fileOverlayOpen, children: drawerTarget?.kind === 'walkthrough' &&
1740
+ selected.declarationRef?.startLine === drawerTarget.startLine }) }))] }), _jsx(FileDrawer, { title: drawerTitle, onClose: closeDrawer, fillHeight: drawerFillHeight, suppressEscape: fileOverlayOpen, hidden: hideDrawer, children: drawerTarget?.kind === 'walkthrough' &&
1610
1741
  focusedWalkthrough &&
1611
1742
  renderWalkthroughViewer ? (_jsx(WalkthroughDrawerContent, { render: renderWalkthroughDrawerContent, walkthrough: focusedWalkthrough, stepIndex: drawerTarget.stepIndex, onOpenFile: onOpenFileFromWalkthrough, proposedAliases: proposedAliases, resolveSymbol: resolveWalkthroughSymbol, onSymbolClick: openConstructDeclaration })) : drawerTarget?.kind === 'file' ? (_jsx(FileDrawerContent, { render: renderDrawerContent, file: drawerTarget.file, startLine: drawerTarget.startLine })) : null }), fileOverlay && (_jsxs("div", { style: {
1612
1743
  position: 'absolute',