@principal-ai/subsystems-react 0.37.5 → 0.37.6

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 (37) hide show
  1. package/dist/index.d.ts +2 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +2 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/stories/Subsystem/C4Graph/c4Fixture.d.ts +3 -0
  6. package/dist/stories/Subsystem/C4Graph/c4Fixture.d.ts.map +1 -0
  7. package/dist/stories/Subsystem/C4Graph/c4Fixture.js +2 -0
  8. package/dist/stories/Subsystem/C4Graph/c4Fixture.js.map +1 -0
  9. package/dist/subsystem/C4Graph.d.ts +22 -0
  10. package/dist/subsystem/C4Graph.d.ts.map +1 -0
  11. package/dist/subsystem/C4Graph.js +305 -0
  12. package/dist/subsystem/C4Graph.js.map +1 -0
  13. package/dist/subsystem/WalkthroughsPanel.d.ts +2 -0
  14. package/dist/subsystem/WalkthroughsPanel.d.ts.map +1 -1
  15. package/dist/subsystem/WalkthroughsPanel.js +114 -48
  16. package/dist/subsystem/WalkthroughsPanel.js.map +1 -1
  17. package/dist/subsystem/model.js +6 -6
  18. package/dist/subsystem/toC4.d.ts +95 -0
  19. package/dist/subsystem/toC4.d.ts.map +1 -0
  20. package/dist/subsystem/toC4.js +196 -0
  21. package/dist/subsystem/toC4.js.map +1 -0
  22. package/dist/subsystem/walkthroughBrief.d.ts +18 -0
  23. package/dist/subsystem/walkthroughBrief.d.ts.map +1 -0
  24. package/dist/subsystem/walkthroughBrief.js +34 -0
  25. package/dist/subsystem/walkthroughBrief.js.map +1 -0
  26. package/package.json +1 -1
  27. package/src/index.ts +6 -1
  28. package/src/stories/Subsystem/C4Graph/C4Container.stories.tsx +104 -0
  29. package/src/stories/Subsystem/C4Graph/c4Fixture.ts +6 -0
  30. package/src/subsystem/C4Graph.tsx +465 -0
  31. package/src/subsystem/WalkthroughsPanel.test.tsx +146 -0
  32. package/src/subsystem/WalkthroughsPanel.tsx +163 -60
  33. package/src/subsystem/model.ts +6 -6
  34. package/src/subsystem/toC4.test.ts +121 -0
  35. package/src/subsystem/toC4.ts +277 -0
  36. package/src/subsystem/walkthroughBrief.test.ts +57 -0
  37. package/src/subsystem/walkthroughBrief.ts +40 -0
