voonex 0.1.0
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/LICENSE +21 -0
- package/README.md +223 -0
- package/dist/components/Box.d.ts +33 -0
- package/dist/components/Box.js +242 -0
- package/dist/components/Button.d.ts +23 -0
- package/dist/components/Button.js +76 -0
- package/dist/components/Checkbox.d.ts +20 -0
- package/dist/components/Checkbox.js +40 -0
- package/dist/components/Input.d.ts +23 -0
- package/dist/components/Input.js +79 -0
- package/dist/components/Menu.d.ts +27 -0
- package/dist/components/Menu.js +93 -0
- package/dist/components/Popup.d.ts +7 -0
- package/dist/components/Popup.js +50 -0
- package/dist/components/ProgressBar.d.ts +28 -0
- package/dist/components/ProgressBar.js +47 -0
- package/dist/components/Radio.d.ts +22 -0
- package/dist/components/Radio.js +64 -0
- package/dist/components/Select.d.ts +24 -0
- package/dist/components/Select.js +126 -0
- package/dist/components/Tab.d.ts +24 -0
- package/dist/components/Tab.js +72 -0
- package/dist/components/Table.d.ts +25 -0
- package/dist/components/Table.js +116 -0
- package/dist/components/Textarea.d.ts +26 -0
- package/dist/components/Textarea.js +176 -0
- package/dist/components/Tree.d.ts +33 -0
- package/dist/components/Tree.js +166 -0
- package/dist/core/Component.d.ts +6 -0
- package/dist/core/Component.js +5 -0
- package/dist/core/Cursor.d.ts +7 -0
- package/dist/core/Cursor.js +59 -0
- package/dist/core/Events.d.ts +11 -0
- package/dist/core/Events.js +37 -0
- package/dist/core/Focus.d.ts +16 -0
- package/dist/core/Focus.js +69 -0
- package/dist/core/Input.d.ts +13 -0
- package/dist/core/Input.js +88 -0
- package/dist/core/Layout.d.ts +18 -0
- package/dist/core/Layout.js +65 -0
- package/dist/core/Screen.d.ts +78 -0
- package/dist/core/Screen.js +373 -0
- package/dist/core/Styler.d.ts +71 -0
- package/dist/core/Styler.js +157 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +41 -0
- package/package.json +29 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ==========================================
|
|
3
|
+
// CORE: CURSOR MANAGEMENT
|
|
4
|
+
// ==========================================
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.Cursor = void 0;
|
|
40
|
+
const readline = __importStar(require("readline"));
|
|
41
|
+
class Cursor {
|
|
42
|
+
static hide() {
|
|
43
|
+
process.stdout.write('\x1b[?25l');
|
|
44
|
+
}
|
|
45
|
+
static show() {
|
|
46
|
+
process.stdout.write('\x1b[?25h');
|
|
47
|
+
}
|
|
48
|
+
static moveTo(x, y) {
|
|
49
|
+
readline.cursorTo(process.stdout, x, y);
|
|
50
|
+
}
|
|
51
|
+
static clearLine() {
|
|
52
|
+
readline.clearLine(process.stdout, 0);
|
|
53
|
+
}
|
|
54
|
+
static clearScreen() {
|
|
55
|
+
readline.cursorTo(process.stdout, 0, 0);
|
|
56
|
+
readline.clearScreenDown(process.stdout);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.Cursor = Cursor;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type EventHandler = (data?: any) => void;
|
|
2
|
+
export declare class EventManager {
|
|
3
|
+
private static instance;
|
|
4
|
+
private listeners;
|
|
5
|
+
private constructor();
|
|
6
|
+
static getInstance(): EventManager;
|
|
7
|
+
on(event: string, handler: EventHandler): void;
|
|
8
|
+
off(event: string, handler: EventHandler): void;
|
|
9
|
+
emit(event: string, data?: any): void;
|
|
10
|
+
}
|
|
11
|
+
export declare const Events: EventManager;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ==========================================
|
|
3
|
+
// CORE: EVENT MANAGER
|
|
4
|
+
// ==========================================
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Events = exports.EventManager = void 0;
|
|
7
|
+
class EventManager {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.listeners = new Map();
|
|
10
|
+
}
|
|
11
|
+
static getInstance() {
|
|
12
|
+
if (!EventManager.instance) {
|
|
13
|
+
EventManager.instance = new EventManager();
|
|
14
|
+
}
|
|
15
|
+
return EventManager.instance;
|
|
16
|
+
}
|
|
17
|
+
on(event, handler) {
|
|
18
|
+
if (!this.listeners.has(event)) {
|
|
19
|
+
this.listeners.set(event, []);
|
|
20
|
+
}
|
|
21
|
+
this.listeners.get(event).push(handler);
|
|
22
|
+
}
|
|
23
|
+
off(event, handler) {
|
|
24
|
+
if (!this.listeners.has(event))
|
|
25
|
+
return;
|
|
26
|
+
const handlers = this.listeners.get(event);
|
|
27
|
+
this.listeners.set(event, handlers.filter(h => h !== handler));
|
|
28
|
+
}
|
|
29
|
+
emit(event, data) {
|
|
30
|
+
if (!this.listeners.has(event))
|
|
31
|
+
return;
|
|
32
|
+
this.listeners.get(event).forEach(handler => handler(data));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.EventManager = EventManager;
|
|
36
|
+
// Global accessor
|
|
37
|
+
exports.Events = EventManager.getInstance();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as readline from 'readline';
|
|
2
|
+
export interface Focusable {
|
|
3
|
+
id: string;
|
|
4
|
+
parent?: Focusable;
|
|
5
|
+
focus(): void;
|
|
6
|
+
blur(): void;
|
|
7
|
+
handleKey(key: readline.Key): boolean | void;
|
|
8
|
+
render(): void;
|
|
9
|
+
}
|
|
10
|
+
export declare class FocusManager {
|
|
11
|
+
private components;
|
|
12
|
+
private activeIndex;
|
|
13
|
+
register(component: Focusable): void;
|
|
14
|
+
handleKey(key: readline.Key): void;
|
|
15
|
+
private cycleFocus;
|
|
16
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FocusManager = void 0;
|
|
4
|
+
class FocusManager {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.components = [];
|
|
7
|
+
this.activeIndex = 0;
|
|
8
|
+
}
|
|
9
|
+
register(component) {
|
|
10
|
+
this.components.push(component);
|
|
11
|
+
if (this.components.length === 1) {
|
|
12
|
+
component.focus();
|
|
13
|
+
this.activeIndex = 0;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
handleKey(key) {
|
|
17
|
+
if (this.components.length === 0)
|
|
18
|
+
return;
|
|
19
|
+
// === COMPONENT LOGIC ===
|
|
20
|
+
// Event Bubbling: Child -> Parent -> Root
|
|
21
|
+
let target = this.components[this.activeIndex];
|
|
22
|
+
let consumed = false;
|
|
23
|
+
while (target) {
|
|
24
|
+
const result = target.handleKey(key);
|
|
25
|
+
if (result === true) {
|
|
26
|
+
consumed = true;
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
target = target.parent;
|
|
30
|
+
}
|
|
31
|
+
if (consumed) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// === NAVIGATION LOGIC ===
|
|
35
|
+
// Next: Tab
|
|
36
|
+
if (key.name === 'tab' && !key.shift) {
|
|
37
|
+
this.cycleFocus(false);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// Fallback: Down/Right for next (if not consumed by component)
|
|
41
|
+
if (key.name === 'down' || key.name === 'right') {
|
|
42
|
+
this.cycleFocus(false);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// Previous: Shift+Tab
|
|
46
|
+
if (key.name === 'tab' && key.shift) {
|
|
47
|
+
this.cycleFocus(true);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// Fallback: Up/Left for previous (if not consumed by component)
|
|
51
|
+
if (key.name === 'up' || key.name === 'left') {
|
|
52
|
+
this.cycleFocus(true);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
cycleFocus(reverse = false) {
|
|
57
|
+
this.components[this.activeIndex].blur();
|
|
58
|
+
this.components[this.activeIndex].render();
|
|
59
|
+
if (reverse) {
|
|
60
|
+
this.activeIndex = (this.activeIndex - 1 + this.components.length) % this.components.length;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
this.activeIndex = (this.activeIndex + 1) % this.components.length;
|
|
64
|
+
}
|
|
65
|
+
this.components[this.activeIndex].focus();
|
|
66
|
+
this.components[this.activeIndex].render();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.FocusManager = FocusManager;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as readline from 'readline';
|
|
2
|
+
export type KeyHandler = (key: readline.Key) => boolean | void;
|
|
3
|
+
export declare class Input {
|
|
4
|
+
private static listeners;
|
|
5
|
+
private static initialized;
|
|
6
|
+
static init(): void;
|
|
7
|
+
static onKey(handler: KeyHandler): void;
|
|
8
|
+
static offKey(handler: KeyHandler): void;
|
|
9
|
+
/**
|
|
10
|
+
* Stops listening and restores stdin.
|
|
11
|
+
*/
|
|
12
|
+
static reset(): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ==========================================
|
|
3
|
+
// CORE: INPUT MANAGER (The "Controller")
|
|
4
|
+
// ==========================================
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.Input = void 0;
|
|
40
|
+
const readline = __importStar(require("readline"));
|
|
41
|
+
const Screen_1 = require("./Screen");
|
|
42
|
+
class Input {
|
|
43
|
+
static init() {
|
|
44
|
+
if (this.initialized)
|
|
45
|
+
return;
|
|
46
|
+
readline.emitKeypressEvents(process.stdin);
|
|
47
|
+
if (process.stdin.isTTY) {
|
|
48
|
+
process.stdin.setRawMode(true);
|
|
49
|
+
}
|
|
50
|
+
process.stdin.on('keypress', (str, key) => {
|
|
51
|
+
// Handle Ctrl+C globally to prevent trapping the user
|
|
52
|
+
if (key.ctrl && key.name === 'c') {
|
|
53
|
+
Screen_1.Screen.leave(); // Restore terminal state
|
|
54
|
+
process.exit();
|
|
55
|
+
}
|
|
56
|
+
// Iterate backwards so newest listeners (e.g. Popups) get first dibs
|
|
57
|
+
for (let i = this.listeners.length - 1; i >= 0; i--) {
|
|
58
|
+
const consumed = this.listeners[i](key);
|
|
59
|
+
if (consumed === true)
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
// Trigger a render check after input handling
|
|
63
|
+
Screen_1.Screen.scheduleRender();
|
|
64
|
+
});
|
|
65
|
+
this.initialized = true;
|
|
66
|
+
}
|
|
67
|
+
static onKey(handler) {
|
|
68
|
+
this.init();
|
|
69
|
+
this.listeners.push(handler);
|
|
70
|
+
}
|
|
71
|
+
static offKey(handler) {
|
|
72
|
+
this.listeners = this.listeners.filter(l => l !== handler);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Stops listening and restores stdin.
|
|
76
|
+
*/
|
|
77
|
+
static reset() {
|
|
78
|
+
if (process.stdin.isTTY) {
|
|
79
|
+
process.stdin.setRawMode(false);
|
|
80
|
+
}
|
|
81
|
+
process.stdin.pause();
|
|
82
|
+
this.listeners = [];
|
|
83
|
+
this.initialized = false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.Input = Input;
|
|
87
|
+
Input.listeners = [];
|
|
88
|
+
Input.initialized = false;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Rect } from './Screen';
|
|
2
|
+
export { Rect };
|
|
3
|
+
export declare class Layout {
|
|
4
|
+
/**
|
|
5
|
+
* Splits a rectangle vertically (into columns).
|
|
6
|
+
* @param parent The parent rectangle
|
|
7
|
+
* @param weights Array of weights (e.g. [1, 2] means 1/3 and 2/3) or absolute sizes
|
|
8
|
+
*/
|
|
9
|
+
static splitVertical(parent: Rect, weights: number[]): Rect[];
|
|
10
|
+
/**
|
|
11
|
+
* Splits a rectangle horizontally (into rows).
|
|
12
|
+
*/
|
|
13
|
+
static splitHorizontal(parent: Rect, weights: number[]): Rect[];
|
|
14
|
+
/**
|
|
15
|
+
* Creates a padded inner rectangle.
|
|
16
|
+
*/
|
|
17
|
+
static pad(rect: Rect, padding: number): Rect;
|
|
18
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ==========================================
|
|
3
|
+
// CORE: LAYOUT ENGINE (The "Architect")
|
|
4
|
+
// ==========================================
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Layout = void 0;
|
|
7
|
+
class Layout {
|
|
8
|
+
/**
|
|
9
|
+
* Splits a rectangle vertically (into columns).
|
|
10
|
+
* @param parent The parent rectangle
|
|
11
|
+
* @param weights Array of weights (e.g. [1, 2] means 1/3 and 2/3) or absolute sizes
|
|
12
|
+
*/
|
|
13
|
+
static splitVertical(parent, weights) {
|
|
14
|
+
const totalWeight = weights.reduce((a, b) => a + b, 0);
|
|
15
|
+
let currentX = parent.x;
|
|
16
|
+
return weights.map((w, i) => {
|
|
17
|
+
// Check if it's the last item to fill remaining space (avoid rounding errors)
|
|
18
|
+
const isLast = i === weights.length - 1;
|
|
19
|
+
const width = isLast
|
|
20
|
+
? parent.width - (currentX - parent.x)
|
|
21
|
+
: Math.floor((w / totalWeight) * parent.width);
|
|
22
|
+
const rect = {
|
|
23
|
+
x: currentX,
|
|
24
|
+
y: parent.y,
|
|
25
|
+
width: width,
|
|
26
|
+
height: parent.height
|
|
27
|
+
};
|
|
28
|
+
currentX += width;
|
|
29
|
+
return rect;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Splits a rectangle horizontally (into rows).
|
|
34
|
+
*/
|
|
35
|
+
static splitHorizontal(parent, weights) {
|
|
36
|
+
const totalWeight = weights.reduce((a, b) => a + b, 0);
|
|
37
|
+
let currentY = parent.y;
|
|
38
|
+
return weights.map((w, i) => {
|
|
39
|
+
const isLast = i === weights.length - 1;
|
|
40
|
+
const height = isLast
|
|
41
|
+
? parent.height - (currentY - parent.y)
|
|
42
|
+
: Math.floor((w / totalWeight) * parent.height);
|
|
43
|
+
const rect = {
|
|
44
|
+
x: parent.x,
|
|
45
|
+
y: currentY,
|
|
46
|
+
width: parent.width,
|
|
47
|
+
height: height
|
|
48
|
+
};
|
|
49
|
+
currentY += height;
|
|
50
|
+
return rect;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Creates a padded inner rectangle.
|
|
55
|
+
*/
|
|
56
|
+
static pad(rect, padding) {
|
|
57
|
+
return {
|
|
58
|
+
x: rect.x + padding,
|
|
59
|
+
y: rect.y + padding,
|
|
60
|
+
width: Math.max(0, rect.width - (padding * 2)),
|
|
61
|
+
height: Math.max(0, rect.height - (padding * 2))
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.Layout = Layout;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export interface Rect {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class Screen {
|
|
8
|
+
private static isAlternateBuffer;
|
|
9
|
+
private static resizeTimeout;
|
|
10
|
+
private static currentBuffer;
|
|
11
|
+
private static previousBuffer;
|
|
12
|
+
private static dirtyRows;
|
|
13
|
+
private static layerStack;
|
|
14
|
+
private static isDirty;
|
|
15
|
+
private static renderScheduled;
|
|
16
|
+
private static width;
|
|
17
|
+
private static height;
|
|
18
|
+
private static renderRoots;
|
|
19
|
+
/**
|
|
20
|
+
* Enters the Alternate Screen Buffer (like Vim or Nano).
|
|
21
|
+
*/
|
|
22
|
+
static enter(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Leaves the Alternate Screen Buffer and restores cursor.
|
|
25
|
+
*/
|
|
26
|
+
static leave(): void;
|
|
27
|
+
private static resizeBuffers;
|
|
28
|
+
/**
|
|
29
|
+
* Schedules a render flush in the next tick.
|
|
30
|
+
* Call this whenever a component changes state.
|
|
31
|
+
*/
|
|
32
|
+
static scheduleRender(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Writes text at a specific coordinate into the virtual buffer.
|
|
35
|
+
* Handles ANSI escape codes using a state machine parser.
|
|
36
|
+
* Supports clipping region and relative positioning.
|
|
37
|
+
*/
|
|
38
|
+
static write(x: number, y: number, text: string, clipRect?: Rect): void;
|
|
39
|
+
/**
|
|
40
|
+
* Pushes the current screen state to a stack.
|
|
41
|
+
*/
|
|
42
|
+
static pushLayer(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Restores the screen state from the stack.
|
|
45
|
+
*/
|
|
46
|
+
static popLayer(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Clears the virtual buffer.
|
|
49
|
+
*/
|
|
50
|
+
static clear(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Registers a root component for the rendering loop (Painter's Algorithm).
|
|
53
|
+
* @param renderFn The function that renders the component
|
|
54
|
+
* @param zIndex Priority (higher draws on top)
|
|
55
|
+
*/
|
|
56
|
+
static mount(renderFn: () => void, zIndex?: number): void;
|
|
57
|
+
/**
|
|
58
|
+
* Unregisters a root component from the rendering loop.
|
|
59
|
+
* @param renderFn The function that renders the component
|
|
60
|
+
*/
|
|
61
|
+
static unmount(renderFn: () => void): void;
|
|
62
|
+
/**
|
|
63
|
+
* Diffs currentBuffer vs previousBuffer and writes changes to stdout.
|
|
64
|
+
* Optimized with String Batching and Relative Cursor Moves.
|
|
65
|
+
*/
|
|
66
|
+
static flush(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Gets current terminal dimensions.
|
|
69
|
+
*/
|
|
70
|
+
static get size(): {
|
|
71
|
+
width: number;
|
|
72
|
+
height: number;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Listens for resize events.
|
|
76
|
+
*/
|
|
77
|
+
static onResize(callback: () => void): void;
|
|
78
|
+
}
|