@gajae-code/tui 0.7.1 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/types/tui.d.ts +1 -0
- package/package.json +3 -3
- package/src/tui.ts +35 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.7.3] - 2026-06-25
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added bottom-pinned TUI layout support so short initial screens can pad above composer/status components and keep the prompt anchored to the terminal viewport bottom (#1120).
|
|
10
|
+
|
|
5
11
|
## [0.6.0] - 2026-06-18
|
|
6
12
|
|
|
7
13
|
### Fixed
|
package/dist/types/tui.d.ts
CHANGED
|
@@ -156,6 +156,7 @@ export declare class TUI extends Container {
|
|
|
156
156
|
*/
|
|
157
157
|
setClearOnShrink(enabled: boolean): void;
|
|
158
158
|
setFocus(component: Component | null): void;
|
|
159
|
+
setBottomPinnedComponent(component: Component | null): void;
|
|
159
160
|
/**
|
|
160
161
|
* Show an overlay component with configurable positioning and sizing.
|
|
161
162
|
* Returns a handle to control the overlay's visibility.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/tui",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.3",
|
|
5
5
|
"description": "Terminal User Interface library with differential rendering for efficient text-based applications",
|
|
6
6
|
"homepage": "https://gaebal-gajae.dev",
|
|
7
7
|
"author": "Yeachan-Heo",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"fmt": "biome format --write ."
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@gajae-code/natives": "0.7.
|
|
42
|
-
"@gajae-code/utils": "0.7.
|
|
41
|
+
"@gajae-code/natives": "0.7.3",
|
|
42
|
+
"@gajae-code/utils": "0.7.3",
|
|
43
43
|
"lru-cache": "11.3.6",
|
|
44
44
|
"marked": "^18.0.3"
|
|
45
45
|
},
|
package/src/tui.ts
CHANGED
|
@@ -321,6 +321,7 @@ export class TUI extends Container {
|
|
|
321
321
|
#fullRedrawCount = 0;
|
|
322
322
|
#stopped = false;
|
|
323
323
|
#terminalUnavailable = false;
|
|
324
|
+
#bottomPinnedComponent: Component | null = null;
|
|
324
325
|
|
|
325
326
|
// Overlay stack for modal components rendered on top of base content
|
|
326
327
|
overlayStack: {
|
|
@@ -382,6 +383,11 @@ export class TUI extends Container {
|
|
|
382
383
|
}
|
|
383
384
|
}
|
|
384
385
|
|
|
386
|
+
setBottomPinnedComponent(component: Component | null): void {
|
|
387
|
+
this.#bottomPinnedComponent = component;
|
|
388
|
+
this.requestRender();
|
|
389
|
+
}
|
|
390
|
+
|
|
385
391
|
/**
|
|
386
392
|
* Show an overlay component with configurable positioning and sizing.
|
|
387
393
|
* Returns a handle to control the overlay's visibility.
|
|
@@ -1269,6 +1275,31 @@ export class TUI extends Container {
|
|
|
1269
1275
|
return lines;
|
|
1270
1276
|
}
|
|
1271
1277
|
|
|
1278
|
+
#padBeforeBottomPinnedComponent(lines: string[], height: number): string[] {
|
|
1279
|
+
const component = this.#bottomPinnedComponent;
|
|
1280
|
+
if (component === null || lines.length >= height) return lines;
|
|
1281
|
+
|
|
1282
|
+
let pinnedStart = -1;
|
|
1283
|
+
for (let i = this.children.length - 1; i >= 0; i--) {
|
|
1284
|
+
if (this.children[i] === component) {
|
|
1285
|
+
pinnedStart = i;
|
|
1286
|
+
break;
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
if (pinnedStart < 0) return lines;
|
|
1290
|
+
|
|
1291
|
+
let pinnedLineCount = 0;
|
|
1292
|
+
for (let i = pinnedStart; i < this.children.length; i++) {
|
|
1293
|
+
pinnedLineCount += this.children[i].render(this.terminal.columns).length;
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
const blankRows = height - lines.length;
|
|
1297
|
+
const insertAt = Math.max(0, lines.length - pinnedLineCount);
|
|
1298
|
+
const padded = [...lines];
|
|
1299
|
+
padded.splice(insertAt, 0, ...Array.from({ length: blankRows }, () => ""));
|
|
1300
|
+
return padded;
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1272
1303
|
#doRender(): void {
|
|
1273
1304
|
if (this.#stopped || !this.terminalAvailable) return;
|
|
1274
1305
|
const width = this.terminal.columns;
|
|
@@ -1287,6 +1318,10 @@ export class TUI extends Container {
|
|
|
1287
1318
|
let newLines = this.render(width);
|
|
1288
1319
|
if (renderMetrics.enabled) renderMetrics.recordHelper("renderTree", renderMetrics.now() - renderTreeStart);
|
|
1289
1320
|
|
|
1321
|
+
if (this.#bottomPinnedComponent !== null && height > 0) {
|
|
1322
|
+
newLines = this.#padBeforeBottomPinnedComponent(newLines, height);
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1290
1325
|
// Composite overlays into the rendered lines (before differential compare)
|
|
1291
1326
|
if (this.overlayStack.length > 0) {
|
|
1292
1327
|
newLines = this.#compositeOverlays(newLines, width, height);
|