fix: extend transcript hover surfaces

This commit is contained in:
Miguel Palhas
2026-09-06 15:26:31 +01:00
parent 22d740a36b
commit b5c9970e28
4 changed files with 36 additions and 28 deletions
+1 -1
View File
@@ -725,7 +725,7 @@ describe("structured connection: reconnection/error/loading", () => {
});
const transcript = conn.el.querySelector(".structured-rows")!;
expect(transcript.textContent).toBe("Younew");
expect(transcript.textContent).toBe("new");
expect(transcript.querySelector('[data-row-id="plan"]')).toBeNull();
expect(conn.el.querySelector(".structured-rail")).toBeNull();
conn.dispose();
+4 -4
View File
@@ -23,6 +23,7 @@ describe("buildTranscriptRow: user/agent/thought", () => {
);
expect(el.className).toContain("st-row-user");
expect(el.textContent).toContain("hi <b>there</b>");
expect(el.querySelector(".st-who")).toBeNull();
// never actual markup from user input
expect(el.querySelector("b")).toBeNull();
});
@@ -61,12 +62,11 @@ describe("buildTranscriptRow: user/agent/thought", () => {
const el = buildTranscriptRow(
row("agent_text", { content: { type: "text", text: "copy **this** exactly" } }),
);
const body = el.querySelector<HTMLElement>(".st-body")!;
expect(body.getAttribute("role")).toBe("button");
body.click();
expect(el.getAttribute("role")).toBe("button");
el.click();
await Promise.resolve();
expect(writeText).toHaveBeenCalledWith("copy **this** exactly");
body.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter", bubbles: true }));
el.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter", bubbles: true }));
await Promise.resolve();
expect(writeText).toHaveBeenCalledTimes(2);
});
+3 -7
View File
@@ -175,21 +175,17 @@ function buildContentRow(row: TranscriptRow, variant: "user" | "agent" | "though
const wrap = el("div", `st-row st-row-${variant}`);
const body = el("div", "st-body");
if (variant === "user") {
const who = el("div", "st-who");
who.textContent = "You";
body.appendChild(who);
const line = el("div", "st-user-text");
line.textContent = text;
makeCopyable(line, text, "message");
body.appendChild(line);
} else if (variant === "agent") {
renderProse(body, text);
makeCopyable(body, text, "response");
} else {
body.textContent = text;
makeCopyable(body, text, "thought");
}
wrap.appendChild(body);
const label = variant === "user" ? "message" : variant === "agent" ? "response" : "thought";
makeCopyable(wrap, text, label);
return wrap;
}
@@ -404,8 +400,8 @@ function buildPlainRow(row: TranscriptRow): HTMLElement {
const wrap = el("div", "st-row st-row-notice");
const body = el("div", "st-body");
body.textContent = `[${row.kind}]`;
makeCopyable(body, body.textContent, "notice");
wrap.appendChild(body);
makeCopyable(wrap, body.textContent, "notice");
return wrap;
}
+28 -16
View File
@@ -2203,10 +2203,8 @@ input.leaf-rename:focus {
}
.structured-rows {
padding: var(--sp-3);
display: flex;
flex-direction: column;
gap: var(--sp-3);
min-width: 0;
}
@@ -2214,6 +2212,7 @@ input.leaf-rename:focus {
.st-row {
display: flex;
gap: var(--sp-3);
padding: var(--sp-3);
min-width: 0;
}
@@ -2222,20 +2221,22 @@ input.leaf-rename:focus {
min-width: 0;
}
/* user turn: the only tinted block besides the approval — an accent rail,
never a full border, so it still reads lighter than the approval card. */
/* User turns read as compact chat bubbles while the padded row remains the
full hover/copy target. */
.st-row-user {
border-left: 2px solid var(--accent);
background: var(--surface-2);
padding: var(--sp-3);
justify-content: flex-end;
}
.st-who {
font-size: var(--fs-11);
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--faint);
margin-bottom: var(--sp-1);
.st-row-user .st-body {
flex: 0 1 auto;
max-width: min(86%, 72ch);
padding: var(--sp-2) var(--sp-3);
border-radius: var(--r-2);
background: var(--surface-3);
}
.st-row-user:hover {
background: var(--surface-2);
}
.st-user-text {
@@ -2322,6 +2323,7 @@ input.leaf-rename:focus {
/* tool rows: bordered, compact, deliberately not lifted */
.st-tool {
flex: 1 1 auto;
border: 1px solid var(--border);
border-radius: var(--r-2);
min-width: 0;
@@ -2346,6 +2348,11 @@ input.leaf-rename:focus {
background: var(--surface-2);
}
.st-row-tool:hover,
.st-row-approval:hover {
background: var(--surface-2);
}
.st-tool-glyph {
width: 16px;
flex: 0 0 auto;
@@ -2436,6 +2443,12 @@ input.leaf-rename:focus {
border: 1px solid var(--border);
border-radius: var(--r-2);
background: color-mix(in oklab, var(--surface-2) 55%, transparent);
padding: var(--sp-2) var(--sp-3);
transition: background var(--dur-fast) var(--ease-out);
}
.st-tool-group:hover {
background: var(--surface-2);
}
.st-tool-group-head {
@@ -2449,7 +2462,7 @@ input.leaf-rename:focus {
display: flex;
align-items: center;
gap: var(--sp-2);
padding: var(--sp-2) var(--sp-3);
padding: 0;
min-width: 0;
}
@@ -2481,10 +2494,9 @@ input.leaf-rename:focus {
}
.st-tool-group-body {
padding: 0 var(--sp-2) var(--sp-2);
padding-top: var(--sp-2);
display: flex;
flex-direction: column;
gap: var(--sp-2);
}
.st-tool-group-body[hidden] {