@principal-ai/subsystems-react 0.37.9 → 0.37.11

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);
@@ -369,7 +370,7 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
369
370
  showEdgeLabels,
370
371
  showSingletonFrames,
371
372
  })
372
- .then(({ nodes, edges: e }) => {
373
+ .then(({ nodes, edges: e, absoluteRects }) => {
373
374
  if (!alive)
374
375
  return;
375
376
  // Prune dims for removed leaves; keep measurements for stable ids so a
@@ -379,7 +380,7 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
379
380
  if (!leafIds.has(id))
380
381
  measuredDimsRef.current.delete(id);
381
382
  }
382
- setBuilt({ nodes, edges: e });
383
+ setBuilt({ nodes, edges: e, absoluteRects });
383
384
  setLayoutReady(false);
384
385
  })
385
386
  .catch((err) => {
@@ -387,7 +388,7 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
387
388
  if (!alive)
388
389
  return;
389
390
  // Reveal the cover even on failure so the UI is not stuck forever.
390
- setBuilt({ nodes: [], edges: [] });
391
+ setBuilt({ nodes: [], edges: [], absoluteRects: new Map() });
391
392
  setLayoutReady(true);
392
393
  });
393
394
  return () => { alive = false; };
@@ -419,10 +420,10 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
419
420
  const measuredHeights = new Map(leafNodes.map((n) => [n.id, dims.get(n.id).height]));
420
421
  const gen = ++pass2GenRef.current;
421
422
  void buildSubsystemGraph({ components, relations, walkthroughs }, { maxNodeWidth, showEdgeLabels, measuredWidths, measuredHeights, showSingletonFrames })
422
- .then(({ nodes, edges: e }) => {
423
+ .then(({ nodes, edges: e, absoluteRects }) => {
423
424
  if (gen !== pass2GenRef.current)
424
425
  return;
425
- setBuilt({ nodes, edges: e });
426
+ setBuilt({ nodes, edges: e, absoluteRects });
426
427
  setLayoutReady(true);
427
428
  })
428
429
  .catch((err) => {
@@ -516,9 +517,19 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
516
517
  // without a stale closure value.
517
518
  const selectedEdgeIdRef = useRef(null);
518
519
  selectedEdgeIdRef.current = selectedEdgeId;
520
+ // Autoplay focus: a sidebar-less embed has no expanded flow to "open", so
521
+ // branding every step as a selection would hide all other nodes. Instead the
522
+ // autoplay sets this (flow id + step) to frame the hop and dim the rest —
523
+ // same treatment as hover — without hiding anything.
524
+ const [autoPlayFocus, setAutoPlayFocus] = useState(null);
519
525
  // Edge ids in walkthrough focus (an active flow's edge set, or a single
520
526
  // step's edge). Used to frame the camera. `null` = no walkthrough focus.
521
527
  const focusEdgeIds = useMemo(() => {
528
+ if (autoPlayFocus) {
529
+ const tl = walkthroughs?.find((t) => t.id === autoPlayFocus.walkthroughId);
530
+ const step = tl?.steps[autoPlayFocus.stepIndex];
531
+ return step ? new Set([walkthroughStepGraphEdgeId(step)]) : null;
532
+ }
522
533
  if (focusedWalkthroughId == null || !walkthroughs)
523
534
  return null;
524
535
  const tl = walkthroughs.find((t) => t.id === focusedWalkthroughId);
@@ -529,7 +540,7 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
529
540
  return step ? new Set([walkthroughStepGraphEdgeId(step)]) : null;
530
541
  }
531
542
  return new Set(tl.steps.map((s) => walkthroughStepGraphEdgeId(s)));
532
- }, [walkthroughs, focusedWalkthroughId, focusedStepIndex]);
543
+ }, [walkthroughs, focusedWalkthroughId, focusedStepIndex, autoPlayFocus]);
533
544
  // 1-based step numbers per edge of the active flow (focused or
534
545
  // hover/autoplay-highlighted). An edge can appear in more than one step.
535
546
  const selectedFlowStepNos = useMemo(() => {
@@ -589,15 +600,21 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
589
600
  // selected + hovered participants. Whole-flow focus (or no focus) keeps
590
601
  // the old hover-replace preview so a step hover still dims the rest.
591
602
  const previewEdgeIds = useMemo(() => {
603
+ // Autoplay drives focus without a hover, so its hop is the preview set.
604
+ if (autoPlayFocus)
605
+ return focusEdgeIds;
592
606
  if (!hoverEdgeIds)
593
607
  return null;
608
+ // While hovering with a *step* already selected, brighten the union of
609
+ // selected + hovered participants; whole-flow focus keeps the old
610
+ // hover-replace preview so a step hover still dims the rest.
594
611
  if (focusedStepIndex == null || !focusEdgeIds)
595
612
  return hoverEdgeIds;
596
613
  const ids = new Set(hoverEdgeIds);
597
614
  for (const id of focusEdgeIds)
598
615
  ids.add(id);
599
616
  return ids;
600
- }, [hoverEdgeIds, focusEdgeIds, focusedStepIndex]);
617
+ }, [hoverEdgeIds, focusEdgeIds, focusedStepIndex, autoPlayFocus]);
601
618
  const previewNodeIds = useMemo(() => endpointsOf(previewEdgeIds),
602
619
  // eslint-disable-next-line react-hooks/exhaustive-deps
603
620
  [baseEdges, previewEdgeIds]);
@@ -633,22 +650,26 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
633
650
  // While a step/flow is hovered, selected + hovered participants stay
634
651
  // bright; everything else among the currently-visible (opened-walkthrough)
635
652
  // nodes is dimmed. Nodes outside the opened-walkthrough set stay hidden.
653
+ // Exception: with no expanded flow at all (a sidebar-less embed), there is
654
+ // nothing to hide toward — everything shows, and focus/hover only dims.
655
+ const noOpenedFlow = openedEdgeIds == null;
636
656
  return xyflowNodesBase.map((n) => {
637
657
  // Boundary frames follow their members: hidden when no member is
638
658
  // visible, dimmed when members are dimmed. Never selectable.
639
659
  if (n.type === 'subsystem-group') {
640
660
  const region = n.data?.region;
641
661
  const memberAliases = region?.memberAliases ?? [];
662
+ // Hover/autoplay dim-only: never hide a frame (see the node branch).
642
663
  const vis = flowElementVisibility({
643
664
  inOpened: memberAliases.some((alias) => openedNodeIds?.has(alias) === true),
644
665
  inSelected: memberAliases.some((alias) => brightNodeIds?.has(alias) === true),
645
666
  anyOpened: openedNodeIds != null,
646
- anySelected: brightNodeIds != null,
667
+ anySelected: brightNodeIds != null || previewNodeIds != null,
647
668
  });
648
669
  const dimmed = previewNodeIds
649
670
  ? vis.hidden || !memberAliases.some((alias) => previewNodeIds.has(alias))
650
671
  : vis.dimmed;
651
- const hidden = vis.hidden;
672
+ const hidden = noOpenedFlow ? false : vis.hidden;
652
673
  // Host override wins over the library's derived frame color.
653
674
  const color = region?.key != null ? boundaryColors?.[region.key] : undefined;
654
675
  return {
@@ -664,15 +685,19 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
664
685
  }
665
686
  const comp = n.data?.component;
666
687
  const fileMatch = fileMatchForNode(comp?.file, openFile, focusNodeIds?.has(n.id) === true);
688
+ // Hover/autoplay is a dim-only signal: never hide non-participants (there
689
+ // may be no "opened" flow to reveal them, e.g. a sidebar-less autoplay
690
+ // embed), only dim them. Bases selection on the focused step, not the
691
+ // hover preview, so hovering doesn't strip the frame's `isSelected`.
667
692
  const isSelected = selected?.alias !== undefined && comp?.alias === selected.alias;
668
693
  const vis = flowElementVisibility({
669
694
  inOpened: openedNodeIds?.has(n.id) === true,
670
695
  inSelected: brightNodeIds?.has(n.id) === true,
671
696
  anyOpened: openedNodeIds != null,
672
- anySelected: brightNodeIds != null,
697
+ anySelected: brightNodeIds != null || previewNodeIds != null,
673
698
  });
674
699
  const dimmed = previewNodeIds ? (vis.hidden || !previewNodeIds.has(n.id)) : vis.dimmed;
675
- const hidden = vis.hidden;
700
+ const hidden = noOpenedFlow ? false : vis.hidden;
676
701
  if (fileMatch === undefined && !isSelected && !dimmed) {
677
702
  const { fileMatch: _f, isSelected: _s, dimmed: _d, ...rest } = n.data;
678
703
  return { ...n, hidden, data: rest };
@@ -846,11 +871,8 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
846
871
  // Boundary frame → frame its members on the canvas; double-click again to
847
872
  // zoom back out. User-initiated, so it ignores the walkthrough zoom gate.
848
873
  if (node.type === 'subsystem-group') {
849
- const region = node.data
850
- ?.region;
851
- const key = region?.key;
852
- const members = region?.memberAliases ?? [];
853
- if (!key || members.length === 0)
874
+ const key = node.data?.region?.key;
875
+ if (!key)
854
876
  return;
855
877
  if (focusedBoundaryKey === key) {
856
878
  setFocusedBoundaryKey(null);
@@ -864,8 +886,11 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
864
886
  return;
865
887
  }
866
888
  setFocusedBoundaryKey(key);
889
+ // Frame the boundary node itself (not its members): the frame extends
890
+ // above its topmost member for the label, and fitting members alone
891
+ // clipped that top. The group node carries the full laid-out bounds.
867
892
  fitView({
868
- nodes: members.map((id) => ({ id })),
893
+ nodes: [{ id: node.id }],
869
894
  padding: 0.25,
870
895
  duration: 300,
871
896
  });
@@ -911,28 +936,73 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
911
936
  window.addEventListener('keydown', onKey);
912
937
  return () => window.removeEventListener('keydown', onKey);
913
938
  }, [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).
939
+ // Camera helper shared by the walkthrough interactions. Fits the union of
940
+ // the focused edges' endpoint rects AND their routed waypoints — the edge
941
+ // carries its full polyline (`elkPathPoints`, absolute flow coords), so the
942
+ // frame is the line the hop actually traces. That keeps a hop whose route
943
+ // bulges out around intervening nodes from being clipped at the viewport
944
+ // edge, and it is the edge's own geometry doing the guiding, not fudge
945
+ // padding.
918
946
  const fitFocusBounds = useCallback((ids) => {
919
947
  if (!zoomOnWalkthroughFocus)
920
948
  return;
921
949
  const nodeIds = new Set();
950
+ const points = [];
922
951
  for (const e of baseEdges) {
923
952
  if (!ids.has(e.id))
924
953
  continue;
925
954
  nodeIds.add(e.source);
926
955
  nodeIds.add(e.target);
956
+ const pts = e.data
957
+ ?.elkPathPoints;
958
+ if (pts?.length)
959
+ points.push(...pts);
927
960
  }
928
961
  if (nodeIds.size === 0)
929
962
  return;
930
- fitView({
931
- nodes: [...nodeIds].map((id) => ({ id })),
932
- padding: 0.25,
933
- duration: 300,
963
+ // Box the focused edge(s): endpoint node rects UNION the routed line's
964
+ // waypoints. Both come from the layout in absolute flow coords, so no
965
+ // coordinate-space mixing (React Flow's grouped child `position`s are
966
+ // parent-relative and would skew the box).
967
+ const rects = built.absoluteRects;
968
+ let minX = Infinity;
969
+ let minY = Infinity;
970
+ let maxX = -Infinity;
971
+ let maxY = -Infinity;
972
+ for (const id of nodeIds) {
973
+ const r = rects.get(id);
974
+ if (!r)
975
+ continue;
976
+ minX = Math.min(minX, r.x);
977
+ minY = Math.min(minY, r.y);
978
+ maxX = Math.max(maxX, r.x + r.width);
979
+ maxY = Math.max(maxY, r.y + r.height);
980
+ }
981
+ for (const p of points) {
982
+ minX = Math.min(minX, p.x);
983
+ minY = Math.min(minY, p.y);
984
+ maxX = Math.max(maxX, p.x);
985
+ maxY = Math.max(maxY, p.y);
986
+ }
987
+ if (!Number.isFinite(minX) || !Number.isFinite(minY))
988
+ return;
989
+ const bounds = {
990
+ x: minX,
991
+ y: minY,
992
+ width: Math.max(1, maxX - minX),
993
+ height: Math.max(1, maxY - minY),
994
+ };
995
+ fitBounds(bounds, {
996
+ padding: 0.15,
997
+ duration: walkthroughFocusDurationMs,
934
998
  });
935
- }, [baseEdges, fitView, zoomOnWalkthroughFocus]);
999
+ }, [
1000
+ baseEdges,
1001
+ built.absoluteRects,
1002
+ fitBounds,
1003
+ zoomOnWalkthroughFocus,
1004
+ walkthroughFocusDurationMs,
1005
+ ]);
936
1006
  // Zoom back out to the full diagram after the last expanded walkthrough
937
1007
  // closes (visibility restores non-flow nodes that were hidden).
938
1008
  const fitOverview = useCallback(() => {
@@ -1097,9 +1167,11 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
1097
1167
  prevPreviewEdgeIdsRef.current = previewEdgeIds;
1098
1168
  if (!zoomOnWalkthroughFocus || walkthroughStepMode === 'dim')
1099
1169
  return;
1100
- // Camera follows hover only when a specific step is already focused.
1101
- if (focusedWalkthroughId == null || focusedStepIndex == null)
1170
+ // Camera follows hover only when a specific step is already focused (or
1171
+ // autoplay is driving an auto-focus).
1172
+ if (!autoPlayFocus && (focusedWalkthroughId == null || focusedStepIndex == null)) {
1102
1173
  return;
1174
+ }
1103
1175
  if (previewEdgeIds) {
1104
1176
  fitFocusBounds(previewEdgeIds);
1105
1177
  return;
@@ -1112,46 +1184,93 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
1112
1184
  focusEdgeIds,
1113
1185
  focusedWalkthroughId,
1114
1186
  focusedStepIndex,
1187
+ autoPlayFocus,
1115
1188
  fitFocusBounds,
1116
1189
  zoomOnWalkthroughFocus,
1117
1190
  walkthroughStepMode,
1118
1191
  ]);
1119
- // Graph-only embeds: cycle walkthrough steps with hover-style dimming.
1192
+ // Graph-only embeds: cycle walkthrough steps. In `focus` mode each step is
1193
+ // selected (camera frames it via fitFocusBounds) and, when a walkthrough
1194
+ // viewer is supplied, its snippet drawer opens; in `dim` mode it only
1195
+ // dim-highlights the step (hover-style) with no camera move.
1120
1196
  useEffect(() => {
1121
- if (!autoPlayWalkthroughs || !walkthroughs?.length || !layoutReady)
1197
+ if (!autoPlayWalkthroughs || walkthroughs == null || walkthroughs.length === 0)
1198
+ return;
1199
+ if (!layoutReady)
1122
1200
  return;
1123
1201
  const playable = walkthroughs.filter((tl) => tl.steps.length > 0);
1124
1202
  if (playable.length === 0)
1125
1203
  return;
1204
+ // Only run the cycles that can actually be shown in the current edge view.
1205
+ const inView = playable.filter((tl) => tl.steps.some((s) => resolvedEdgeView === 'relations'
1206
+ ? isRelationMechanism(s.mechanism)
1207
+ : isWalkthroughMechanism(s.mechanism)));
1208
+ if (inView.length === 0)
1209
+ return;
1210
+ const cyc = inView;
1126
1211
  let cancelled = false;
1127
1212
  let tlIdx = 0;
1128
1213
  let stepIdx = 0;
1129
1214
  let timer = null;
1130
1215
  const interval = Math.max(400, walkthroughAutoPlayIntervalMs);
1216
+ const focusMode = walkthroughStepMode !== 'dim';
1217
+ let cleanup = () => { };
1131
1218
  const tick = () => {
1132
1219
  if (cancelled)
1133
1220
  return;
1134
- const tl = playable[tlIdx];
1221
+ const tl = cyc[tlIdx];
1135
1222
  setSelected(null);
1136
1223
  setSelectedEdgeId(null);
1137
- setFocusedWalkthroughId(null);
1138
- setFocusedStepIndex(null);
1139
- setHoveredWalkthroughStep({ walkthroughId: tl.id, stepIndex: stepIdx });
1224
+ if (focusMode) {
1225
+ setHoveredWalkthroughStep(null);
1226
+ setFocusedWalkthroughId(null);
1227
+ setFocusedStepIndex(null);
1228
+ setAutoPlayFocus({ walkthroughId: tl.id, stepIndex: stepIdx });
1229
+ if (!hideDrawer) {
1230
+ const step = tl.steps[stepIdx];
1231
+ if (step) {
1232
+ if (renderWalkthroughViewer) {
1233
+ setDrawerTarget({ kind: 'walkthrough', walkthroughId: tl.id, stepIndex: stepIdx });
1234
+ }
1235
+ else {
1236
+ setDrawerTarget({ kind: 'file', file: step.file, startLine: step.line });
1237
+ }
1238
+ }
1239
+ }
1240
+ }
1241
+ else {
1242
+ setAutoPlayFocus(null);
1243
+ setFocusedWalkthroughId(null);
1244
+ setFocusedStepIndex(null);
1245
+ setHoveredWalkthroughStep({ walkthroughId: tl.id, stepIndex: stepIdx });
1246
+ }
1140
1247
  stepIdx += 1;
1141
1248
  if (stepIdx >= tl.steps.length) {
1142
1249
  stepIdx = 0;
1143
- tlIdx = (tlIdx + 1) % playable.length;
1250
+ tlIdx = (tlIdx + 1) % cyc.length;
1144
1251
  }
1145
1252
  timer = window.setTimeout(tick, interval);
1146
1253
  };
1147
1254
  tick();
1148
- return () => {
1255
+ cleanup = () => {
1149
1256
  cancelled = true;
1150
1257
  if (timer != null)
1151
1258
  window.clearTimeout(timer);
1152
1259
  setHoveredWalkthroughStep(null);
1260
+ setFocusedWalkthroughId(null);
1261
+ setFocusedStepIndex(null);
1262
+ setAutoPlayFocus(null);
1153
1263
  };
1154
- }, [autoPlayWalkthroughs, walkthroughs, walkthroughAutoPlayIntervalMs, layoutReady]);
1264
+ return cleanup;
1265
+ }, [
1266
+ autoPlayWalkthroughs,
1267
+ walkthroughs,
1268
+ walkthroughAutoPlayIntervalMs,
1269
+ layoutReady,
1270
+ walkthroughStepMode,
1271
+ renderWalkthroughViewer,
1272
+ hideDrawer,
1273
+ ]);
1155
1274
  // Arrow keys step through the focused walkthrough once a step is active
1156
1275
  // (sidebar click or drawer open). Ignores typing targets and chords.
1157
1276
  useEffect(() => {
@@ -1606,7 +1725,7 @@ function Inner({ components, relations, walkthroughs, initialWalkthroughId, onRe
1606
1725
  drawerTarget.startLine != null &&
1607
1726
  !!selected.file &&
1608
1727
  selected.file === drawerTarget.file &&
1609
- selected.declarationRef?.startLine === drawerTarget.startLine }) }))] }), _jsx(FileDrawer, { title: drawerTitle, onClose: closeDrawer, fillHeight: drawerFillHeight, suppressEscape: fileOverlayOpen, children: drawerTarget?.kind === 'walkthrough' &&
1728
+ selected.declarationRef?.startLine === drawerTarget.startLine }) }))] }), _jsx(FileDrawer, { title: drawerTitle, onClose: closeDrawer, fillHeight: drawerFillHeight, suppressEscape: fileOverlayOpen, hidden: hideDrawer, children: drawerTarget?.kind === 'walkthrough' &&
1610
1729
  focusedWalkthrough &&
1611
1730
  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
1731
  position: 'absolute',