mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-31 16:21:50 +03:00
style(tui): keep short transcripts and composer top-aligned
This commit is contained in:
@@ -14,6 +14,7 @@ import type {
|
|||||||
WorkspaceScopePayload,
|
WorkspaceScopePayload,
|
||||||
} from "./protocol"
|
} from "./protocol"
|
||||||
import type { HostAgentState, HostMetadata, TuiHost } from "./host"
|
import type { HostAgentState, HostMetadata, TuiHost } from "./host"
|
||||||
|
import type { Transcript } from "./transcript"
|
||||||
|
|
||||||
const options: AppOptions = {
|
const options: AppOptions = {
|
||||||
wsUrl: "ws://localhost.invalid/ws",
|
wsUrl: "ws://localhost.invalid/ws",
|
||||||
@@ -123,6 +124,45 @@ describe("NanobotTui layout", () => {
|
|||||||
|
|
||||||
const createRenderer = (options: Parameters<typeof createTestRenderer>[0]) => createTestRenderer(options)
|
const createRenderer = (options: Parameters<typeof createTestRenderer>[0]) => createTestRenderer(options)
|
||||||
|
|
||||||
|
test("keeps short transcripts and the composer anchored at the top", async () => {
|
||||||
|
setup = await createRenderer({
|
||||||
|
width: 100,
|
||||||
|
height: 18,
|
||||||
|
screenMode: "alternate-screen",
|
||||||
|
consoleMode: "disabled",
|
||||||
|
})
|
||||||
|
const app = mount(setup)
|
||||||
|
const ui = app as unknown as {
|
||||||
|
transcript: Transcript
|
||||||
|
title: BoxRenderable
|
||||||
|
status: TextRenderable
|
||||||
|
}
|
||||||
|
const positions = () => ({
|
||||||
|
transcriptHeight: ui.transcript.root.height,
|
||||||
|
titleY: ui.title.y,
|
||||||
|
statusY: ui.status.y,
|
||||||
|
})
|
||||||
|
|
||||||
|
let anchoredPositions: ReturnType<typeof positions> | undefined
|
||||||
|
for (const height of [18, 30, 36]) {
|
||||||
|
setup.resize(100, height)
|
||||||
|
await setup.renderOnce()
|
||||||
|
expect(ui.title.y).toBe(ui.transcript.root.y + ui.transcript.root.height)
|
||||||
|
expect(ui.status.y + ui.status.height).toBeLessThan(setup.renderer.height)
|
||||||
|
if (!anchoredPositions) anchoredPositions = positions()
|
||||||
|
else expect(positions()).toEqual(anchoredPositions)
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.transcript.user("A short prompt")
|
||||||
|
await setup.renderOnce()
|
||||||
|
const promptPositions = positions()
|
||||||
|
expect(promptPositions.titleY).toBeGreaterThan(anchoredPositions?.titleY || 0)
|
||||||
|
|
||||||
|
setup.resize(100, 40)
|
||||||
|
await setup.renderOnce()
|
||||||
|
expect(positions()).toEqual(promptPositions)
|
||||||
|
})
|
||||||
|
|
||||||
test("reflows a single retained layout across terminal resizes", async () => {
|
test("reflows a single retained layout across terminal resizes", async () => {
|
||||||
setup = await createRenderer({
|
setup = await createRenderer({
|
||||||
width: 100,
|
width: 100,
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ export class Transcript {
|
|||||||
id: "nanobot-tui-transcript",
|
id: "nanobot-tui-transcript",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
minHeight: 0,
|
minHeight: 0,
|
||||||
flexGrow: 1,
|
flexGrow: 0,
|
||||||
scrollX: false,
|
scrollX: false,
|
||||||
scrollY: true,
|
scrollY: true,
|
||||||
stickyScroll: true,
|
stickyScroll: true,
|
||||||
@@ -99,6 +99,7 @@ export class Transcript {
|
|||||||
viewportCulling: true,
|
viewportCulling: true,
|
||||||
contentOptions: {
|
contentOptions: {
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
|
minHeight: 0,
|
||||||
paddingTop: 1,
|
paddingTop: 1,
|
||||||
paddingBottom: 1,
|
paddingBottom: 1,
|
||||||
paddingLeft: 1,
|
paddingLeft: 1,
|
||||||
|
|||||||
Reference in New Issue
Block a user