@@ -0,0 +1,305 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * C4Graph — a C4 projection of a (composed) subsystem model on React Flow.
4
+ *
5
+ * Prototype test case: feed it a `C4Model` from `toC4()` and it draws the
6
+ * system as a compound frame, its containers (or components) as boxes, and
7
+ * externals/actors outside the system. Static `relations` render as solid
8
+ * edges; `walkthrough` hops render as dashed flow edges. Click a box to list
9
+ * the source components it rolled up.
10
+ *
11
+ * Same interaction language as the other graphs: React Flow + ELK + the shared
12
+ * `GRAPH_NAV_PROPS` chrome. Deliberately small — no measurement passes, no
13
+ * drawers, no walkthrough playback.
14
+ */
15
+ import { useEffect, useMemo, useState } from 'react';
16
+ import { Handle, MarkerType, Position, ReactFlow, ReactFlowProvider, useReactFlow, } from '@xyflow/react';
17
+ import { useTheme } from '@principal-ade/industry-theme';
18
+ import { computeElkLayout } from '../utils/elkLayout';
19
+ import { describeConstructBreakdown, MECHANISM_COLOR } from './model';
20
+ import { GRAPH_CANVAS_CLASS, GRAPH_NAV_PROPS, GraphChrome, GraphLayerStyle } from './graphChrome';
21
+ const NODE_W = 230;
22
+ const NODE_H = 80;
23
+ function baseName(path) {
24
+ const parts = path.split('/').filter(Boolean);
25
+ return parts[parts.length - 1] ?? path;
26
+ }
27
+ function edgeColor(mechanism, fallback) {
28
+ if (!mechanism)
29
+ return fallback;
30
+ return MECHANISM_COLOR[mechanism] ?? fallback;
31
+ }
32
+ function C4NodeView(props) {
33
+ const { theme } = useTheme();
34
+ const { node, selected } = props.data;
35
+ const muted = theme.colors.textMuted ?? theme.colors.textSecondary;
36
+ const kindColor = node.kind === 'external'
37
+ ? (theme.colors.warning ?? theme.colors.accent ?? theme.colors.info)
38
+ : node.kind === 'actor'
39
+ ? (theme.colors.accent ?? theme.colors.info)
40
+ : (theme.colors.border ?? '#333');
41
+ const tag = node.kind === 'container' ? 'container' : node.kind === 'external' ? 'external system' : node.kind === 'actor' ? 'actor' : 'component';
42
+ const subtitle = node.kind === 'component'
43
+ ? `${node.component?.construct ?? 'code'}${node.component?.file ? ` · ${baseName(node.component.file)}` : ''}`
44
+ : `${describeConstructBreakdown(node.constructs)}${node.members.length > 0 ? ` · ${node.members.length} component${node.members.length === 1 ? '' : 's'}` : ''}`;
45
+ return (_jsxs("div", { style: {
46
+ width: NODE_W,
47
+ height: NODE_H,
48
+ boxSizing: 'border-box',
49
+ display: 'flex',
50
+ flexDirection: 'column',
51
+ justifyContent: 'center',
52
+ gap: 2,
53
+ padding: '8px 12px',
54
+ borderRadius: node.kind === 'actor' ? 20 : 8,
55
+ background: theme.colors.backgroundSecondary ?? theme.colors.background,
56
+ border: `2px ${node.kind === 'component' ? 'solid' : node.kind === 'container' ? 'solid' : 'dashed'} ${selected ? theme.colors.primary : kindColor}`,
57
+ boxShadow: '0 1px 4px rgba(0,0,0,0.25)',
58
+ cursor: 'pointer',
59
+ fontFamily: theme.fonts.body,
60
+ }, children: [_jsx("span", { style: {
61
+ fontFamily: theme.fonts.monospace,
62
+ fontSize: theme.fontSizes[0],
63
+ letterSpacing: 0.5,
64
+ textTransform: 'uppercase',
65
+ color: kindColor,
66
+ whiteSpace: 'nowrap',
67
+ overflow: 'hidden',
68
+ textOverflow: 'ellipsis',
69
+ }, children: tag }), _jsx("span", { style: {
70
+ fontWeight: 600,
71
+ fontSize: theme.fontSizes[2],
72
+ color: theme.colors.text,
73
+ whiteSpace: 'nowrap',
74
+ overflow: 'hidden',
75
+ textOverflow: 'ellipsis',
76
+ }, title: node.label, children: node.label }), _jsx("span", { style: {
77
+ fontFamily: theme.fonts.monospace,
78
+ fontSize: theme.fontSizes[0],
79
+ color: muted,
80
+ whiteSpace: 'nowrap',
81
+ overflow: 'hidden',
82
+ textOverflow: 'ellipsis',
83
+ }, title: node.members.join(', '), children: subtitle }), _jsx(Handle, { type: "target", position: Position.Left, style: { opacity: 0 } }), _jsx(Handle, { type: "source", position: Position.Right, style: { opacity: 0 } })] }));
84
+ }
85
+ function C4GroupView(props) {
86
+ const { theme } = useTheme();
87
+ const color = props.data.color;
88
+ return (_jsx("div", { style: {
89
+ width: '100%',
90
+ height: '100%',
91
+ boxSizing: 'border-box',
92
+ borderRadius: 12,
93
+ border: `2px dashed ${color}`,
94
+ background: 'transparent',
95
+ pointerEvents: 'none',
96
+ }, children: _jsx("span", { style: {
97
+ position: 'absolute',
98
+ top: 0,
99
+ transform: 'translateY(-50%)',
100
+ left: 12,
101
+ zIndex: 1,
102
+ fontFamily: theme.fonts.monospace,
103
+ fontSize: theme.fontSizes[2],
104
+ fontWeight: 600,
105
+ letterSpacing: 0.5,
106
+ textTransform: 'uppercase',
107
+ lineHeight: '18px',
108
+ color,
109
+ background: theme.colors.background,
110
+ boxShadow: `0 0 0 1.5px ${theme.colors.background}`,
111
+ border: `2px solid ${color}`,
112
+ borderRadius: 4,
113
+ padding: '4px 10px',
114
+ boxSizing: 'border-box',
115
+ whiteSpace: 'nowrap',
116
+ }, children: props.data.label }) }));
117
+ }
118
+ const nodeTypes = {
119
+ 'c4-node': C4NodeView,
120
+ 'c4-group': C4GroupView,
121
+ };
122
+ function Inner({ model, title, onSelectNode }) {
123
+ const { theme } = useTheme();
124
+ const { fitView } = useReactFlow();
125
+ const muted = theme.colors.textMuted ?? theme.colors.textSecondary;
126
+ const [nodes, setNodes] = useState([]);
127
+ const [rfEdges, setRfEdges] = useState([]);
128
+ const [ready, setReady] = useState(false);
129
+ const [selectedId, setSelectedId] = useState(null);
130
+ const layoutKey = useMemo(() => [
131
+ ...model.nodes.map((n) => `${n.id}\0${n.parentId ?? ''}\0${n.label}`).sort(),
132
+ ...model.groups.map((g) => `${g.id}\0${g.parentId ?? ''}\0${g.memberIds.length}`).sort(),
133
+ ...model.edges.map((e) => `${e.id}\0${e.count}`).sort(),
134
+ ].join('\n'), [model]);
135
+ useEffect(() => {
136
+ let alive = true;
137
+ setReady(false);
138
+ setSelectedId(null);
139
+ const rfNodes = model.nodes.map((n, i) => ({
140
+ id: n.id,
141
+ type: 'c4-node',
142
+ position: { x: (i % 4) * (NODE_W + 60), y: Math.floor(i / 4) * (NODE_H + 40) },
143
+ width: NODE_W,
144
+ height: NODE_H,
145
+ ...(n.parentId ? { parentId: n.parentId } : {}),
146
+ data: { node: n, selected: false },
147
+ }));
148
+ const groups = model.groups.map((g) => ({
149
+ id: g.id,
150
+ memberIds: g.memberIds,
151
+ ...(g.parentId ? { parentId: g.parentId } : {}),
152
+ }));
153
+ const rfEdges = model.edges.map((e) => {
154
+ const flow = e.kind === 'flow';
155
+ const color = flow ? edgeColor(e.mechanisms[0], muted) : (theme.colors.border ?? '#666');
156
+ return {
157
+ id: e.id,
158
+ source: e.source,
159
+ target: e.target,
160
+ label: e.label,
161
+ labelShowBg: false,
162
+ labelStyle: { fill: muted, fontSize: theme.fontSizes[0], fontFamily: theme.fonts.monospace },
163
+ style: {
164
+ stroke: color,
165
+ strokeWidth: 1 + Math.min(e.count, 6) * 0.4,
166
+ ...(flow ? { strokeDasharray: '6 4' } : {}),
167
+ },
168
+ markerEnd: { type: MarkerType.ArrowClosed, color, width: 18, height: 18 },
169
+ data: { edge: e },
170
+ };
171
+ });
172
+ void computeElkLayout(rfNodes, rfEdges, {
173
+ direction: 'RIGHT',
174
+ preserveNodePositions: false,
175
+ groups,
176
+ keepSingletonGroups: true,
177
+ })
178
+ .then((result) => {
179
+ if (!alive)
180
+ return;
181
+ const positioned = new Map(result.nodes.map((n) => [n.id, n]));
182
+ const builtGroups = new Set(result.groupBounds.keys());
183
+ const groupById = new Map(model.groups.map((g) => [g.id, g]));
184
+ const depthOf = (id) => {
185
+ let d = 0;
186
+ let g = groupById.get(id);
187
+ while (g?.parentId) {
188
+ d += 1;
189
+ g = groupById.get(g.parentId);
190
+ }
191
+ return d;
192
+ };
193
+ const shells = [...result.groupBounds.entries()]
194
+ .sort((a, b) => depthOf(a[0]) - depthOf(b[0]))
195
+ .map(([id, b]) => {
196
+ const def = groupById.get(id);
197
+ const parentId = def?.parentId && builtGroups.has(def.parentId) ? def.parentId : undefined;
198
+ return {
199
+ id,
200
+ type: 'c4-group',
201
+ position: { x: b.x, y: b.y },
202
+ width: Math.max(200, b.width),
203
+ height: Math.max(120, b.height),
204
+ draggable: false,
205
+ selectable: false,
206
+ ...(parentId ? { parentId } : {}),
207
+ data: {
208
+ label: def?.label ?? id,
209
+ kind: def?.kind ?? 'container',
210
+ color: def?.kind === 'system' ? (theme.colors.text ?? '#888') : (theme.colors.accent ?? theme.colors.info),
211
+ },
212
+ };
213
+ });
214
+ const leaves = rfNodes.map((n) => {
215
+ const p = positioned.get(n.id);
216
+ const node = p ? { ...n, position: { x: p.position.x, y: p.position.y } } : n;
217
+ const parentId = node.parentId;
218
+ if (parentId && !builtGroups.has(parentId)) {
219
+ const { parentId: _drop, ...rest } = node;
220
+ return rest;
221
+ }
222
+ return node;
223
+ });
224
+ setNodes([...shells, ...leaves]);
225
+ setRfEdges(rfEdges);
226
+ setReady(true);
227
+ requestAnimationFrame(() => fitView({ padding: 0.15 }));
228
+ })
229
+ .catch((err) => {
230
+ if (!alive)
231
+ return;
232
+ console.warn('[c4-graph] ELK layout failed, using grid:', err);
233
+ setNodes(rfNodes);
234
+ setRfEdges(rfEdges);
235
+ setReady(true);
236
+ requestAnimationFrame(() => fitView({ padding: 0.15 }));
237
+ });
238
+ return () => {
239
+ alive = false;
240
+ };
241
+ // eslint-disable-next-line react-hooks/exhaustive-deps
242
+ }, [layoutKey]);
243
+ const selected = useMemo(() => model.nodes.find((n) => n.id === selectedId) ?? null, [model, selectedId]);
244
+ const displayNodes = useMemo(() => nodes.map((n) => n.type === 'c4-node'
245
+ ? { ...n, data: { ...n.data, selected: n.id === selectedId } }
246
+ : n), [nodes, selectedId]);
247
+ const runtime = model.nodes.filter((n) => n.kind === 'container' || n.kind === 'component').length;
248
+ const outside = model.nodes.filter((n) => n.kind === 'external' || n.kind === 'actor').length;
249
+ return (_jsxs("div", { style: { position: 'relative', width: '100%', height: '100%', background: theme.colors.background }, children: [_jsx(GraphLayerStyle, {}), _jsx(ReactFlow, { nodes: displayNodes, edges: rfEdges, nodeTypes: nodeTypes, className: GRAPH_CANVAS_CLASS, ...GRAPH_NAV_PROPS, onNodeClick: (_e, node) => {
250
+ if (node.type !== 'c4-node')
251
+ return;
252
+ const next = node.id === selectedId ? null : node.id;
253
+ setSelectedId(next);
254
+ onSelectNode?.(next);
255
+ }, onPaneClick: () => {
256
+ setSelectedId(null);
257
+ onSelectNode?.(null);
258
+ }, proOptions: { hideAttribution: true }, children: _jsx(GraphChrome, {}) }), !ready && (_jsx("div", { style: {
259
+ position: 'absolute',
260
+ inset: 0,
261
+ display: 'flex',
262
+ alignItems: 'center',
263
+ justifyContent: 'center',
264
+ background: theme.colors.background,
265
+ color: muted,
266
+ fontFamily: theme.fonts.monospace,
267
+ fontSize: theme.fontSizes[0],
268
+ }, children: "Laying out C4 view\u2026" })), title && (_jsxs("div", { style: {
269
+ position: 'absolute',
270
+ top: 12,
271
+ left: 12,
272
+ fontSize: theme.fontSizes[2],
273
+ fontWeight: 600,
274
+ color: theme.colors.text,
275
+ background: theme.colors.backgroundSecondary ?? theme.colors.background,
276
+ border: `1px solid ${theme.colors.border ?? '#333'}`,
277
+ borderRadius: 6,
278
+ padding: '4px 10px',
279
+ }, children: [title, _jsxs("span", { style: { fontFamily: theme.fonts.monospace, fontSize: theme.fontSizes[0], color: muted, marginLeft: 8 }, children: [model.view, " view \u00B7 ", runtime, " ", model.view === 'container' ? 'containers' : 'components', " \u00B7 ", outside, " outside"] })] })), selected && (_jsxs("div", { style: {
280
+ position: 'absolute',
281
+ top: 12,
282
+ right: 12,
283
+ width: 280,
284
+ maxHeight: 'calc(100% - 24px)',
285
+ overflowY: 'auto',
286
+ background: theme.colors.backgroundSecondary ?? theme.colors.background,
287
+ border: `1px solid ${theme.colors.border ?? '#333'}`,
288
+ borderRadius: 8,
289
+ padding: '10px 12px',
290
+ }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 8 }, children: [_jsx("span", { style: { fontWeight: 600, color: theme.colors.text, flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }, children: selected.label }), _jsx("button", { type: "button", onClick: () => {
291
+ setSelectedId(null);
292
+ onSelectNode?.(null);
293
+ }, "aria-label": "Clear selection", style: { border: 'none', background: 'transparent', color: muted, cursor: 'pointer', fontSize: theme.fontSizes[2], lineHeight: 1 }, children: "\u00D7" })] }), _jsxs("div", { style: { fontFamily: theme.fonts.monospace, fontSize: theme.fontSizes[0], color: muted, margin: '4px 0 8px' }, children: [selected.kind, " \u00B7 ", selected.members.length, " component", selected.members.length === 1 ? '' : 's', selected.models && selected.models.length > 0 ? ` · ${selected.models.length} model${selected.models.length === 1 ? '' : 's'}` : ''] }), _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 2 }, children: selected.members.map((alias) => (_jsx("span", { title: alias, style: {
294
+ fontFamily: theme.fonts.monospace,
295
+ fontSize: theme.fontSizes[0],
296
+ color: theme.colors.text,
297
+ overflow: 'hidden',
298
+ textOverflow: 'ellipsis',
299
+ whiteSpace: 'nowrap',
300
+ }, children: alias }, alias))) })] }))] }));
301
+ }
302
+ export function C4Graph(props) {
303
+ return (_jsx(ReactFlowProvider, { children: _jsx(Inner, { ...props }) }));
304
+ }
305
+ //# sourceMappingURL=C4Graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"C4Graph.js","sourceRoot":"","sources":["../../src/subsystem/C4Graph.tsx"],"names":[],"mappings":"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"}
@@ -13,6 +13,8 @@
13
13
  import { type SubsystemWalkthrough } from './model';
