fix(web): preserve expanded structured cards

This commit is contained in:
Miguel Palhas
2026-09-05 10:29:40 +01:00
parent 12bd68a2af
commit 31b429a840
3 changed files with 113 additions and 6 deletions
+25 -3
View File
@@ -106,6 +106,7 @@ export function createStructuredConnection(
let rows: TranscriptRow[] = [];
const rowIndex = new Map<string, number>();
const rowEls = new Map<string, HTMLElement>();
const expandedRowIds = new Set<string>();
let state: ReducedState = { turn: idleTurn() };
let pendingApprovalRowId: string | null = null;
let latestSession: Session | undefined = store?.snapshot().sessions.get(sessionId);
@@ -151,8 +152,24 @@ export function createStructuredConnection(
}
}
function buildRowElement(row: TranscriptRow): HTMLElement {
const el = buildTranscriptRow(
row,
approvalStateFor(row),
expandedRowIds.has(row.id),
(expanded) => {
if (expanded) expandedRowIds.add(row.id);
else expandedRowIds.delete(row.id);
},
);
if (el.querySelector(".st-tool-head")?.getAttribute("aria-expanded") !== "true") {
expandedRowIds.delete(row.id);
}
return el;
}
function mountRow(row: TranscriptRow): void {
const el = buildTranscriptRow(row, approvalStateFor(row));
const el = buildRowElement(row);
rowEls.set(row.id, el);
rowsEl.appendChild(el);
}
@@ -160,9 +177,8 @@ export function createStructuredConnection(
function remountRow(row: TranscriptRow): void {
const old = rowEls.get(row.id);
const oldToolHead = old?.querySelector<HTMLButtonElement>(".st-tool-head") ?? null;
const wasExpanded = oldToolHead?.getAttribute("aria-expanded") === "true";
const restoreFocus = document.activeElement === oldToolHead;
const el = buildTranscriptRow(row, approvalStateFor(row), wasExpanded);
const el = buildRowElement(row);
rowEls.set(row.id, el);
if (old) old.replaceWith(el);
else rowsEl.appendChild(el);
@@ -172,6 +188,10 @@ export function createStructuredConnection(
function applySnapshot(snapshot: { rows: TranscriptRow[] }): void {
rows = [...snapshot.rows];
const expandableIds = new Set(
rows.filter((row) => row.kind === "tool_call" || row.kind === "tool_diff").map((row) => row.id),
);
for (const id of expandedRowIds) if (!expandableIds.has(id)) expandedRowIds.delete(id);
rowIndex.clear();
rows.forEach((row, i) => rowIndex.set(row.id, i));
rowEls.clear();
@@ -199,6 +219,7 @@ export function createStructuredConnection(
const i = rowIndex.get(delta.id);
if (i === undefined) return;
rows.splice(i, 1);
expandedRowIds.delete(delta.id);
rowIndex.clear();
rows.forEach((row, idx) => rowIndex.set(row.id, idx));
rowEls.get(delta.id)?.remove();
@@ -482,6 +503,7 @@ export function createStructuredConnection(
resizeObserver.disconnect();
unsubscribeStore?.();
closeCurrentSocket();
expandedRowIds.clear();
el.remove();
},
};