@opentui/core 0.0.0-20250908-4906ddad → 0.0.0-20250912-12c969f4

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.
@@ -0,0 +1,10 @@
1
+ import type { ViewportBounds } from "../types";
2
+ interface ViewportObject {
3
+ x: number;
4
+ y: number;
5
+ width: number;
6
+ height: number;
7
+ zIndex: number;
8
+ }
9
+ export declare function getObjectsInViewport<T extends ViewportObject>(viewport: ViewportBounds, objects: T[], direction?: "row" | "column", padding?: number, minTriggerSize?: number): T[];
10
+ export {};
@@ -1,6 +1,7 @@
1
1
  import type { TextRenderable } from "../renderables/Text";
2
2
  import type { TextChunk } from "../text-buffer";
3
3
  import { type ColorInput } from "./RGBA";
4
+ declare const BrandedStyledText: unique symbol;
4
5
  export type Color = ColorInput;
5
6
  export interface StyleAttrs {
6
7
  fg?: Color;
@@ -13,7 +14,9 @@ export interface StyleAttrs {
13
14
  reverse?: boolean;
14
15
  blink?: boolean;
15
16
  }
17
+ export declare function isStyledText(obj: any): obj is StyledText;
16
18
  export declare class StyledText {
19
+ [BrandedStyledText]: boolean;
17
20
  chunks: TextChunk[];
18
21
  textRenderable?: TextRenderable;
19
22
  constructor(chunks: TextChunk[]);
@@ -71,3 +74,4 @@ export declare const bg: (color: Color) => (input: StylableInput) => TextChunk;
71
74
  * Returns a StyledText object containing chunks of text with optional styles.
72
75
  */
73
76
  export declare function t(strings: TemplateStringsArray, ...values: StylableInput[]): StyledText;
77
+ export {};
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "type": "module",
7
- "version": "0.0.0-20250908-4906ddad",
7
+ "version": "0.0.0-20250912-12c969f4",
8
8
  "description": "OpenTUI is a TypeScript library for building terminal user interfaces (TUIs)",
9
9
  "license": "MIT",
10
10
  "repository": {
@@ -38,11 +38,11 @@
38
38
  "bun-webgpu": "0.1.3",
39
39
  "planck": "^1.4.2",
40
40
  "three": "0.177.0",
41
- "@opentui/core-darwin-x64": "0.0.0-20250908-4906ddad",
42
- "@opentui/core-darwin-arm64": "0.0.0-20250908-4906ddad",
43
- "@opentui/core-linux-x64": "0.0.0-20250908-4906ddad",
44
- "@opentui/core-linux-arm64": "0.0.0-20250908-4906ddad",
45
- "@opentui/core-win32-x64": "0.0.0-20250908-4906ddad",
46
- "@opentui/core-win32-arm64": "0.0.0-20250908-4906ddad"
41
+ "@opentui/core-darwin-x64": "0.0.0-20250912-12c969f4",
42
+ "@opentui/core-darwin-arm64": "0.0.0-20250912-12c969f4",
43
+ "@opentui/core-linux-x64": "0.0.0-20250912-12c969f4",
44
+ "@opentui/core-linux-arm64": "0.0.0-20250912-12c969f4",
45
+ "@opentui/core-win32-x64": "0.0.0-20250912-12c969f4",
46
+ "@opentui/core-win32-arm64": "0.0.0-20250912-12c969f4"
47
47
  }
48
48
  }
@@ -20,7 +20,7 @@ export declare enum InputRenderableEvents {
20
20
  ENTER = "enter"
21
21
  }
22
22
  export declare class InputRenderable extends Renderable {
23
- protected focusable: boolean;
23
+ protected _focusable: boolean;
24
24
  private _value;
25
25
  private _cursorPosition;
26
26
  private _placeholder;
@@ -17,7 +17,7 @@ export declare class ScrollBarRenderable extends Renderable {
17
17
  readonly startArrow: ArrowRenderable;
18
18
  readonly endArrow: ArrowRenderable;
19
19
  readonly orientation: "vertical" | "horizontal";
20
- protected focusable: boolean;
20
+ protected _focusable: boolean;
21
21
  private _scrollSize;
22
22
  private _scrollPosition;
23
23
  private _viewportSize;
@@ -18,6 +18,8 @@ export interface ScrollBoxOptions extends BoxOptions<ScrollBoxRenderable> {
18
18
  scrollbarOptions?: Omit<ScrollBarOptions, "orientation">;
19
19
  verticalScrollbarOptions?: Omit<ScrollBarOptions, "orientation">;
20
20
  horizontalScrollbarOptions?: Omit<ScrollBarOptions, "orientation">;
21
+ stickyScroll?: boolean;
22
+ stickyStart?: "bottom" | "top" | "left" | "right";
21
23
  }
22
24
  export declare class ScrollBoxRenderable extends BoxRenderable {
23
25
  static idCounter: number;
@@ -27,7 +29,7 @@ export declare class ScrollBoxRenderable extends BoxRenderable {
27
29
  readonly content: ContentRenderable;
28
30
  readonly horizontalScrollBar: ScrollBarRenderable;
29
31
  readonly verticalScrollBar: ScrollBarRenderable;
30
- protected focusable: boolean;
32
+ protected _focusable: boolean;
31
33
  private selectionListener?;
32
34
  private autoScrollMouseX;
33
35
  private autoScrollMouseY;
@@ -40,13 +42,26 @@ export declare class ScrollBoxRenderable extends BoxRenderable {
40
42
  private cachedAutoScrollSpeed;
41
43
  private autoScrollAccumulatorX;
42
44
  private autoScrollAccumulatorY;
45
+ private _stickyScroll;
46
+ private _stickyScrollTop;
47
+ private _stickyScrollBottom;
48
+ private _stickyScrollLeft;
49
+ private _stickyScrollRight;
50
+ private _stickyStart?;
51
+ private _hasManualScroll;
52
+ get stickyScroll(): boolean;
53
+ set stickyScroll(value: boolean);
54
+ get stickyStart(): "bottom" | "top" | "left" | "right" | undefined;
55
+ set stickyStart(value: "bottom" | "top" | "left" | "right" | undefined);
43
56
  get scrollTop(): number;
44
57
  set scrollTop(value: number);
45
58
  get scrollLeft(): number;
46
59
  set scrollLeft(value: number);
47
60
  get scrollWidth(): number;
48
61
  get scrollHeight(): number;
49
- constructor(ctx: RenderContext, { wrapperOptions, viewportOptions, contentOptions, rootOptions, scrollbarOptions, verticalScrollbarOptions, horizontalScrollbarOptions, ...options }: ScrollBoxOptions);
62
+ private updateStickyState;
63
+ private applyStickyStart;
64
+ constructor(ctx: RenderContext, { wrapperOptions, viewportOptions, contentOptions, rootOptions, scrollbarOptions, verticalScrollbarOptions, horizontalScrollbarOptions, stickyScroll, stickyStart, ...options }: ScrollBoxOptions);
50
65
  protected onUpdate(deltaTime: number): void;
51
66
  scrollBy(delta: number | {
52
67
  x: number;
@@ -31,7 +31,7 @@ export declare enum SelectRenderableEvents {
31
31
  ITEM_SELECTED = "itemSelected"
32
32
  }
33
33
  export declare class SelectRenderable extends Renderable {
34
- protected focusable: boolean;
34
+ protected _focusable: boolean;
35
35
  private _options;
36
36
  private selectedIndex;
37
37
  private scrollOffset;
@@ -1,31 +1,44 @@
1
1
  import { type ColorInput, OptimizedBuffer, Renderable, type RenderableOptions, type RenderContext, RGBA } from "../index";
2
2
  export interface SliderOptions extends RenderableOptions<SliderRenderable> {
3
3
  orientation: "vertical" | "horizontal";
4
- thumbSize?: number;
5
- thumbPosition?: number;
4
+ value?: number;
5
+ min?: number;
6
+ max?: number;
7
+ viewPortSize?: number;
6
8
  backgroundColor?: ColorInput;
7
9
  foregroundColor?: ColorInput;
8
- onChange?: (position: number) => void;
10
+ onChange?: (value: number) => void;
9
11
  }
10
12
  export declare class SliderRenderable extends Renderable {
11
13
  readonly orientation: "vertical" | "horizontal";
12
- private _thumbSize;
13
- private _thumbPosition;
14
+ private _value;
15
+ private _min;
16
+ private _max;
17
+ private _viewPortSize;
14
18
  private _backgroundColor;
15
19
  private _foregroundColor;
16
20
  private _onChange?;
17
21
  constructor(ctx: RenderContext, options: SliderOptions);
18
- get thumbSize(): number;
19
- set thumbSize(value: number);
20
- get thumbPosition(): number;
21
- set thumbPosition(value: number);
22
+ get value(): number;
23
+ set value(newValue: number);
24
+ get min(): number;
25
+ set min(newMin: number);
26
+ get max(): number;
27
+ set max(newMax: number);
28
+ set viewPortSize(size: number);
29
+ get viewPortSize(): number;
22
30
  get backgroundColor(): RGBA;
23
31
  set backgroundColor(value: ColorInput);
24
32
  get foregroundColor(): RGBA;
25
33
  set foregroundColor(value: ColorInput);
34
+ private calculateDragOffsetVirtual;
26
35
  private setupMouseHandling;
27
- private updatePositionFromMouse;
28
- private getThumbPosition;
36
+ private updateValueFromMouseDirect;
37
+ private updateValueFromMouseWithOffset;
29
38
  private getThumbRect;
30
39
  protected renderSelf(buffer: OptimizedBuffer): void;
40
+ private renderHorizontal;
41
+ private renderVertical;
42
+ private getVirtualThumbSize;
43
+ private getVirtualThumbStart;
31
44
  }
@@ -29,7 +29,7 @@ export declare enum TabSelectRenderableEvents {
29
29
  ITEM_SELECTED = "itemSelected"
30
30
  }
31
31
  export declare class TabSelectRenderable extends Renderable {
32
- protected focusable: boolean;
32
+ protected _focusable: boolean;
33
33
  private _options;
34
34
  private selectedIndex;
35
35
  private scrollOffset;
@@ -1,10 +1,11 @@
1
- import { Renderable, type RenderableOptions } from "../Renderable";
1
+ import { BaseRenderable, Renderable, type RenderableOptions } from "../Renderable";
2
2
  import { Selection } from "../lib/selection";
3
3
  import { StyledText } from "../lib/styled-text";
4
4
  import { type TextChunk } from "../text-buffer";
5
5
  import { RGBA } from "../lib/RGBA";
6
6
  import { type RenderContext } from "../types";
7
7
  import type { OptimizedBuffer } from "../buffer";
8
+ import { RootTextNodeRenderable, TextNodeRenderable } from "./TextNode";
8
9
  export interface TextOptions extends RenderableOptions<TextRenderable> {
9
10
  content?: StyledText | string;
10
11
  fg?: string | RGBA;
@@ -25,6 +26,7 @@ export declare class TextRenderable extends Renderable {
25
26
  private lastLocalSelection;
26
27
  private textBuffer;
27
28
  private _lineInfo;
29
+ protected rootTextNode: RootTextNodeRenderable;
28
30
  protected _defaultOptions: {
29
31
  content: string;
30
32
  fg: RGBA;
@@ -41,6 +43,7 @@ export declare class TextRenderable extends Renderable {
41
43
  get plainText(): string;
42
44
  get textLength(): number;
43
45
  get chunks(): TextChunk[];
46
+ get textNode(): RootTextNodeRenderable;
44
47
  set content(value: StyledText | string);
45
48
  get fg(): RGBA;
46
49
  set fg(value: RGBA | string | undefined);
@@ -59,6 +62,12 @@ export declare class TextRenderable extends Renderable {
59
62
  insertChunk(chunk: TextChunk, index?: number): void;
60
63
  removeChunk(chunk: TextChunk): void;
61
64
  replaceChunk(chunk: TextChunk, oldChunk: TextChunk): void;
65
+ private updateTextFromNodes;
66
+ add(obj: TextNodeRenderable | StyledText | string, index?: number): number;
67
+ remove(id: string): void;
68
+ insertBefore(obj: BaseRenderable | any, anchor?: TextNodeRenderable): number;
69
+ getTextChildren(): BaseRenderable[];
70
+ clear(): void;
62
71
  shouldStartSelection(x: number, y: number): boolean;
63
72
  onSelectionChanged(selection: Selection | null): boolean;
64
73
  getSelectedText(): string;
@@ -67,6 +76,8 @@ export declare class TextRenderable extends Renderable {
67
76
  start: number;
68
77
  end: number;
69
78
  } | null;
79
+ onLifecyclePass: () => void;
80
+ render(buffer: OptimizedBuffer, deltaTime: number): void;
70
81
  protected renderSelf(buffer: OptimizedBuffer): void;
71
82
  destroy(): void;
72
83
  }
@@ -0,0 +1,64 @@
1
+ import type { TextRenderable } from ".";
2
+ import { BaseRenderable, type BaseRenderableOptions } from "../Renderable";
3
+ import { RGBA } from "../lib/RGBA";
4
+ import { StyledText } from "../lib/styled-text";
5
+ import { type TextChunk } from "../text-buffer";
6
+ import type { RenderContext } from "../types";
7
+ export interface TextNodeOptions extends BaseRenderableOptions {
8
+ fg?: string | RGBA;
9
+ bg?: string | RGBA;
10
+ attributes?: number;
11
+ }
12
+ declare const BrandedTextNodeRenderable: unique symbol;
13
+ export declare function isTextNodeRenderable(obj: any): obj is TextNodeRenderable;
14
+ export declare class TextNodeRenderable extends BaseRenderable {
15
+ [BrandedTextNodeRenderable]: boolean;
16
+ private _fg?;
17
+ private _bg?;
18
+ private _attributes;
19
+ private _children;
20
+ parent: TextNodeRenderable | null;
21
+ constructor(options: TextNodeOptions);
22
+ get children(): (string | TextNodeRenderable)[];
23
+ set children(children: (string | TextNodeRenderable)[]);
24
+ requestRender(): void;
25
+ add(obj: TextNodeRenderable | StyledText | string, index?: number): number;
26
+ replace(obj: TextNodeRenderable | string, index: number): void;
27
+ insertBefore(child: string | TextNodeRenderable | StyledText, anchorNode: TextNodeRenderable | string | unknown): this;
28
+ remove(child: string | TextNodeRenderable): this;
29
+ clear(): void;
30
+ mergeStyles(parentStyle: {
31
+ fg?: RGBA;
32
+ bg?: RGBA;
33
+ attributes: number;
34
+ }): {
35
+ fg?: RGBA;
36
+ bg?: RGBA;
37
+ attributes: number;
38
+ };
39
+ gatherWithInheritedStyle(parentStyle?: {
40
+ fg?: RGBA;
41
+ bg?: RGBA;
42
+ attributes: number;
43
+ }): TextChunk[];
44
+ static fromString(text: string, options?: Partial<TextNodeOptions>): TextNodeRenderable;
45
+ static fromNodes(nodes: TextNodeRenderable[], options?: Partial<TextNodeOptions>): TextNodeRenderable;
46
+ toChunks(parentStyle?: {
47
+ fg?: RGBA;
48
+ bg?: RGBA;
49
+ attributes: number;
50
+ }): TextChunk[];
51
+ getChildren(): BaseRenderable[];
52
+ getChildrenCount(): number;
53
+ getRenderable(id: string): BaseRenderable | undefined;
54
+ set fg(fg: RGBA);
55
+ set bg(bg: RGBA);
56
+ set attributes(attributes: number);
57
+ }
58
+ export declare class RootTextNodeRenderable extends TextNodeRenderable {
59
+ private readonly ctx;
60
+ textParent: TextRenderable;
61
+ constructor(ctx: RenderContext, options: TextNodeOptions, textParent: TextRenderable);
62
+ requestRender(): void;
63
+ }
64
+ export {};
@@ -1,12 +1,33 @@
1
1
  import { ASCIIFontRenderable, BoxRenderable, InputRenderable, SelectRenderable, TabSelectRenderable, TextRenderable, VRenderable, type ASCIIFontOptions, type BoxOptions, type TextOptions, type VRenderableOptions, type InputRenderableOptions, type SelectRenderableOptions, type TabSelectRenderableOptions, FrameBufferRenderable, type FrameBufferOptions } from "../";
2
- import { type VChild, type ProxiedVNode } from "./vnode";
3
- export declare function Generic(props?: VRenderableOptions, ...children: VChild[]): ProxiedVNode<typeof VRenderable>;
4
- export declare function Box(props?: BoxOptions, ...children: VChild[]): ProxiedVNode<typeof BoxRenderable>;
2
+ import { TextNodeRenderable } from "../TextNode";
3
+ import { type VChild } from "./vnode";
4
+ import type { RGBA } from "../../lib/RGBA";
5
+ export declare function Generic(props?: VRenderableOptions, ...children: VChild[]): import("./vnode").ProxiedVNode<typeof VRenderable>;
6
+ export declare function Box(props?: BoxOptions, ...children: VChild[]): import("./vnode").ProxiedVNode<typeof BoxRenderable>;
5
7
  export declare function Text(props?: TextOptions & {
6
8
  content?: any;
7
- }, ...children: VChild[]): ProxiedVNode<typeof TextRenderable>;
8
- export declare function ASCIIFont(props?: ASCIIFontOptions, ...children: VChild[]): ProxiedVNode<typeof ASCIIFontRenderable>;
9
- export declare function Input(props?: InputRenderableOptions, ...children: VChild[]): ProxiedVNode<typeof InputRenderable>;
10
- export declare function Select(props?: SelectRenderableOptions, ...children: VChild[]): ProxiedVNode<typeof SelectRenderable>;
11
- export declare function TabSelect(props?: TabSelectRenderableOptions, ...children: VChild[]): ProxiedVNode<typeof TabSelectRenderable>;
12
- export declare function FrameBuffer(props: FrameBufferOptions, ...children: VChild[]): ProxiedVNode<typeof FrameBufferRenderable>;
9
+ }, ...children: VChild[] | TextNodeRenderable[]): import("./vnode").ProxiedVNode<typeof TextRenderable>;
10
+ export declare function ASCIIFont(props?: ASCIIFontOptions, ...children: VChild[]): import("./vnode").ProxiedVNode<typeof ASCIIFontRenderable>;
11
+ export declare function Input(props?: InputRenderableOptions, ...children: VChild[]): import("./vnode").ProxiedVNode<typeof InputRenderable>;
12
+ export declare function Select(props?: SelectRenderableOptions, ...children: VChild[]): import("./vnode").ProxiedVNode<typeof SelectRenderable>;
13
+ export declare function TabSelect(props?: TabSelectRenderableOptions, ...children: VChild[]): import("./vnode").ProxiedVNode<typeof TabSelectRenderable>;
14
+ export declare function FrameBuffer(props: FrameBufferOptions, ...children: VChild[]): import("./vnode").ProxiedVNode<typeof FrameBufferRenderable>;
15
+ export declare const vstyles: {
16
+ bold: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
17
+ italic: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
18
+ underline: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
19
+ dim: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
20
+ blink: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
21
+ inverse: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
22
+ hidden: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
23
+ strikethrough: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
24
+ boldItalic: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
25
+ boldUnderline: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
26
+ italicUnderline: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
27
+ boldItalicUnderline: (...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
28
+ color: (color: string | RGBA, ...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
29
+ bgColor: (bgColor: string | RGBA, ...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
30
+ fg: (color: string | RGBA, ...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
31
+ bg: (bgColor: string | RGBA, ...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
32
+ styled: (attributes?: number, ...children: (string | TextNodeRenderable)[]) => TextNodeRenderable;
33
+ };
@@ -27,7 +27,7 @@ export declare function h<TCtor extends RenderableConstructor<any>>(type: TCtor,
27
27
  export declare function h<P>(type: FunctionalConstruct<P>, props?: P, ...children: VChild[]): VNode<P>;
28
28
  export declare function h<P>(type: Construct<P>, props?: P, ...children: VChild[]): VNode<P> | ProxiedVNode<any>;
29
29
  export declare function isVNode(node: any): node is VNode;
30
- export declare function maybeMakeRenderable(ctx: RenderContext, node: Renderable | VNode<any, any[]>): Renderable | null;
30
+ export declare function maybeMakeRenderable(ctx: RenderContext, node: Renderable | VNode<any, any[]> | unknown): Renderable | null;
31
31
  export declare function wrapWithDelegates<T extends InstanceType<RenderableConstructor>>(instance: T, delegateMap: Record<string, string> | undefined): T;
32
32
  export type InstantiateFn<NodeType extends VNode | Renderable> = Renderable & {
33
33
  __node?: NodeType;
@@ -1,6 +1,7 @@
1
1
  export * from "./Box";
2
2
  export * from "./FrameBuffer";
3
3
  export * from "./Text";
4
+ export * from "./TextNode";
4
5
  export * from "./ASCIIFont";
5
6
  export * from "./Input";
6
7
  export * from "./Select";
package/renderer.d.ts CHANGED
@@ -70,7 +70,7 @@ export declare class CliRenderer extends EventEmitter implements RenderContext {
70
70
  private static animationFrameId;
71
71
  private lib;
72
72
  rendererPtr: Pointer;
73
- private stdin;
73
+ stdin: NodeJS.ReadStream;
74
74
  private stdout;
75
75
  private exitOnCtrlC;
76
76
  private isDestroyed;
@@ -134,7 +134,14 @@ export declare class CliRenderer extends EventEmitter implements RenderContext {
134
134
  private sigwinchHandler;
135
135
  private _capabilities;
136
136
  private _latestPointer;
137
+ private _currentFocusedRenderable;
138
+ private lifecyclePasses;
137
139
  constructor(lib: RenderLib, rendererPtr: Pointer, stdin: NodeJS.ReadStream, stdout: NodeJS.WriteStream, width: number, height: number, config?: CliRendererConfig);
140
+ registerLifecyclePass(renderable: Renderable): void;
141
+ unregisterLifecyclePass(renderable: Renderable): void;
142
+ getLifecyclePasses(): Set<Renderable>;
143
+ get currentFocusedRenderable(): Renderable | null;
144
+ focusRenderable(renderable: Renderable): void;
138
145
  addToHitGrid(x: number, y: number, width: number, height: number, id: number): void;
139
146
  get widthMethod(): WidthMethod;
140
147
  private writeOut;
@@ -155,7 +162,7 @@ export declare class CliRenderer extends EventEmitter implements RenderContext {
155
162
  get capabilities(): any | null;
156
163
  set experimental_splitHeight(splitHeight: number);
157
164
  private interceptStdoutWrite;
158
- private disableStdoutInterception;
165
+ disableStdoutInterception(): void;
159
166
  private flushStdoutCache;
160
167
  private enableMouse;
161
168
  private disableMouse;
@@ -163,6 +170,7 @@ export declare class CliRenderer extends EventEmitter implements RenderContext {
163
170
  disableKittyKeyboard(): void;
164
171
  set useThread(useThread: boolean);
165
172
  setupTerminal(): Promise<void>;
173
+ private setupInput;
166
174
  private handleMouseData;
167
175
  private takeMemorySnapshot;
168
176
  private startMemorySnapshotTimer;
@@ -0,0 +1,67 @@
1
+ import type { CliRenderer } from "../renderer";
2
+ export declare const KeyCodes: {
3
+ readonly ENTER: "\r";
4
+ readonly TAB: "\t";
5
+ readonly BACKSPACE: "\b";
6
+ readonly DELETE: "\u001B[3~";
7
+ readonly HOME: "\u001B[H";
8
+ readonly END: "\u001B[F";
9
+ readonly ESCAPE: "\u001B";
10
+ readonly ARROW_UP: "\u001B[A";
11
+ readonly ARROW_DOWN: "\u001B[B";
12
+ readonly ARROW_RIGHT: "\u001B[C";
13
+ readonly ARROW_LEFT: "\u001B[D";
14
+ readonly F1: "\u001BOP";
15
+ readonly F2: "\u001BOQ";
16
+ readonly F3: "\u001BOR";
17
+ readonly F4: "\u001BOS";
18
+ readonly F5: "\u001B[15~";
19
+ readonly F6: "\u001B[17~";
20
+ readonly F7: "\u001B[18~";
21
+ readonly F8: "\u001B[19~";
22
+ readonly F9: "\u001B[20~";
23
+ readonly F10: "\u001B[21~";
24
+ readonly F11: "\u001B[23~";
25
+ readonly F12: "\u001B[24~";
26
+ readonly CTRL_A: "\u0001";
27
+ readonly CTRL_B: "\u0002";
28
+ readonly CTRL_C: "\u0003";
29
+ readonly CTRL_D: "\u0004";
30
+ readonly CTRL_E: "\u0005";
31
+ readonly CTRL_F: "\u0006";
32
+ readonly CTRL_G: "\u0007";
33
+ readonly CTRL_H: "\b";
34
+ readonly CTRL_I: "\t";
35
+ readonly CTRL_J: "\n";
36
+ readonly CTRL_K: "\v";
37
+ readonly CTRL_L: "\f";
38
+ readonly CTRL_M: "\r";
39
+ readonly CTRL_N: "\u000E";
40
+ readonly CTRL_O: "\u000F";
41
+ readonly CTRL_P: "\u0010";
42
+ readonly CTRL_Q: "\u0011";
43
+ readonly CTRL_R: "\u0012";
44
+ readonly CTRL_S: "\u0013";
45
+ readonly CTRL_T: "\u0014";
46
+ readonly CTRL_U: "\u0015";
47
+ readonly CTRL_V: "\u0016";
48
+ readonly CTRL_W: "\u0017";
49
+ readonly CTRL_X: "\u0018";
50
+ readonly CTRL_Y: "\u0019";
51
+ readonly CTRL_Z: "\u001A";
52
+ readonly ALT_A: "\u001Ba";
53
+ readonly ALT_B: "\u001Bb";
54
+ readonly ALT_C: "\u001Bc";
55
+ };
56
+ export type KeyInput = string | keyof typeof KeyCodes;
57
+ export declare function createMockKeys(renderer: CliRenderer): {
58
+ pressKeys: (keys: KeyInput[], delayMs?: number) => Promise<void>;
59
+ pressKey: (key: KeyInput) => void;
60
+ typeText: (text: string, delayMs?: number) => Promise<void>;
61
+ pressEnter: () => void;
62
+ pressEscape: () => void;
63
+ pressTab: () => void;
64
+ pressBackspace: () => void;
65
+ pressArrow: (direction: "up" | "down" | "left" | "right") => void;
66
+ pressCtrlC: () => void;
67
+ };
@@ -0,0 +1,38 @@
1
+ import type { CliRenderer } from "../renderer";
2
+ export declare const MouseButtons: {
3
+ readonly LEFT: 0;
4
+ readonly MIDDLE: 1;
5
+ readonly RIGHT: 2;
6
+ readonly WHEEL_UP: 64;
7
+ readonly WHEEL_DOWN: 65;
8
+ readonly WHEEL_LEFT: 66;
9
+ readonly WHEEL_RIGHT: 67;
10
+ };
11
+ export type MouseButton = (typeof MouseButtons)[keyof typeof MouseButtons];
12
+ export interface MousePosition {
13
+ x: number;
14
+ y: number;
15
+ }
16
+ export interface MouseModifiers {
17
+ shift?: boolean;
18
+ alt?: boolean;
19
+ ctrl?: boolean;
20
+ }
21
+ export type MouseEventType = "down" | "up" | "move" | "drag" | "scroll";
22
+ export interface MouseEventOptions {
23
+ button?: MouseButton;
24
+ modifiers?: MouseModifiers;
25
+ delayMs?: number;
26
+ }
27
+ export declare function createMockMouse(renderer: CliRenderer): {
28
+ moveTo: (x: number, y: number, options?: MouseEventOptions) => Promise<void>;
29
+ click: (x: number, y: number, button?: MouseButton, options?: MouseEventOptions) => Promise<void>;
30
+ doubleClick: (x: number, y: number, button?: MouseButton, options?: MouseEventOptions) => Promise<void>;
31
+ pressDown: (x: number, y: number, button?: MouseButton, options?: MouseEventOptions) => Promise<void>;
32
+ release: (x: number, y: number, button?: MouseButton, options?: MouseEventOptions) => Promise<void>;
33
+ drag: (startX: number, startY: number, endX: number, endY: number, button?: MouseButton, options?: MouseEventOptions) => Promise<void>;
34
+ scroll: (x: number, y: number, direction: "up" | "down" | "left" | "right", options?: MouseEventOptions) => Promise<void>;
35
+ getCurrentPosition: () => MousePosition;
36
+ getPressedButtons: () => MouseButton[];
37
+ emitMouseEvent: (type: MouseEventType, x: number, y: number, button?: MouseButton, options?: Omit<MouseEventOptions, "button">) => Promise<void>;
38
+ };
@@ -0,0 +1,15 @@
1
+ import { CliRenderer, type CliRendererConfig } from "../renderer";
2
+ import { createMockKeys } from "./mock-keys";
3
+ import { createMockMouse } from "./mock-mouse";
4
+ export interface TestRendererOptions extends CliRendererConfig {
5
+ }
6
+ export interface TestRenderer extends CliRenderer {
7
+ }
8
+ export type MockInput = ReturnType<typeof createMockKeys>;
9
+ export type MockMouse = ReturnType<typeof createMockMouse>;
10
+ export declare function createTestRenderer(options: TestRendererOptions): Promise<{
11
+ renderer: TestRenderer;
12
+ mockInput: MockInput;
13
+ mockMouse: MockMouse;
14
+ renderOnce: () => Promise<void>;
15
+ }>;
package/text-buffer.d.ts CHANGED
@@ -5,8 +5,7 @@ import { type Pointer } from "bun:ffi";
5
5
  import { type WidthMethod } from "./types";
6
6
  export interface TextChunk {
7
7
  __isChunk: true;
8
- text: Uint8Array;
9
- plainText: string;
8
+ text: string;
10
9
  fg?: RGBA;
11
10
  bg?: RGBA;
12
11
  attributes?: number;
@@ -17,8 +16,10 @@ export declare class TextBuffer {
17
16
  private _length;
18
17
  private _capacity;
19
18
  private _lineInfo?;
19
+ private _destroyed;
20
20
  constructor(lib: RenderLib, ptr: Pointer, capacity: number);
21
21
  static create(capacity: number | undefined, widthMethod: WidthMethod): TextBuffer;
22
+ private guard;
22
23
  setStyledText(text: StyledText): void;
23
24
  setDefaultFg(fg: RGBA | null): void;
24
25
  setDefaultBg(bg: RGBA | null): void;
package/types.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { RGBA } from "./lib/RGBA";
2
2
  import type { EventEmitter } from "events";
3
3
  import type { Selection } from "./lib/selection";
4
+ import type { Renderable } from "./Renderable";
4
5
  export declare const TextAttributes: {
5
6
  NONE: number;
6
7
  BOLD: number;
@@ -46,6 +47,11 @@ export interface RenderContext extends EventEmitter {
46
47
  hasSelection: boolean;
47
48
  getSelection: () => Selection | null;
48
49
  requestSelectionUpdate: () => void;
50
+ currentFocusedRenderable: Renderable | null;
51
+ focusRenderable: (renderable: Renderable) => void;
52
+ registerLifecyclePass: (renderable: Renderable) => void;
53
+ unregisterLifecyclePass: (renderable: Renderable) => void;
54
+ getLifecyclePasses: () => Set<Renderable>;
49
55
  }
50
56
  export type Timeout = ReturnType<typeof setTimeout> | undefined;
51
57
  export interface ViewportBounds {
package/utils.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Renderable } from "./Renderable";
1
2
  export declare function createTextAttributes({ bold, italic, underline, dim, blink, inverse, hidden, strikethrough, }?: {
2
3
  bold?: boolean;
3
4
  italic?: boolean;
@@ -8,3 +9,4 @@ export declare function createTextAttributes({ bold, italic, underline, dim, bli
8
9
  hidden?: boolean;
9
10
  strikethrough?: boolean;
10
11
  }): number;
12
+ export declare function visualizeRenderableTree(renderable: Renderable, maxDepth?: number): void;
package/zig.d.ts CHANGED
@@ -10,7 +10,9 @@ export declare enum LogLevel {
10
10
  Debug = 3
11
11
  }
12
12
  export interface RenderLib {
13
- createRenderer: (width: number, height: number) => Pointer | null;
13
+ createRenderer: (width: number, height: number, options?: {
14
+ testing: boolean;
15
+ }) => Pointer | null;
14
16
  destroyRenderer: (renderer: Pointer, useAlternateScreen: boolean, splitHeight: number) => void;
15
17
  setUseThread: (renderer: Pointer, useThread: boolean) => void;
16
18
  setBackgroundColor: (renderer: Pointer, color: RGBA) => void;