@remotex-labs/xansi
Version:
A lightweight ANSI utility library for styling terminal output
1,063 lines (1,062 loc) • 37.6 kB
TypeScript
/**
* Writes raw data directly to the standard output stream without any processing
*
* @param data - The string or Buffer to write to stdout
*
* @returns Nothing
*
* @example
* ```ts
* // Write an ANSI escape sequence followed by text
* writeRaw('\x1b[31mThis text is red\x1b[0m');
* ```
*
* @since 1.0.0
*/
export declare function writeRaw(data: string | Buffer): void;
/**
* Generates an ANSI escape sequence to move the terminal cursor to the specified position
*
* @param row - The row (line) number to move the cursor to (1-based index)
* @param column - The column position to move the cursor to (1-based index)
*
* @returns ANSI escape sequence string that moves the cursor when written to the terminal
*
* @example
* ```ts
* // Move cursor to the beginning of line 5
* const escapeSequence = moveCursor(5, 1);
* process.stdout.write(escapeSequence);
* ```
*
* @since 1.0.0
*/
export declare function moveCursor(row: number, column?: number): string;
/**
* Removes ANSI escape sequences from a string
*
* @param str - The input string containing ANSI escape sequences
* @returns A plain string with all ANSI escape sequences removed
*
* @remarks
* This function uses a regular expression to match and remove ANSI escape sequences
* that control text styling in terminal output. These sequences typically start with
* the escape character (x1b) followed by square brackets and control codes.
*
* The function is useful for:
* - Getting accurate string length measurements without styling codes
* - Preparing terminal output for non-terminal destinations (files, logs)
* - Normalizing text for comparison or processing
*
* @example
* ```ts
* import { xterm, stripAnsi } from '@remotex-labs/xansi';
*
* const coloredText = xterm.red('Error!');
* console.log(stripAnsi(coloredText)); // "Error!" (without ANSI codes)
* ```
*
* @since 1.0.0
*/
export declare function stripAnsi(str: string): string;
/**
* Contains ANSI escape sequence constants for terminal control operations
*
* @remarks
* These ANSI escape codes are used to control terminal output behavior such as
* cursor movement, screen clearing, and visibility. The enum provides a type-safe
* way to access these constants without having to remember the raw escape sequences.
*
* Each constant is an escape sequence that can be written directly to the terminal
* to achieve the described effect.
*
* @see ShadowRenderer
* @see https://en.wikipedia.org/wiki/ANSI_escape_code
*
* @since 1.0.0
*/
export declare const ANSI: {
/**
* Clears from the cursor to the end of the line
*
* @see https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
* @since 1.0.0
*/
readonly CLEAR_LINE: "\u001B[K";
/**
* Hides the cursor
*
* @see https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
* @since 1.0.0
*/
readonly HIDE_CURSOR: "\u001B[?25l";
/**
* Shows the cursor
*
* @see https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
* @since 1.0.0
*/
readonly SHOW_CURSOR: "\u001B[?25h";
/**
* Saves the current cursor position
*
* @see https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
* @since 1.0.0
*/
readonly SAVE_CURSOR: "\u001B[s";
/**
* Clears the entire screen and moves the cursor to home position (top-left)
*
* @see https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
* @since 1.0.0
*/
readonly CLEAR_SCREEN: "\u001B[2J\u001B[H";
/**
* Restores the cursor to the previously saved position
*
* @see https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
* @since 1.0.0
*/
readonly RESTORE_CURSOR: "\u001B[u";
/**
* Clears the screen from the cursor position down
*
* @see https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
* @since 1.0.0
*/
readonly CLEAR_SCREEN_DOWN: "\u001B[J";
/**
* Resets the terminal to its initial state (RIS - Reset to Initial State).
* Clears screen, scrollback buffer, and most settings.
* This is a "hard reset" escape code.
*
* @see https://en.wikipedia.org/wiki/ANSI_escape_code#Reset_(RIS)
* @since 1.0.0
*/
readonly RESET_TERMINAL: "\u001Bc";
};
/**
* Represents an ANSI style code pair with application and reset codes
*
* @template code - The ANSI code to apply a style
* @template reset - The ANSI code to reset the applied style
*
* @returns A tuple containing the application code and reset code
*
* @remarks
* This type defines the structure for ANSI escape code pairs used for terminal styling.
* The first element is the code that applies a style (color, format, etc.), while
* the second element is the code that resets that specific style.
*
* @example
* ```ts
* // Bold style: apply code 1, reset code 22
* const boldStyle: StyleCodeType = [1, 22];
*
* // Red foreground: apply code 31, reset code 39
* const redForeground: StyleCodeType = [31, 39];
* ```
*
* @since 1.0.0
*/
export type StyleCodeType = [code: number | string, reset: number];
/**
* Collection of ANSI text modifier codes for terminal styling
*
* @returns An object mapping modifier names to their corresponding ANSI style codes
*
* @remarks
* Provides commonly used text modifiers like bold, dim, etc. Each entry contains
* a pair of codes: the first to apply the style and the second to reset it.
* These modifiers change the appearance of text without affecting its color.
*
* @example
* ```ts
* // Apply bold styling to text
* const boldCode = ansiModifiers.bold;
* console.log(`\x1b[${boldCode[0]}mBold Text\x1b[${boldCode[1]}m`);
* ```
*
* @see StyleCodeType
* @since 1.0.0
*/
export declare const ansiModifiers: {
dim: [number, number];
bold: [number, number];
reset: [number, number];
hidden: [number, number];
inverse: [number, number];
};
/**
* Collection of ANSI foreground color codes for terminal text coloring
*
* @returns An object mapping color names to their corresponding ANSI foreground style codes
*
* @remarks
* Provides standard and bright variants of terminal foreground colors.
* Each entry contains a pair of codes: the first to apply the color and
* the second (39) to reset to the default foreground color.
*
* @example
* ```ts
* // Apply red foreground color to text
* const redCode = ansiForegroundColors.red;
* console.log(`\x1b[${redCode[0]}mRed Text\x1b[${redCode[1]}m`);
*
* // Apply bright blue color
* const brightBlueCode = ansiForegroundColors.blueBright;
* console.log(`\x1b[${brightBlueCode[0]}mBright Blue\x1b[${brightBlueCode[1]}m`);
* ```
*
* @see StyleCodeType
* @since 1.0.0
*/
export declare const ansiForegroundColors: {
red: [number, number];
gray: [number, number];
blue: [number, number];
cyan: [number, number];
black: [number, number];
white: [number, number];
green: [number, number];
yellow: [number, number];
magenta: [number, number];
redBright: [number, number];
blueBright: [number, number];
cyanBright: [number, number];
whiteBright: [number, number];
greenBright: [number, number];
blackBright: [number, number];
yellowBright: [number, number];
magentaBright: [number, number];
darkGray: [string, number];
lightGray: [string, number];
lightCoral: [string, number];
oliveGreen: [string, number];
deepOrange: [string, number];
brightPink: [string, number];
lightOrange: [string, number];
burntOrange: [string, number];
lightYellow: [string, number];
canaryYellow: [string, number];
lightGoldenrodYellow: [string, number];
};
/**
* Collection of ANSI background color codes for terminal text backgrounds
*
* @returns An object mapping color names to their corresponding ANSI background style codes
*
* @remarks
* Provides standard and bright variants of terminal background colors.
* Each entry contains a pair of codes: the first to apply the background color and
* the second (49) to reset to the default background.
* All background color names are prefixed with 'bg' to distinguish them from foreground colors.
*
* @example
* ```ts
* // Apply red background to text
* const bgRedCode = ansiBackgroundColors.bgRed;
* console.log(`\x1b[${bgRedCode[0]}mText with Red Background\x1b[${bgRedCode[1]}m`);
*
* // Apply bright cyan background
* const bgCyanBrightCode = ansiBackgroundColors.bgCyanBright;
* console.log(`\x1b[${bgCyanBrightCode[0]}mBright Cyan Background\x1b[${bgCyanBrightCode[1]}m`);
* ```
*
* @see StyleCodeType
* @since 1.0.0
*/
export declare const ansiBackgroundColors: {
bgRed: [number, number];
bgBlue: [number, number];
bgCyan: [number, number];
bgGray: [number, number];
bgBlack: [number, number];
bgGreen: [number, number];
bgWhite: [number, number];
bgYellow: [number, number];
bgMagenta: [number, number];
bgRedBright: [number, number];
bgBlueBright: [number, number];
bgCyanBright: [number, number];
bgBlackBright: [number, number];
bgWhiteBright: [number, number];
bgGreenBright: [number, number];
bgYellowBright: [number, number];
bgMagentaBright: [number, number];
};
/**
* Represents valid ANSI modifier keys for text styling.
*
* @remarks
* This type extracts the keys from the ansiModifiers object, allowing for
* type-safe access to text modifiers like bold, inverse, etc.
*
* @see ansiModifiers
* @since 1.0.0
*/
type AnsiModifiersType = keyof typeof ansiModifiers;
/**
* Represents valid ANSI foreground color keys.
*
* @remarks
* This type extracts the keys from the ansiForegroundColors object, providing
* type-safe access to standard terminal foreground colors.
*
* @see ansiForegroundColors
* @since 1.0.0
*/
type AnsiForegroundColorsType = keyof typeof ansiForegroundColors;
/**
* Represents valid ANSI background color keys.
*
* @remarks
* This type extracts the keys from the ansiBackgroundColors object, providing
* type-safe access to standard terminal background colors.
*
* @see ansiBackgroundColors
* @since 1.0.0
*/
type AnsiBackgroundColorsType = keyof typeof ansiBackgroundColors;
/**
* Represents a function that formats text with ANSI escape codes.
*
* @param text - Array of string segments to be formatted
* @returns Formatted string with ANSI escape codes
*
* @remarks
* This type defines the basic formatter function signature that
* accepts multiple string arguments and joins them with ANSI styling.
*
* @since 1.0.0
*/
type AnsiFunctionType = AnsiFormatterType & AnsiTaggedFormatterType;
/**
* Represents a tagged template function for ANSI formatting.
*
* @param strings - Template string segments
* @param values - Values to be interpolated between string segments
* @returns Formatted string with ANSI escape codes
*
* @remarks
* This type enables the use of template literals with ANSI styling,
* allowing for more readable inline styling of dynamic content.
*
* @since 1.0.0
*/
type AnsiFormatterType = (...text: Array<string>) => string;
/**
* Combined type supporting both regular function calls and tagged templates.
*
* @remarks
* This intersection type unifies the two different ways to apply ANSI formatting:
* regular function calls with multiple arguments and tagged template literals.
*
* @example
* ```ts
* // Both of these would be supported:
* formatter('Hello', 'World');
* formatter`Hello ${'World'}`;
* ```
*
* @see AnsiFormatterType
* @see AnsiTaggedFormatterType
* @since 1.0.0
*/
type AnsiTaggedFormatterType = (strings: TemplateStringsArray, ...values: Array<unknown>) => string;
/**
* Defines properties for text modifiers available based on already applied modifiers
*
* @template UsedFg - Indicates whether a foreground color has already been applied
* @template UsedBg - Indicates whether a background color has already been applied
* @template UsedModifiers - String literal union of already applied text modifiers
*
* @returns A mapped type containing modifier properties not yet applied
*
* @remarks
* This type creates properties for each available text modifier (bold, inverse, etc.)
* while excluding modifiers that have already been applied. Each property returns a new
* chainable builder with the applied modifier added to the type tracking.
*
* @since 1.0.0
*/
type ModifierPropsType<UsedFg extends boolean, UsedBg extends boolean, UsedModifiers extends string> = {
[K in AnsiModifiersType as K extends UsedModifiers ? never : K]: AnsiChainableBuilderType<UsedFg, UsedBg, UsedModifiers | K>;
};
/**
* Defines foreground color properties available when no foreground color has been applied
*
* @template UsedFg - Indicates whether a foreground color has already been applied
* @template UsedBg - Indicates whether a background color has already been applied
* @template UsedModifiers - String literal union of already applied text modifiers
*
* @returns A mapped type containing foreground color properties or unknown if a foreground color is already applied
*
* @remarks
* This type conditionally creates properties for each available foreground color,
* but only if no foreground color has been applied yet. This prevents applying multiple
* foreground colors to the same text string.
*
* @since 1.0.0
*/
type FgColorPropsType<UsedFg extends boolean, UsedBg extends boolean, UsedModifiers extends string> = UsedFg extends true ? unknown : {
[K in AnsiForegroundColorsType]: AnsiChainableBuilderType<true, UsedBg, UsedModifiers>;
};
/**
* Defines background color properties available when no background color has been applied
*
* @template UsedFg - Indicates whether a foreground color has already been applied
* @template UsedBg - Indicates whether a background color has already been applied
* @template UsedModifiers - String literal union of already applied text modifiers
*
* @returns A mapped type containing background color properties or unknown if a background color is already applied
*
* @remarks
* This type conditionally creates properties for each available background color,
* but only if no background color has been applied yet. This prevents applying multiple
* background colors to the same text string.
*
* @since 1.0.0
*/
type BgColorPropsType<UsedFg extends boolean, UsedBg extends boolean, UsedModifiers extends string> = UsedBg extends true ? unknown : {
[K in AnsiBackgroundColorsType]: AnsiChainableBuilderType<UsedFg, true, UsedModifiers>;
};
/**
* Defines RGB and hexadecimal foreground color methods
*
* @template UsedFg - Indicates whether a foreground color has already been applied
* @template UsedBg - Indicates whether a background color has already been applied
* @template UsedModifiers - String literal union of already applied text modifiers
*
* @remarks
* This interface provides methods for applying RGB and hex colors to text as foreground colors.
*
* @since 1.0.0
*/
interface RgbMethodsInterface<UsedFg extends boolean, UsedBg extends boolean, UsedModifiers extends string> {
/**
* Applies a hexadecimal color as the foreground color
*
* @param color - Hexadecimal color string (e.g., "#ff0000" or "f00")
* @returns A chainable builder with the foreground color applied
*
* @since 1.0.0
*/
hex: (color: string) => AnsiChainableBuilderType<UsedFg, UsedBg, UsedModifiers>;
/**
* Applies an RGB color as the foreground color
*
* @param r - Red component (0-255)
* @param g - Green component (0-255)
* @param b - Blue component (0-255)
* @returns A chainable builder with the foreground color applied
*
* @since 1.0.0
*/
rgb: (r: number, g: number, b: number) => AnsiChainableBuilderType<UsedFg, UsedBg, UsedModifiers>;
}
/**
* Defines RGB and hexadecimal background color methods
*
* @template UsedFg - Indicates whether a foreground color has already been applied
* @template UsedBg - Indicates whether a background color has already been applied
* @template UsedModifiers - String literal union of already applied text modifiers
*
* @remarks
* This interface provides methods for applying RGB and hex colors to text as background colors.
*
* @since 1.0.0
*/
interface BgRgbMethodsInterface<UsedFg extends boolean, UsedBg extends boolean, UsedModifiers extends string> {
/**
* Applies a hexadecimal color as the background color
*
* @param color - Hexadecimal color string (e.g., "#ff0000" or "f00")
* @returns A chainable builder with the background color applied
*
* @since 1.0.0
*/
bgHex: (color: string) => AnsiChainableBuilderType<UsedFg, UsedBg, UsedModifiers>;
/**
* Applies an RGB color as the background color
*
* @param r - Red component (0-255)
* @param g - Green component (0-255)
* @param b - Blue component (0-255)
* @returns A chainable builder with the background color applied
*
* @since 1.0.0
*/
bgRgb: (r: number, g: number, b: number) => AnsiChainableBuilderType<UsedFg, UsedBg, UsedModifiers>;
}
/**
* Conditional type that provides RGB foreground color methods when no foreground color has been applied
*
* @template UsedFg - Indicates whether a foreground color has already been applied
* @template UsedBg - Indicates whether a background color has already been applied
* @template UsedModifiers - String literal union of already applied text modifiers
*
* @returns RGB method interface or unknown if a foreground color is already applied
*
* @remarks
* This type conditionally includes RGB color methods only if no foreground color has been applied yet.
*
* @see RgbMethodsInterface
* @since 1.0.0
*/
type RgbMethodsType<UsedFg extends boolean, UsedBg extends boolean, UsedModifiers extends string> = UsedFg extends true ? unknown : RgbMethodsInterface<true, UsedBg, UsedModifiers>;
/**
* Conditional type that provides RGB background color methods when no background color has been applied
*
* @template UsedFg - Indicates whether a foreground color has already been applied
* @template UsedBg - Indicates whether a background color has already been applied
* @template UsedModifiers - String literal union of already applied text modifiers
*
* @returns RGB background method interface or unknown if a background color is already applied
*
* @remarks
* This type conditionally includes RGB background color methods only if no background color has been applied yet.
*
* @see BgRgbMethodsInterface
* @since 1.0.0
*/
type BgRgbMethodsType<UsedFg extends boolean, UsedBg extends boolean, UsedModifiers extends string> = UsedBg extends true ? unknown : BgRgbMethodsInterface<UsedFg, true, UsedModifiers>;
/**
* Represents a chainable builder for ANSI text styling with strong typing for colors and modifiers
*
* @template UsedFg - Indicates whether a foreground color has already been applied
* @template UsedBg - Indicates whether a background color has already been applied
* @template UsedModifiers - String literal union of already applied text modifiers
*
* @returns A function that can be called with text to format or used as a tagged template literal
*
* @remarks
* This type enables chainable styling API with TypeScript constraints to prevent applying the same
* category of styles multiple times. It combines function behavior with property access for intuitive
* styling composition.
*
* @example
* ```ts
* // Basic usage
* xterm.red.bold('Hello world');
*
* // As tagged template
* xterm.green.bgBlack`Success: ${data}`;
*
* // Chaining multiple styles
* xterm.yellow.bold.inverse('Warning');
*
* // RGB and hex colors
* xterm.rgb(255, 100, 50).bgHex('#003366')('Custom colored text');
* ```
*
* @see ansiModifiers
* @see ansiForegroundColors
* @see ansiBackgroundColors
*
* @since 1.0.0
*/
export type AnsiChainableBuilderType<UsedFg extends boolean = false, UsedBg extends boolean = false, UsedModifiers extends string = never> = AnsiFunctionType & ModifierPropsType<UsedFg, UsedBg, UsedModifiers> & FgColorPropsType<UsedFg, UsedBg, UsedModifiers> & BgColorPropsType<UsedFg, UsedBg, UsedModifiers> & BgRgbMethodsType<UsedFg, UsedBg, UsedModifiers> & RgbMethodsType<UsedFg, UsedBg, UsedModifiers>;
/**
* Pre-configured ANSI terminal styling utility with chainable methods
*
* @example
* ```ts
* // Basic styling
* console.log(xterm.bold("This is bold text"));
* console.log(xterm.red("This is red text"));
*
* // Chain multiple styles
* console.log(xterm.bold.red("This is bold and red"));
* console.log(xterm.green("This is green"));
*
* // Use with template literals
* const name = "World";
* console.log(xterm.cyan`Hello ${name}!`);
*
* // RGB and Hex colors
* console.log(xterm.rgb(255, 136, 0)("Custom orange text"));
* console.log(xterm.hex("#FF8800")("Hex orange text"));
*
* // Background colors
* console.log(xterm.bgGreen("Text with green background"));
* console.log(xterm.bgHex("#333333")("Text with a dark background"));
* ```
*
* @remarks
* The `xterm` export provides a convenient, ready-to-use instance of the chainable
* styling builder. It supports all standard ANSI styles, RGB colors, and hexadecimal
* color definitions for both foreground and background.
*
* This is the recommended entry point for using the styling functionality in most cases.
* For custom styling chains with pre-applied styles, use `createXtermChain()` directly.
*
* @see createXtermChain
* @see AnsiChainableBuilderType
*
* @since 1.0.0
*/
export declare const xterm: AnsiChainableBuilderType;
/**
* Represents a single character cell in the terminal with its properties
*
* @since 1.0.0
*/
export interface CellInterface {
/**
* The character to display in this cell
* @since 1.0.0
*/
char: string;
/**
* Indicates whether this cell has been modified and needs redrawing
* @since 1.0.0
*/
dirty: boolean;
}
/**
* Context information passed during the rendering process
*
* @remarks
* This interface encapsulates all the relevant information needed during
* the rendering of a single line. It's used internally by the render method
* to track the rendering state and accumulate output.
*
*
* @since 1.0.0
*/
export interface RenderContextInterface {
/**
* Whether to force redrawing of all cells regardless of dirty state
* @since 1.0.0
*/
force: boolean;
/**
* Accumulated output string to be written to the terminal
* @since 1.0.0
*/
output: string;
/**
* The current line in the view buffer being processed
* @since 1.0.0
*/
viewLine: Array<string>;
/**
* The screen row number currently being rendered
* @since 1.0.0
*/
screenRow: number;
/**
* The content line being rendered to the screen
*
* @see CellInterface
* @since 1.0.0
*/
contentLine: Array<CellInterface>;
}
/**
* Processes ANSI escape codes and updates the active styles map
*
* @param code - The ANSI code to process
* @param index - Current index in the codes array
* @param codes - Array of all ANSI codes in the sequence
* @param active - Map of active styles to be updated
* @returns The new index position after processing
*
* @throws InvalidCodeError - When an unsupported ANSI code is encountered
*
* @example
* ```ts
* const active = new Map<string, string>();
* const codes = ['1', '31'];
* const newIndex = processAnsiCode('1', 0, codes, active);
* ```
*
* @since 1.0.0
*/
export declare function processAnsiCode(code: string, index: number, codes: Array<string>, active: Map<string, string>): number;
/**
* Splits an ANSI-styled string into individual characters, each wrapped with current active ANSI codes and their resets
*
* @param str - The ANSI-styled string to process
* @returns An array of strings where each element is a character with its complete ANSI styling context
*
* @throws Error - If the ANSI sequence contains invalid codes
*
* @remarks
* This function maintains the styling context for each character by tracking active ANSI codes
* as it processes the input string. It reconstructs each visible character with its full styling
* information, ensuring that each character in the returned array has the proper ANSI codes
* prefixed and the corresponding reset codes suffixed.
*
* The function handles:
* - Plain text characters
* - ANSI escape sequences for styling
* - Multiple active styles simultaneously
*
* @example
* ```ts
* // Split a string with bold and colored text
* const input = "\x1b[1m\x1b[31mBold Red\x1b[0m";
* const chars = splitWithAnsiContext(input);
* // Result: Each character will be individually styled with bold and red
* // e.g., ["\x1b[1m\x1b[31mB\x1b[22m\x1b[39m", "\x1b[1m\x1b[31mo\x1b[22m\x1b[39m", ...]
* ```
*
* @see processAnsiCode - For details on how individual ANSI codes are processed
* @since 1.0.0
*/
export declare function splitWithAnsiContext(str: string): Array<string>;
/**
* A virtual terminal renderer that manages efficient screen updates
*
* ShadowRenderer provides a mechanism to render content to the terminal
* while minimizing the number of draw operations needed. It does this by
* maintaining an internal representation of both the desired content and
* the current terminal state, only updating parts of the screen that have
* changed between render cycles.
*
* @remarks
* The renderer maintains separate buffers for content (what should be displayed)
* and view (what is currently displayed). During rendering, it performs a diff
* between these buffers to determine the minimal set of changes needed to update
* the terminal display.
*
* This class supports:
* - Partial screen updates for performance
* - Content scrolling
* - Variable viewport dimensions
* - Rich text styling through cell properties
*
* @example
* ```ts
* // Create a new renderer positioned at row 2, column 3 with dimensions 80x24
* const renderer = new ShadowRenderer(2, 3, 80, 24);
*
* // Set some content and render it
* renderer.writeText(0, 0, contentCells);
* renderer.render();
* ```
*
* @since 1.0.0
*/
export declare class ShadowRenderer {
private terminalHeight;
private terminalWidth;
private topPosition;
private leftPosition;
/**
* Current scroll position in the content
*
* @remarks
* Tracks the index of the first row visible at the top of the viewport.
* A value of 0 indicates the content is not scrolled, while higher values
* indicate the content has been scrolled down by that many rows.
*
* This value is used during rendering to determine which portion of the
* contentBuffer to display in the visible area of the terminal.
*
* @see scroll - The getter for accessing this value
*
* @private
*/
private scrollPosition;
/**
* Internal buffer representing the current visible state of the terminal
*
* @remarks
* This two-dimensional array stores the actual rendered content as it appears in the terminal.
* It's organized in a row-major format, with each row containing an array of strings.
*
* Unlike contentBuffer which stores full cell information, viewBuffer only contains
* the string representation of each cell. This buffer is used for diffing against
* new content to determine what needs to be redrawn during render operations,
* allowing for efficient partial updates to the terminal display.
*
* @private
*/
private viewBuffer;
/**
* Internal buffer containing the content to be rendered
*
* @remarks
* This two-dimensional array stores all content cells in a row-major format,
* where each row is an array of CellInterface objects representing individual
* characters with their associated style information.
*
* The outer array represents rows, while the inner arrays represent columns within each row.
* This structure allows for efficient access and manipulation of cell data during
* the rendering process.
*
* @private
* @see CellInterface
*/
private contentBuffer;
/**
* Creates a new ShadowRenderer instance for terminal-based UI rendering
*
* @param terminalHeight - The height of the terminal viewport in rows
* @param terminalWidth - The width of the terminal viewport in columns
* @param topPosition - The top-offset position within the terminal
* @param leftPosition - The left offset position within the terminal
*
* @since 1.0.0
*/
constructor(terminalHeight: number, terminalWidth: number, topPosition: number, leftPosition: number);
/**
* Gets the top position offset of the renderer in the terminal
*
* @returns The row offset from the top edge of the terminal
*
* @since 1.0.0
*/
get top(): number;
/**
* Gets the left position offset of the renderer in the terminal
*
* @returns The column offset from the left edge of the terminal
*
* @since 1.0.0
*/
get left(): number;
/**
* Gets the width of the renderer's viewport
*
* @returns The number of columns visible in the renderer's viewport
*
* @since 1.0.0
*/
get width(): number;
/**
* Gets the height of the renderer's viewport
*
* @returns The number of rows visible in the renderer's viewport
*
* @since 1.0.0
*/
get height(): number;
/**
* Gets the current scroll position
*
* @returns The current row index at the top of the viewport
*
* @since 1.0.0
*/
get scroll(): number;
/**
* Sets the top position offset of the renderer in the terminal
*
* @param top - The row offset from the top edge of the terminal
*
* @remarks
* This setter updates the vertical positioning of the renderer's viewport
* within the terminal. The top position is used as an offset when calculating
* absolute cursor positions during rendering operations.
*
* Note that changing the top position does not automatically trigger a re-render.
* You should call the render() method separately after changing the position.
*
* @since 1.0.0
*/
set top(top: number);
/**
* Sets the left position offset of the renderer in the terminal
*
* @param left - The column offset from the left edge of the terminal
*
* @remarks
* This setter updates the horizontal positioning of the renderer's viewport
* within the terminal. The left position is used as an offset when calculating
* absolute cursor positions during rendering operations.
*
* Note that changing the left position does not automatically trigger a re-render.
* You should call the render() method separately after changing the position.
*
* @since 1.0.0
*/
set left(left: number);
/**
* Sets the width of the renderer's viewport
*
* @param terminalWidth - The number of columns visible in the renderer's viewport
*
* @remarks
* This setter updates the internal width property which controls how many
* columns are rendered during the rendering process. This should be updated
* whenever the terminal or display area is resized.
*
* Note that changing the width does not automatically trigger a re-render.
* You should call the render() method separately after changing dimensions.
*
* @since 1.0.0
*/
set width(terminalWidth: number);
/**
* Sets the height of the renderer's viewport
*
* @param terminalHeight - The number of rows visible in the renderer's viewport
*
* @remarks
* This setter updates the internal height property which controls how many
* rows are rendered during the rendering process. This should be updated
* whenever the terminal or display area is resized.
*
* Note that changing the height does not automatically trigger a re-render.
* You should call the render() method separately after changing dimensions.
*
* @since 1.0.0
*/
set height(terminalHeight: number);
/**
* Sets the scroll position and renders the updated view
*
* @param position - New scroll position or relative movement (if negative)
*
* @remarks
* This setter handles both absolute and relative scrolling:
* - Positive values set the absolute scroll position
* - Negative values move relative to the current position
*
* If the requested position scrolls beyond the end of the content,
* the operation is ignored. After setting a valid scroll position,
* the view is automatically re-rendered.
*
* @example
* ```ts
* // Set absolute scroll position to row 10
* renderer.scroll = 10;
*
* // Scroll up 3 rows (relative movement)
* renderer.scroll = -3;
* ```
*
* @since 1.0.0
*/
set scroll(position: number);
/**
* Clears the renderer by removing all content from the screen and resetting internal buffers
*
* @returns This method doesn't return a value
*
* @example
* ```ts
* // Reset the renderer state completely
* renderer.clear();
* ```
*
* @since 1.0.0
*/
clear(): void;
/**
* Clears the visible content from the terminal screen
*
* @returns Nothing
*
* @remarks
* This method builds a string of ANSI escape sequences that move the cursor
* to the beginning of each line in the view buffer and then clears each line.
* It doesn't reset the internal buffers, only clears the visible output.
*
* @example
* ```ts
* // Clear just the screen output without resetting buffers
* renderer.clearScreen();
* ```
*
* @since 1.0.0
*/
clearScreen(): void;
/**
* Writes text to the specified position in the content buffer
*
* @param row - Row position (0-based)
* @param column - Column position (0-based)
* @param text - Text to write
* @param clean - Whether to clear existing content first
*
* @remarks
* This method only updates the internal content buffer and marks cells as dirty.
* It doesn't immediately render to the screen - call render() to display changes.
* Only the first line of multi-line text is processed, and a text is truncated
* if it exceeds terminal boundaries.
*
* @example
* ```ts
* // Write text in the top-left corner
* renderer.writeText(0, 0, "Hello world");
*
* // Write text at position (5,10) and clear any existing content
* renderer.writeText(5, 10, "Menu Options", true);
*
* // Display the changes
* renderer.render();
* ```
*
* @since 1.0.0
*/
writeText(row: number, column: number, text: string, clean?: boolean): void;
/**
* Renders the content buffer to the screen using optimized terminal output
*
* @param force - Forces all cells to be redrawn, even if they haven't changed
*
* @remarks
* This method performs an optimized render by:
* - Only rendering the visible portion of the content buffer based on scroll position
* - Only updating cells that have been marked as dirty (unless force=true)
* - Clearing trailing content from previous renders
* - Repositioning the cursor to the bottom right when finished
*
* If the content buffer is empty or all content is scrolled out of view,
* the method will return early without performing any operations.
*
* @example
* ```ts
* // Normal render - only updates what changed
* renderer.render();
*
* // Force redraw of everything, useful after terminal resize
* renderer.render(true);
* ```
*
* @since 1.0.0
*/
render(force?: boolean): void;
/**
* Renders a single line of content to the output buffer
*
* @param context - The current rendering context
*
* @remarks
* This private method handles the optimization of terminal output by:
* - Skipping cells that haven't changed since the last render
* - Only moving the cursor when necessary
* - Updating the view buffer to reflect what's been rendered
* - Clearing the dirty flag on cells after they're processed
*
* The context object contains all states needed for the rendering process,
* including the accumulating output string and references to the current
* content and view lines.
*
* @private
* @since 1.0.0
*/
private renderLine;
/**
* Generates an ANSI escape sequence to move the cursor to a position
*
* @param row - The row position relative to renderer's viewport
* @param column - The column position relative to renderer's viewport (defaults to 0)
* @returns ANSI escape sequence string for cursor positioning
*
* @remarks
* This private helper method translates relative viewport coordinates to
* absolute terminal coordinates by adding the renderer's top and left
* position offsets. The returned value is a string containing the
* appropriate ANSI escape sequence.
*
* @private
* @since 1.0.0
*/
private moveCursor;
}