mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-31 16:21:50 +03:00
fix(tui): suppress terminal scrollbar glyphs
This commit is contained in:
@@ -20,6 +20,18 @@ const options: AppOptions = {
|
||||
theme: "auto",
|
||||
}
|
||||
|
||||
interface HiddenScrollBar {
|
||||
visible: boolean
|
||||
slider: { visible: boolean }
|
||||
startArrow: { visible: boolean }
|
||||
endArrow: { visible: boolean }
|
||||
}
|
||||
|
||||
interface HiddenScrollBox {
|
||||
verticalScrollBar: HiddenScrollBar
|
||||
horizontalScrollBar: HiddenScrollBar
|
||||
}
|
||||
|
||||
function occurrences(frame: string, value: string): number {
|
||||
return frame.split(value).length - 1
|
||||
}
|
||||
@@ -718,6 +730,8 @@ describe("NanobotTui layout", () => {
|
||||
shell: { backgroundColor: { intent: string } }
|
||||
composerFrame: { backgroundColor: { intent: string } }
|
||||
composer: { backgroundColor: { intent: string } }
|
||||
transcript: { root: HiddenScrollBox }
|
||||
diffViewer: { scroll: HiddenScrollBox }
|
||||
}
|
||||
const lines = setup.captureSpans().lines
|
||||
const spans = lines.flatMap((line) => line.spans)
|
||||
@@ -730,6 +744,14 @@ describe("NanobotTui layout", () => {
|
||||
expect(internals.composer.backgroundColor.intent).toBe("default")
|
||||
expect(spans.length).toBeGreaterThan(0)
|
||||
expect(brandedRows).toHaveLength(0)
|
||||
for (const scrollBox of [internals.transcript.root, internals.diffViewer.scroll]) {
|
||||
for (const bar of [scrollBox.verticalScrollBar, scrollBox.horizontalScrollBar]) {
|
||||
expect(bar.visible).toBeFalse()
|
||||
expect(bar.slider.visible).toBeFalse()
|
||||
expect(bar.startArrow.visible).toBeFalse()
|
||||
expect(bar.endArrow.visible).toBeFalse()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test("rethemes the complete retained interface when the terminal appearance changes", async () => {
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from "@opentui/core"
|
||||
|
||||
import type { FileEditEvent, HistoryMessage } from "./protocol"
|
||||
import { hideScrollbars } from "./scrollbox"
|
||||
|
||||
export interface DiffViewerTheme {
|
||||
text: string
|
||||
@@ -152,9 +153,10 @@ export class DiffViewer {
|
||||
paddingTop: 1,
|
||||
paddingBottom: 1,
|
||||
},
|
||||
verticalScrollbarOptions: { visible: true },
|
||||
verticalScrollbarOptions: { visible: false },
|
||||
horizontalScrollbarOptions: { visible: false },
|
||||
})
|
||||
hideScrollbars(this.scroll)
|
||||
this.footer = new TextRenderable(renderer, {
|
||||
id: "nanobot-tui-diff-footer",
|
||||
content: "←/→ file · pgup/pgdn scroll · esc close",
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import type { ScrollBoxRenderable } from "@opentui/core"
|
||||
|
||||
/** Keep scrolling functional without drawing terminal-dependent block glyphs. */
|
||||
export function hideScrollbars(scrollBox: ScrollBoxRenderable): void {
|
||||
for (const bar of [scrollBox.verticalScrollBar, scrollBox.horizontalScrollBar]) {
|
||||
// ScrollBar can make itself visible again when content starts overflowing.
|
||||
// Hiding its children as well keeps embedded terminals deterministic.
|
||||
bar.visible = false
|
||||
bar.showArrows = false
|
||||
bar.slider.visible = false
|
||||
bar.startArrow.visible = false
|
||||
bar.endArrow.visible = false
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from "@opentui/core"
|
||||
|
||||
import type { FileEditEvent, HistoryMessage, ToolProgressEvent } from "./protocol"
|
||||
import { hideScrollbars } from "./scrollbox"
|
||||
|
||||
export interface TranscriptTheme {
|
||||
text: string
|
||||
@@ -88,8 +89,7 @@ export class Transcript {
|
||||
horizontalScrollbarOptions: { visible: false },
|
||||
onMouseScroll: () => this.scheduleNavigationUpdate(),
|
||||
})
|
||||
this.root.verticalScrollBar.visible = false
|
||||
this.root.horizontalScrollBar.visible = false
|
||||
hideScrollbars(this.root)
|
||||
}
|
||||
|
||||
setTheme(theme: TranscriptTheme): void {
|
||||
@@ -151,7 +151,7 @@ export class Transcript {
|
||||
this.wrote = false
|
||||
this.nextId = 0
|
||||
this.navigation = { awayFromBottom: false, unseenOutput: false }
|
||||
this.root.verticalScrollBar.visible = false
|
||||
hideScrollbars(this.root)
|
||||
this.header(header)
|
||||
this.emitNavigation()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user