14
14
  /** Pause (ms) between steps when a walkthrough autoplays. */
15
15
  export declare const WALKTHROUGH_PLAY_PAUSE_MS = 2500;
16
+ /** How long a step's copy button flashes its "copied" checkmark (ms). */
17
+ export declare const STEP_COPY_FEEDBACK_MS = 2000;
16
18
  export interface WalkthroughsPanelProps {
17
19
  /** Ordered walkthroughs — the list renders them in array order. */
18
20
  walkthroughs: SubsystemWalkthrough[];
@@ -1 +1 @@
1
- {"version":3,"file":"WalkthroughsPanel.d.ts","sourceRoot":"","sources":["../../src/subsystem/WalkthroughsPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;;AAMH,OAAO,EAKL,KAAK,oBAAoB,EAC1B,MAAM,SAAS,CAAC;AAEjB,6DAA6D;AAC7D,eAAO,MAAM,yBAAyB,OAAO,CAAC;AA4W9C,MAAM,WAAW,sBAAsB;IACrC,mEAAmE;IACnE,YAAY,EAAE,oBAAoB,EAAE,CAAC;IACrC,qDAAqD;IACrD,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAClC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,sBAAsB,EAAE;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,GAAG,IAAI,CAAC;IACT,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,EAAE,CAAC,EAAE,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAChD,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,EAAE,CAAC,EAAE,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACnE,WAAW,EAAE,CAAC,EAAE,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACnE,WAAW,EAAE,CAAC,EAAE,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAChD,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,IAAI,CAAC;IACnD;;;;OAIG;IACH,eAAe,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACvC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,SAAS,EACT,eAAe,GAChB,EAAE,sBAAsB,+BA0LxB"}
1
+ {"version":3,"file":"WalkthroughsPanel.d.ts","sourceRoot":"","sources":["../../src/subsystem/WalkthroughsPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;;AAMH,OAAO,EAKL,KAAK,oBAAoB,EAC1B,MAAM,SAAS,CAAC;AAGjB,6DAA6D;AAC7D,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,yEAAyE;AACzE,eAAO,MAAM,qBAAqB,OAAO,CAAC;AA+c1C,MAAM,WAAW,sBAAsB;IACrC,mEAAmE;IACnE,YAAY,EAAE,oBAAoB,EAAE,CAAC;IACrC,qDAAqD;IACrD,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAClC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,sBAAsB,EAAE;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,GAAG,IAAI,CAAC;IACT,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,EAAE,CAAC,EAAE,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAChD,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,EAAE,CAAC,EAAE,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACnE,WAAW,EAAE,CAAC,EAAE,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACnE,WAAW,EAAE,CAAC,EAAE,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAChD,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,IAAI,CAAC;IACnD;;;;OAIG;IACH,eAAe,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACvC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,SAAS,EACT,eAAe,GAChB,EAAE,sBAAsB,+BA0LxB"}
@@ -12,10 +12,15 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
12
12
  */
13
13
  import { useCallback, useEffect, useRef, useState } from 'react';
14
14
  import { useTheme } from '@principal-ade/industry-theme';
15
- import { ChevronDown, GripVertical, Pause, Play } from 'lucide-react';
15
+ import { Check, ChevronDown, Copy, GripVertical, Pause, Play } from 'lucide-react';
16
16
  import { PROPOSED_COLOR, reorderTargetIndex, reorderWalkthroughs, walkthroughStepGraphEdgeId, } from './model';
17
+ import { buildStepBrief } from './walkthroughBrief';
17
18
  /** Pause (ms) between steps when a walkthrough autoplays. */
18
19
  export const WALKTHROUGH_PLAY_PAUSE_MS = 2500;
20
+ /** How long a step's copy button flashes its "copied" checkmark (ms). */
21
+ export const STEP_COPY_FEEDBACK_MS = 2000;
22
+ /** Square size (px) of a walkthrough header's Play/Collapse control. */
23
+ const WALKTHROUGH_CONTROL_SIZE = 34;
19
24
  /** One collapsible walkthrough in the sidebar's flows panel. Clicking the
20
25
  * title: closed → open + select; open with a step selected → select the whole
21
26
  * flow (deselect the step, stay open); open with the whole flow selected →
@@ -35,6 +40,13 @@ function WalkthroughFlow({ walkthrough, collapsed, active, onToggleCollapsed, on
35
40
  const [gripHover, setGripHover] = useState(false);
36
41
  const [hoveredStep, setHoveredStep] = useState(null);
37
42
  const stepButtonRefs = useRef([]);
43
+ // Per-step copy affordance: revealed while a row is hovered or holds focus.
44
+ // `focusedStep` tracks focus-within (button or its copy control) so the icon
45
+ // stays put while the pointer or focus moves between them.
46
+ const [focusedStep, setFocusedStep] = useState(null);
47
+ const [copyHoverStep, setCopyHoverStep] = useState(null);
48
+ const [copiedStep, setCopiedStep] = useState(null);
49
+ const copyTimerRef = useRef(null);
38
50
  // Autoplay: stepping through the flow's steps with a pause between each.
39
51
  const [playing, setPlaying] = useState(false);
40
52
  const playTimerRef = useRef(null);
@@ -48,6 +60,30 @@ function WalkthroughFlow({ walkthrough, collapsed, active, onToggleCollapsed, on
48
60
  // Clear any pending timer on unmount.
49
61
  // eslint-disable-next-line react-hooks/exhaustive-deps
50
62
  useEffect(() => () => stopPlaying(), []);
63
+ const copyStep = useCallback((stepIndex) => {
64
+ const brief = buildStepBrief(walkthrough, stepIndex);
65
+ if (brief.length === 0)
66
+ return;
67
+ const clipboard = navigator.clipboard;
68
+ if (!clipboard)
69
+ return;
70
+ void clipboard
71
+ .writeText(brief)
72
+ .then(() => {
73
+ setCopiedStep(stepIndex);
74
+ if (copyTimerRef.current != null) {
75
+ window.clearTimeout(copyTimerRef.current);
76
+ }
77
+ copyTimerRef.current = window.setTimeout(() => setCopiedStep(null), STEP_COPY_FEEDBACK_MS);
78
+ })
79
+ .catch(() => {
80
+ // best-effort — show nothing when the clipboard is unavailable
81
+ });
82
+ }, [walkthrough]);
83
+ useEffect(() => () => {
84
+ if (copyTimerRef.current != null)
85
+ window.clearTimeout(copyTimerRef.current);
86
+ }, []);
51
87
  // Native HTML5 drag suppresses mouse events, so a row hovered when the drag
52
88
  // began never gets its mouseleave — its hover styling would stick after the
53
89
  // drop. Reset every row's hover whenever a drag starts or ends.
@@ -110,7 +146,8 @@ function WalkthroughFlow({ walkthrough, collapsed, active, onToggleCollapsed, on
110
146
  display: 'flex',
111
147
  alignItems: 'center',
112
148
  gap: 4,
113
- padding: '0 16px',
149
+ height: WALKTHROUGH_CONTROL_SIZE,
150
+ padding: '0 0 0 16px',
114
151
  background: wholeFlowActive || headerHover ? hoverBg : 'transparent',
115
152
  transition: 'background 120ms ease',
116
153
  }, children: [_jsx("button", { type: "button", onClick: () => {
@@ -133,7 +170,7 @@ function WalkthroughFlow({ walkthrough, collapsed, active, onToggleCollapsed, on
133
170
  display: 'flex',
134
171
  alignItems: 'center',
135
172
  minWidth: 0,
136
- padding: '10px 0',
173
+ padding: 0,
137
174
  border: 'none',
138
175
  background: 'transparent',
139
176
  textAlign: 'left',
@@ -154,11 +191,11 @@ function WalkthroughFlow({ walkthrough, collapsed, active, onToggleCollapsed, on
154
191
  alignItems: 'center',
155
192
  justifyContent: 'center',
156
193
  flexShrink: 0,
157
- width: 22,
158
- height: 22,
194
+ alignSelf: 'stretch',
195
+ width: WALKTHROUGH_CONTROL_SIZE,
159
196
  padding: 0,
160
197
  border: 'none',
161
- borderRadius: 4,
198
+ borderRadius: 0,
162
199
  background: playing || playHover ? theme.colors.border : 'transparent',
163
200
  color: playing || playHover ? theme.colors.text : muted,
164
201
  cursor: 'pointer',
@@ -173,11 +210,11 @@ function WalkthroughFlow({ walkthrough, collapsed, active, onToggleCollapsed, on
173
210
  alignItems: 'center',
174
211
  justifyContent: 'center',
175
212
  flexShrink: 0,
176
- width: 22,
177
- height: 22,
213
+ alignSelf: 'stretch',
214
+ width: WALKTHROUGH_CONTROL_SIZE,
178
215
  padding: 0,
179
216
  border: 'none',
180
- borderRadius: 4,
217
+ borderRadius: 0,
181
218
  background: collapseHover ? theme.colors.border : 'transparent',
182
219
  color: collapseHover ? theme.colors.text : muted,
183
220
  cursor: 'pointer',
@@ -189,7 +226,7 @@ function WalkthroughFlow({ walkthrough, collapsed, active, onToggleCollapsed, on
189
226
  display: 'inline-flex',
190
227
  alignItems: 'center',
191
228
  flexShrink: 0,
192
- marginRight: -8,
229
+ marginRight: 8,
193
230
  padding: '2px 0',
194
231
  color: gripHover || reorder.isDragging ? theme.colors.text : muted,
195
232
  cursor: reorder.isDragging ? 'grabbing' : 'grab',
@@ -200,45 +237,74 @@ function WalkthroughFlow({ walkthrough, collapsed, active, onToggleCollapsed, on
200
237
  }, children: walkthrough.steps.map((step, i) => {
201
238
  const stepActive = active !== null && active.stepIndex === i;
202
239
  const proposed = stepProposed(step.from, step.to);
203
- return (_jsxs("button", { ref: (el) => {
204
- stepButtonRefs.current[i] = el;
205
- }, type: "button", title: proposed ? 'Step touches a proposed component' : undefined, onMouseEnter: () => {
206
- setHoveredStep(i);
207
- onHoverStep(walkthrough, i);
208
- }, onClick: () => onFocusStep(walkthrough, i), style: {
209
- display: 'flex',
210
- alignItems: 'center',
211
- gap: 8,
212
- minWidth: 0,
213
- padding: '8px 8px 8px 17px',
214
- textAlign: 'left',
215
- borderRadius: 0,
216
- border: 'none',
217
- outline: 'none',
218
- background: stepActive || hoveredStep === i ? hoverBg : 'transparent',
219
- cursor: 'pointer',
220
- transition: 'background 120ms ease',
221
- }, children: [_jsx("span", { style: {
222
- flexShrink: 0,
223
- width: 14,
224
- fontSize: theme.fontSizes[0],
225
- fontFamily: theme.fonts.monospace,
226
- fontWeight: proposed ? 700 : undefined,
227
- color: proposed
228
- ? PROPOSED_COLOR
229
- : stepActive
230
- ? theme.colors.text
231
- : muted,
232
- }, children: i + 1 }), _jsx("span", { style: {
233
- flex: 1,
240
+ const revealed = stepActive || hoveredStep === i || focusedStep === i || copiedStep === i;
241
+ const copied = copiedStep === i;
242
+ const copyHovered = copyHoverStep === i;
243
+ return (_jsxs("div", { style: { position: 'relative' }, onFocus: () => setFocusedStep(i), onBlur: (e) => {
244
+ if (!e.currentTarget.contains(e.relatedTarget)) {
245
+ setFocusedStep((cur) => (cur === i ? null : cur));
246
+ }
247
+ }, children: [_jsxs("button", { ref: (el) => {
248
+ stepButtonRefs.current[i] = el;
249
+ }, type: "button", title: proposed ? 'Step touches a proposed component' : undefined, onMouseEnter: () => {
250
+ setHoveredStep(i);
251
+ onHoverStep(walkthrough, i);
252
+ }, onClick: () => onFocusStep(walkthrough, i), style: {
253
+ display: 'flex',
254
+ alignItems: 'center',
255
+ gap: 8,
234
256
  minWidth: 0,
235
- overflow: 'hidden',
236
- textOverflow: 'ellipsis',
237
- whiteSpace: 'nowrap',
238
- fontSize: theme.fontSizes[1],
239
- fontFamily: theme.fonts.monospace,
240
- color: proposed ? PROPOSED_COLOR : theme.colors.text,
241
- }, children: step.symbol })] }, `${walkthroughStepGraphEdgeId(step)}-${i}`));
257
+ width: '100%',
258
+ padding: '8px 36px 8px 17px',
259
+ textAlign: 'left',
260
+ borderRadius: 0,
261
+ border: 'none',
262
+ outline: 'none',
263
+ background: stepActive || hoveredStep === i ? hoverBg : 'transparent',
264
+ cursor: 'pointer',
265
+ transition: 'background 120ms ease',
266
+ }, children: [_jsx("span", { style: {
267
+ flexShrink: 0,
268
+ width: 14,
269
+ fontSize: theme.fontSizes[0],
270
+ fontFamily: theme.fonts.monospace,
271
+ fontWeight: proposed ? 700 : undefined,
272
+ color: proposed
273
+ ? PROPOSED_COLOR
274
+ : stepActive
275
+ ? theme.colors.text
276
+ : muted,
277
+ }, children: i + 1 }), _jsx("span", { style: {
278
+ flex: 1,
279
+ minWidth: 0,
280
+ overflow: 'hidden',
281
+ textOverflow: 'ellipsis',
282
+ whiteSpace: 'nowrap',
283
+ fontSize: theme.fontSizes[1],
284
+ fontFamily: theme.fonts.monospace,
285
+ color: proposed ? PROPOSED_COLOR : theme.colors.text,
286
+ }, children: step.symbol })] }), revealed && (_jsx("button", { type: "button", "aria-label": `Copy step ${i + 1} of ${walkthrough.title} for an agent`, title: copied ? 'Copied' : 'Copy this step for an agent', onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => setCopyHoverStep(i), onMouseLeave: () => setCopyHoverStep((cur) => (cur === i ? null : cur)), onClick: () => copyStep(i), style: {
287
+ position: 'absolute',
288
+ right: 0,
289
+ top: 0,
290
+ bottom: 0,
291
+ display: 'inline-flex',
292
+ alignItems: 'center',
293
+ justifyContent: 'center',
294
+ width: 'auto',
295
+ aspectRatio: '1 / 1',
296
+ padding: 0,
297
+ border: 'none',
298
+ borderRadius: 0,
299
+ background: copied
300
+ ? 'rgba(16,185,129,0.12)'
301
+ : copyHovered
302
+ ? theme.colors.border
303
+ : 'transparent',
304
+ color: copied ? '#10b981' : copyHovered ? theme.colors.text : muted,
305
+ cursor: 'pointer',
306
+ transition: 'background 120ms ease, color 120ms ease',
307
+ }, children: copied ? (_jsx(Check, { size: 12, strokeWidth: 2 })) : (_jsx(Copy, { size: 12, strokeWidth: 2 })) }))] }, `${walkthroughStepGraphEdgeId(step)}-${i}`));
242
308
  }) }))] }));
243
309
  }
244
310
  /**