fix(web): separate transcript scrolling from composer

This commit is contained in:
Miguel Palhas
2026-09-06 14:01:43 +01:00
parent 913421e244
commit a771d29210
3 changed files with 30 additions and 11 deletions
+12
View File
@@ -1227,6 +1227,18 @@ describe("structured connection: transcript scrolling", () => {
describe("structured connection: pane lifecycle", () => {
beforeEach(() => vi.clearAllMocks());
it("keeps the composer outside the transcript scroll region", () => {
const conn = mount({ sockets: [new FakeSocket()] });
const main = conn.el.querySelector(".structured-main")!;
const scroll = conn.el.querySelector(".structured-scroll")!;
const composer = conn.el.querySelector(".structured-composer")!;
expect(main.contains(scroll)).toBe(true);
expect(main.contains(composer)).toBe(true);
expect(scroll.contains(composer)).toBe(false);
conn.dispose();
});
it("sendInput is a no-op — there is no PTY behind a structured session", () => {
const conn = mount({ sockets: [new FakeSocket()] });
expect(() => conn.sendInput("\x0b")).not.toThrow();
+4 -2
View File
@@ -65,8 +65,10 @@ export function createStructuredConnection(
<button class="btn btn-ghost btn-icon disconnect" type="button" aria-label="Disconnect" title="Disconnect this session">⏻</button>
</header>
<div class="structured-body">
<div class="structured-scroll">
<div class="structured-rows"></div>
<div class="structured-main">
<div class="structured-scroll">
<div class="structured-rows"></div>
</div>
<form class="structured-composer">
<textarea class="structured-input" rows="1" placeholder="Reply, or / for commands…"></textarea>
<button type="submit" class="btn btn-primary structured-send">Send</button>
+14 -9
View File
@@ -2193,7 +2193,7 @@ input.leaf-rename:focus {
grid-template-rows: auto minmax(0, 1fr);
}
.structured-body.st-narrow .structured-scroll {
.structured-body.st-narrow .structured-main {
grid-row: 2;
}
@@ -2204,16 +2204,22 @@ input.leaf-rename:focus {
max-height: 40%;
}
.structured-scroll {
.structured-main {
min-width: 0;
overflow-y: auto;
min-height: 0;
display: flex;
flex-direction: column;
}
.structured-scroll {
flex: 1 1 auto;
min-height: 0;
min-width: 0;
overflow-y: auto;
}
.structured-rows {
flex: 1 0 auto;
padding: var(--sp-3) var(--sp-3) 0;
padding: var(--sp-3);
display: flex;
flex-direction: column;
gap: var(--sp-3);
@@ -2616,11 +2622,10 @@ input.leaf-rename:focus {
border-color: var(--danger);
}
/* composer: sticky at the bottom of the scrolling transcript column */
/* The composer is a sibling of the scrolling transcript, not part of it: it
stays reachable at the pane edge without changing transcript scroll math. */
.structured-composer {
position: sticky;
bottom: 0;
margin-top: var(--sp-3);
flex: 0 0 auto;
padding: var(--sp-3);
border-top: 1px solid var(--border);
background: var(--surface);