diff --git a/.vscode/opentui.code-snippets b/.vscode/opentui.code-snippets new file mode 100644 index 00000000..65d30248 --- /dev/null +++ b/.vscode/opentui.code-snippets @@ -0,0 +1,219 @@ +{ + // OpenTUI Component Snippets + + "OpenTUI Box Component": { + "prefix": "tui-box", + "body": [ + "const ${1:box} = new BoxRenderable('${2:id}', {", + " width: ${3:'100%'},", + " height: ${4:10},", + " border: ${5:true},", + " borderStyle: '${6|single,double,rounded,heavy|}',", + " padding: ${7:1}", + "});", + "$0" + ], + "description": "Create a BoxRenderable component" + }, + + "OpenTUI Text Component": { + "prefix": "tui-text", + "body": [ + "const ${1:text} = new TextRenderable('${2:id}', {", + " text: '${3:Hello World}',", + " color: ${4:'#ffffff'},", + " align: '${5|left,center,right|}',", + " wrap: ${6:true}", + "});", + "$0" + ], + "description": "Create a TextRenderable component" + }, + + "OpenTUI Input Component": { + "prefix": "tui-input", + "body": [ + "const ${1:input} = new InputRenderable('${2:id}', {", + " placeholder: '${3:Enter text...}',", + " value: '${4:}',", + " maxLength: ${5:50},", + " onChange: (value) => {", + " ${6:console.log(value);}", + " },", + " onSubmit: (value) => {", + " ${7:// Handle submit}", + " }", + "});", + "$0" + ], + "description": "Create an InputRenderable component" + }, + + "OpenTUI ASCII Font": { + "prefix": "tui-ascii", + "body": [ + "const ${1:title} = new ASCIIFontRenderable('${2:id}', {", + " text: '${3:TITLE}',", + " font: '${4|default,bulky,chrome,huge|}',", + " color: '${5:#00ff00}',", + " align: '${6|left,center,right|}'", + "});", + "$0" + ], + "description": "Create ASCII art text" + }, + + "OpenTUI Application": { + "prefix": "tui-app", + "body": [ + "import { CliRenderer, BoxRenderable, TextRenderable } from '@opentui/core';", + "", + "// Create renderer", + "const renderer = new CliRenderer(", + " lib,", + " rendererPtr,", + " process.stdin,", + " process.stdout,", + " ${1:80}, // width", + " ${2:24}, // height", + " {", + " backgroundColor: '${3:#1e1e1e}'", + " }", + ");", + "", + "// Create main container", + "const mainBox = new BoxRenderable('main', {", + " width: '100%',", + " height: '100%',", + " border: true,", + " borderStyle: 'rounded',", + " padding: 2", + "});", + "", + "// Add components", + "${4:// Your components here}", + "", + "// Build tree", + "renderer.root.add(mainBox, 0);", + "", + "// Start rendering", + "renderer.start();", + "$0" + ], + "description": "Create a complete OpenTUI application" + }, + + "OpenTUI Flexbox Layout": { + "prefix": "tui-flex", + "body": [ + "const ${1:container} = new BoxRenderable('${2:flex-container}', {", + " width: '100%',", + " height: '100%',", + " flexDirection: '${3|row,column,row-reverse,column-reverse|}',", + " justifyContent: '${4|flex-start,flex-end,center,space-between,space-around,space-evenly|}',", + " alignItems: '${5|flex-start,flex-end,center,stretch,baseline|}',", + " gap: ${6:1}", + "});", + "$0" + ], + "description": "Create a flexbox container" + }, + + "OpenTUI Animation Timeline": { + "prefix": "tui-timeline", + "body": [ + "const timeline = new Timeline({", + " duration: ${1:1000},", + " loop: ${2:false},", + " autoplay: ${3:true}", + "});", + "", + "timeline.add({", + " target: ${4:component},", + " properties: {", + " ${5:x}: { from: ${6:0}, to: ${7:100} },", + " ${8:opacity}: { from: ${9:0}, to: ${10:1} }", + " },", + " duration: ${11:500},", + " easing: '${12|linear,easeInQuad,easeOutQuad,easeInOutQuad,easeInCubic,easeOutCubic,easeInOutCubic|}'", + "});", + "$0" + ], + "description": "Create an animation timeline" + }, + + "OpenTUI Event Handler": { + "prefix": "tui-event", + "body": [ + "on${1|MouseDown,MouseUp,MouseMove,MouseDrag,MouseScroll,KeyDown,KeyUp|}: (${2:event}) => {", + " ${3:// Handle event}", + " ${4:return true; // Prevent bubbling}", + "}" + ], + "description": "Add an event handler" + }, + + "OpenTUI Custom Component": { + "prefix": "tui-component", + "body": [ + "class ${1:MyComponent} extends ${2|Renderable,BoxRenderable,TextRenderable|} {", + " constructor(id: string, options: ${3:RenderableOptions}) {", + " super(id, options);", + " ${4:// Initialize}", + " }", + "", + " protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void {", + " super.renderSelf(buffer, deltaTime);", + " ${5:// Custom rendering}", + " }", + "", + " handleKeyPress(key: ParsedKey | string): boolean {", + " ${6:// Handle keyboard input}", + " return super.handleKeyPress(key);", + " }", + "}", + "$0" + ], + "description": "Create a custom OpenTUI component" + }, + + "OpenTUI Form": { + "prefix": "tui-form", + "body": [ + "class ${1:LoginForm} extends BoxRenderable {", + " private ${2:username}Input: InputRenderable;", + " private ${3:password}Input: InputRenderable;", + "", + " constructor() {", + " super('${4:form}', {", + " flexDirection: 'column',", + " gap: 1,", + " padding: 2,", + " border: true,", + " title: '${5:Form Title}'", + " });", + "", + " this.${2}Input = new InputRenderable('${2}', {", + " placeholder: '${6:Username}',", + " onSubmit: () => this.${3}Input.focus()", + " });", + "", + " this.${3}Input = new InputRenderable('${3}', {", + " placeholder: '${7:Password}',", + " password: true,", + " onSubmit: () => this.submit()", + " });", + "", + " this.add(this.${2}Input, 0);", + " this.add(this.${3}Input, 1);", + " }", + "", + " private submit() {", + " ${8:// Handle form submission}", + " }", + "}", + "$0" + ], + "description": "Create a form with inputs" + } +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..aec8880f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,73 @@ +{ + // TypeScript & JavaScript + "typescript.tsdk": "node_modules/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true, + "typescript.preferences.includePackageJsonAutoImports": "on", + "typescript.preferences.quoteStyle": "single", + "typescript.suggest.paths": true, + "typescript.suggest.completeFunctionCalls": true, + "typescript.updateImportsOnFileMove.enabled": "always", + "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + // IntelliSense Enhancement + "editor.quickSuggestions": { + "strings": true, + "comments": false, + "other": true + }, + "editor.suggest.snippetsPreventQuickSuggestions": false, + "editor.suggest.showMethods": true, + "editor.suggest.showFunctions": true, + "editor.suggest.showConstructors": true, + "editor.suggest.showFields": true, + "editor.suggest.showVariables": true, + "editor.suggest.showClasses": true, + "editor.suggest.showStructs": true, + "editor.suggest.showInterfaces": true, + "editor.suggest.showModules": true, + "editor.suggest.showProperties": true, + "editor.suggest.showEvents": true, + "editor.suggest.showOperators": true, + "editor.suggest.showUnits": true, + "editor.suggest.showValues": true, + "editor.suggest.showConstants": true, + "editor.suggest.showEnums": true, + "editor.suggest.showEnumMembers": true, + "editor.suggest.showKeywords": true, + "editor.suggest.showWords": true, + "editor.suggest.showColors": true, + "editor.suggest.showFiles": true, + "editor.suggest.showReferences": true, + "editor.suggest.showCustomcolors": true, + "editor.suggest.showFolders": true, + "editor.suggest.showTypeParameters": true, + "editor.suggest.showSnippets": true, + "editor.suggest.showIssues": true, + "editor.suggest.showUsers": true, + // Auto Import + "javascript.suggest.autoImports": true, + "typescript.suggest.autoImports": true, + "javascript.updateImportsOnFileMove.enabled": "always", + // Code Actions + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit", + "source.fixAll.eslint": "explicit" + }, + // File Associations + "files.associations": { + "*.tsx": "typescriptreact", + "*.ts": "typescript", + "*.jsx": "javascriptreact", + "*.js": "javascript" + }, + // OpenTUI Specific + "typescript.preferences.importModuleSpecifier": "non-relative", + // Prettier + "editor.formatOnSave": true, + // Search Exclusions + "search.exclude": { + "**/node_modules": true, + "**/dist": true, + "**/build": true, + "**/.git": true + } +} diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..e0cf73d7 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,78 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +OpenTUI is a TypeScript library for building terminal user interfaces (TUIs), serving as the foundational framework for opencode and terminaldotshop projects. The project is structured as a monorepo with multiple packages. + +## Essential Commands + +```bash +# Development +bun install # Install dependencies +bun run build # Build all packages +cd packages/core && bun run src/examples/index.ts # Run core examples + +# Package-specific builds (from packages/core) +bun run build:dev # Debug build with Zig +bun run build:prod # Production build with Zig +bun run build # Full build (native + TypeScript) + +# Testing +bun test # Run all tests +bun test # Run specific test file + +# Release workflow +bun run prepare-release # Prepare for release +bun run pre-publish # Pre-publish checks +bun run publish # Publish packages +``` + +## Architecture + +### Package Structure +- **@opentui/core**: Core library with imperative API, renderables, animations, text styling, and input handling. Contains native Zig components for performance-critical operations. +- **@opentui/react**: React reconciler implementation with custom hooks (useKeyboard, useRenderer, useResize) +- **@opentui/solid**: SolidJS reconciler with JSX runtime and Babel transformation + +### Key Technologies +- **Runtime**: Bun (>=1.2.0 required) +- **Language**: TypeScript with strict mode +- **Native**: Zig (0.14.0-0.14.1) for performance-critical components +- **Cross-platform**: Builds for darwin/linux/windows on x64/arm64 + +### Native Integration +The core package includes Zig components that compile to native libraries (.so, .dll, .dylib) for each platform. These handle performance-critical rendering operations and are automatically built during `bun run build`. + +### 3D Capabilities +Core package exports 3D features through separate entry points: +- WebGPU integration +- Three.js support +- Physics engines (Rapier, Planck) + +## Development Patterns + +### Testing +Tests use Bun's built-in test framework. Import pattern: +```typescript +import { expect, describe, it, beforeEach, afterEach } from "bun:test" +``` + +### Code Style +- No semicolons (Prettier configured) +- 120 character line width +- Explicit TypeScript types for public APIs +- camelCase for variables/functions, PascalCase for classes/interfaces + +### File Organization +- Group related functionality in directories +- Use index files for clean exports +- Examples in `/examples` directories within each package + +## Important Notes + +- Always use Bun (not npm/yarn) for package management +- Native builds require Zig 0.14.0-0.14.1 installed +- When modifying native code, rebuild with appropriate optimization level +- Cross-platform binaries are pre-built but can be regenerated with build commands \ No newline at end of file diff --git a/packages/core/docs/api/api-summary.md b/packages/core/docs/api/api-summary.md new file mode 100644 index 00000000..f8d2d199 --- /dev/null +++ b/packages/core/docs/api/api-summary.md @@ -0,0 +1,427 @@ +# OpenTUI API Summary + +## Classes + +### Renderable + +**Constructor:** +```typescript +constructor(id: string, options: RenderableOptions) +``` + +**Properties:** +- `renderablesByNumber: Map` +- `id: string` +- `num: number` +- `selectable: boolean` +- `parent: Renderable | null` + +**Methods:** +- `hasSelection(): boolean` +- `onSelectionChanged(selection: SelectionState | null): boolean` +- `getSelectedText(): string` +- `shouldStartSelection(x: number, y: number): boolean` +- `focus(): void` +- `blur(): void` +- `handleKeyPress(key: ParsedKey | string): boolean` +- `needsUpdate(): void` +- `requestZIndexSort(): void` +- `setPosition(position: Position): void` +- `getLayoutNode(): TrackedNode` +- `updateFromLayout(): void` +- `add(obj: Renderable, index: number): number` +- `insertBefore(obj: Renderable, anchor: Renderable): number` +- `propagateContext(ctx: RenderContext | null): void` +- `getRenderable(id: string): Renderable` +- `remove(id: string): void` +- `getChildren(): Renderable[]` +- `render(buffer: OptimizedBuffer, deltaTime: number): void` +- `destroy(): void` +- `destroyRecursively(): void` +- `processMouseEvent(event: MouseEvent): void` + +### RootRenderable + +**Constructor:** +```typescript +constructor(width: number, height: number, ctx: RenderContext, rootContext: RootContext) +``` + +**Methods:** +- `requestLayout(): void` +- `calculateLayout(): void` +- `resize(width: number, height: number): void` + +### MouseEvent + +**Constructor:** +```typescript +constructor(target: Renderable | null, attributes: RawMouseEvent & { source?: Renderable }) +``` + +**Properties:** +- `type: MouseEventType` +- `button: number` +- `x: number` +- `y: number` +- `source: Renderable` +- `modifiers: { + shift: boolean + alt: boolean + ctrl: boolean + }` +- `scroll: ScrollInfo` +- `target: Renderable | null` + +**Methods:** +- `preventDefault(): void` + +### CliRenderer + +**Constructor:** +```typescript +constructor(lib: RenderLib, rendererPtr: Pointer, stdin: NodeJS.ReadStream, stdout: NodeJS.WriteStream, width: number, height: number, config: CliRendererConfig) +``` + +**Properties:** +- `rendererPtr: Pointer` +- `nextRenderBuffer: OptimizedBuffer` +- `currentRenderBuffer: OptimizedBuffer` +- `root: RootRenderable` +- `width: number` +- `height: number` +- `debugOverlay: any` + +**Methods:** +- `needsUpdate(): void` +- `setMemorySnapshotInterval(interval: number): void` +- `setBackgroundColor(color: ColorInput): void` +- `toggleDebugOverlay(): void` +- `configureDebugOverlay(options: { enabled?: boolean; corner?: DebugOverlayCorner }): void` +- `clearTerminal(): void` +- `dumpHitGrid(): void` +- `dumpBuffers(timestamp: number): void` +- `dumpStdoutBuffer(timestamp: number): void` +- `setCursorPosition(x: number, y: number, visible: boolean): void` +- `setCursorStyle(style: CursorStyle, blinking: boolean, color: RGBA): void` +- `setCursorColor(color: RGBA): void` +- `setCursorPosition(x: number, y: number, visible: boolean): void` +- `setCursorStyle(style: CursorStyle, blinking: boolean, color: RGBA): void` +- `setCursorColor(color: RGBA): void` +- `addPostProcessFn(processFn: (buffer: OptimizedBuffer, deltaTime: number) => void): void` +- `removePostProcessFn(processFn: (buffer: OptimizedBuffer, deltaTime: number) => void): void` +- `clearPostProcessFns(): void` +- `setFrameCallback(callback: (deltaTime: number) => Promise): void` +- `removeFrameCallback(callback: (deltaTime: number) => Promise): void` +- `clearFrameCallbacks(): void` +- `requestLive(): void` +- `dropLive(): void` +- `start(): void` +- `pause(): void` +- `stop(): void` +- `destroy(): void` +- `intermediateRender(): void` +- `getStats(): { fps: number; frameCount: number; frameTimes: number[]; averageFrameTime: number; minFrameTime: number; maxFrameTime: number; }` +- `resetStats(): void` +- `setGatherStats(enabled: boolean): void` +- `getSelection(): Selection` +- `getSelectionContainer(): Renderable` +- `hasSelection(): boolean` +- `clearSelection(): void` + +### OptimizedBuffer + +**Constructor:** +```typescript +constructor(lib: RenderLib, ptr: Pointer, buffer: { + char: Uint32Array + fg: Float32Array + bg: Float32Array + attributes: Uint8Array + }, width: number, height: number, options: { respectAlpha?: boolean }) +``` + +**Properties:** +- `id: string` +- `lib: RenderLib` +- `respectAlpha: boolean` + +**Methods:** +- `create(width: number, height: number, options: { respectAlpha?: boolean }): OptimizedBuffer` +- `getWidth(): number` +- `getHeight(): number` +- `setRespectAlpha(respectAlpha: boolean): void` +- `clear(bg: RGBA, clearChar: string): void` +- `clearLocal(bg: RGBA, clearChar: string): void` +- `setCell(x: number, y: number, char: string, fg: RGBA, bg: RGBA, attributes: number): void` +- `get(x: number, y: number): { char: number; fg: RGBA; bg: RGBA; attributes: number; }` +- `setCellWithAlphaBlending(x: number, y: number, char: string, fg: RGBA, bg: RGBA, attributes: number): void` +- `setCellWithAlphaBlendingLocal(x: number, y: number, char: string, fg: RGBA, bg: RGBA, attributes: number): void` +- `drawText(text: string, x: number, y: number, fg: RGBA, bg: RGBA, attributes: number, selection: { start: number; end: number; bgColor?: RGBA; fgColor?: RGBA } | null): void` +- `fillRect(x: number, y: number, width: number, height: number, bg: RGBA): void` +- `fillRectLocal(x: number, y: number, width: number, height: number, bg: RGBA): void` +- `drawFrameBuffer(destX: number, destY: number, frameBuffer: OptimizedBuffer, sourceX: number, sourceY: number, sourceWidth: number, sourceHeight: number): void` +- `drawFrameBufferLocal(destX: number, destY: number, frameBuffer: OptimizedBuffer, sourceX: number, sourceY: number, sourceWidth: number, sourceHeight: number): void` +- `destroy(): void` +- `drawTextBuffer(textBuffer: TextBuffer, x: number, y: number, clipRect: { x: number; y: number; width: number; height: number }): void` +- `drawSuperSampleBuffer(x: number, y: number, pixelDataPtr: Pointer, pixelDataLength: number, format: "bgra8unorm" | "rgba8unorm", alignedBytesPerRow: number): void` +- `drawSuperSampleBufferFFI(x: number, y: number, pixelDataPtr: Pointer, pixelDataLength: number, format: "bgra8unorm" | "rgba8unorm", alignedBytesPerRow: number): void` +- `drawPackedBuffer(dataPtr: Pointer, dataLen: number, posX: number, posY: number, terminalWidthCells: number, terminalHeightCells: number): void` +- `setCellWithAlphaBlendingFFI(x: number, y: number, char: string, fg: RGBA, bg: RGBA, attributes: number): void` +- `fillRectFFI(x: number, y: number, width: number, height: number, bg: RGBA): void` +- `resize(width: number, height: number): void` +- `clearFFI(bg: RGBA): void` +- `drawTextFFI(text: string, x: number, y: number, fg: RGBA, bg: RGBA, attributes: number): void` +- `drawFrameBufferFFI(destX: number, destY: number, frameBuffer: OptimizedBuffer, sourceX: number, sourceY: number, sourceWidth: number, sourceHeight: number): void` +- `drawBox(options: { + x: number + y: number + width: number + height: number + borderStyle?: BorderStyle + customBorderChars?: Uint32Array + border: boolean | BorderSides[] + borderColor: RGBA + backgroundColor: RGBA + shouldFill?: boolean + title?: string + titleAlignment?: "left" | "center" | "right" + }): void` + +### BoxRenderable + +**Constructor:** +```typescript +constructor(id: string, options: BoxOptions) +``` + +**Properties:** +- `shouldFill: boolean` + +### TextRenderable + +**Constructor:** +```typescript +constructor(id: string, options: TextOptions) +``` + +**Properties:** +- `selectable: boolean` + +**Methods:** +- `shouldStartSelection(x: number, y: number): boolean` +- `onSelectionChanged(selection: SelectionState | null): boolean` +- `getSelectedText(): string` +- `hasSelection(): boolean` +- `destroy(): void` + +### ASCIIFontRenderable + +**Constructor:** +```typescript +constructor(id: string, options: ASCIIFontOptions) +``` + +**Properties:** +- `selectable: boolean` + +**Methods:** +- `shouldStartSelection(x: number, y: number): boolean` +- `onSelectionChanged(selection: SelectionState | null): boolean` +- `getSelectedText(): string` +- `hasSelection(): boolean` + +### InputRenderable + +**Constructor:** +```typescript +constructor(id: string, options: InputRenderableOptions) +``` + +**Methods:** +- `focus(): void` +- `blur(): void` +- `handleKeyPress(key: ParsedKey | string): boolean` + +### Timeline + +**Constructor:** +```typescript +constructor(options: TimelineOptions) +``` + +**Properties:** +- `items: (TimelineAnimationItem | TimelineCallbackItem)[]` +- `subTimelines: TimelineTimelineItem[]` +- `currentTime: number` +- `isPlaying: boolean` +- `isComplete: boolean` +- `duration: number` +- `loop: boolean` +- `synced: boolean` + +**Methods:** +- `add(target: any, properties: AnimationOptions, startTime: number | string): this` +- `once(target: any, properties: AnimationOptions): this` +- `call(callback: () => void, startTime: number | string): this` +- `sync(timeline: Timeline, startTime: number): this` +- `play(): this` +- `pause(): this` +- `resetItems(): void` +- `restart(): this` +- `update(deltaTime: number): void` + +## Interfaces + +### RootContext + +- `requestLive: void` +- `dropLive: void` + +### Position + +- `top: number | "auto" | `${number}%`` +- `right: number | "auto" | `${number}%`` +- `bottom: number | "auto" | `${number}%`` +- `left: number | "auto" | `${number}%`` + +### LayoutOptions + +- `flexGrow: number` +- `flexShrink: number` +- `flexDirection: FlexDirectionString` +- `alignItems: AlignString` +- `justifyContent: JustifyString` +- `flexBasis: number | "auto" | undefined` +- `position: PositionTypeString` +- `top: number | "auto" | `${number}%`` +- `right: number | "auto" | `${number}%`` +- `bottom: number | "auto" | `${number}%`` +- `left: number | "auto" | `${number}%`` +- `minWidth: number` +- `minHeight: number` +- `maxWidth: number` +- `maxHeight: number` +- `margin: number | "auto" | `${number}%`` +- `marginTop: number | "auto" | `${number}%`` +- `marginRight: number | "auto" | `${number}%`` +- `marginBottom: number | "auto" | `${number}%`` +- `marginLeft: number | "auto" | `${number}%`` +- `padding: number | `${number}%`` +- `paddingTop: number | `${number}%`` +- `paddingRight: number | `${number}%`` +- `paddingBottom: number | `${number}%`` +- `paddingLeft: number | `${number}%`` +- `enableLayout: boolean` + +### RenderableOptions + +- `width: number | "auto" | `${number}%`` +- `height: number | "auto" | `${number}%`` +- `zIndex: number` +- `visible: boolean` +- `buffered: boolean` +- `live: boolean` +- `onMouseDown: (event: MouseEvent) => void` +- `onMouseUp: (event: MouseEvent) => void` +- `onMouseMove: (event: MouseEvent) => void` +- `onMouseDrag: (event: MouseEvent) => void` +- `onMouseDragEnd: (event: MouseEvent) => void` +- `onMouseDrop: (event: MouseEvent) => void` +- `onMouseOver: (event: MouseEvent) => void` +- `onMouseOut: (event: MouseEvent) => void` +- `onMouseScroll: (event: MouseEvent) => void` +- `onKeyDown: (key: ParsedKey) => void` + +### CliRendererConfig + +- `stdin: NodeJS.ReadStream` +- `stdout: NodeJS.WriteStream` +- `exitOnCtrlC: boolean` +- `debounceDelay: number` +- `targetFps: number` +- `memorySnapshotInterval: number` +- `useThread: boolean` +- `gatherStats: boolean` +- `maxStatSamples: number` +- `consoleOptions: ConsoleOptions` +- `postProcessFns: ((buffer: OptimizedBuffer, deltaTime: number) => void)[]` +- `enableMouseMovement: boolean` +- `useMouse: boolean` +- `useAlternateScreen: boolean` +- `useConsole: boolean` +- `experimental_splitHeight: number` + +### BoxOptions + +- `backgroundColor: string | RGBA` +- `borderStyle: BorderStyle` +- `border: boolean | BorderSides[]` +- `borderColor: string | RGBA` +- `customBorderChars: BorderCharacters` +- `shouldFill: boolean` +- `title: string` +- `titleAlignment: "left" | "center" | "right"` +- `focusedBorderColor: ColorInput` + +### TextOptions + +- `content: StyledText | string` +- `fg: string | RGBA` +- `bg: string | RGBA` +- `selectionBg: string | RGBA` +- `selectionFg: string | RGBA` +- `selectable: boolean` +- `attributes: number` + +### ASCIIFontOptions + +- `text: string` +- `font: "tiny" | "block" | "shade" | "slick"` +- `fg: RGBA | RGBA[]` +- `bg: RGBA` +- `selectionBg: string | RGBA` +- `selectionFg: string | RGBA` +- `selectable: boolean` + +### InputRenderableOptions + +- `backgroundColor: ColorInput` +- `textColor: ColorInput` +- `focusedBackgroundColor: ColorInput` +- `focusedTextColor: ColorInput` +- `placeholder: string` +- `placeholderColor: ColorInput` +- `cursorColor: ColorInput` +- `maxLength: number` +- `value: string` + +### TimelineOptions + +- `duration: number` +- `loop: boolean` +- `autoplay: boolean` +- `onComplete: () => void` +- `onPause: () => void` + +### AnimationOptions + +- `duration: number` +- `ease: EasingFunctions` +- `onUpdate: (animation: JSAnimation) => void` +- `onComplete: () => void` +- `onStart: () => void` +- `onLoop: () => void` +- `loop: boolean | number` +- `loopDelay: number` +- `alternate: boolean` +- `once: boolean` +- `: any` + +### JSAnimation + +- `targets: any[]` +- `deltaTime: number` +- `progress: number` +- `currentTime: number` + diff --git a/packages/core/docs/api/extracted-api.json b/packages/core/docs/api/extracted-api.json new file mode 100644 index 00000000..363a77d4 --- /dev/null +++ b/packages/core/docs/api/extracted-api.json @@ -0,0 +1,2262 @@ +{ + "classes": [ + { + "name": "Renderable", + "methods": [ + { + "name": "hasSelection", + "returnType": "boolean", + "parameters": [] + }, + { + "name": "onSelectionChanged", + "returnType": "boolean", + "parameters": [ + { + "name": "selection", + "type": "SelectionState | null" + } + ] + }, + { + "name": "getSelectedText", + "returnType": "string", + "parameters": [] + }, + { + "name": "shouldStartSelection", + "returnType": "boolean", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + } + ] + }, + { + "name": "focus", + "returnType": "void", + "parameters": [] + }, + { + "name": "blur", + "returnType": "void", + "parameters": [] + }, + { + "name": "handleKeyPress", + "returnType": "boolean", + "parameters": [ + { + "name": "key", + "type": "ParsedKey | string" + } + ] + }, + { + "name": "needsUpdate", + "returnType": "void", + "parameters": [] + }, + { + "name": "requestZIndexSort", + "returnType": "void", + "parameters": [] + }, + { + "name": "setPosition", + "returnType": "void", + "parameters": [ + { + "name": "position", + "type": "Position" + } + ] + }, + { + "name": "getLayoutNode", + "returnType": "TrackedNode", + "parameters": [] + }, + { + "name": "updateFromLayout", + "returnType": "void", + "parameters": [] + }, + { + "name": "add", + "returnType": "number", + "parameters": [ + { + "name": "obj", + "type": "Renderable" + }, + { + "name": "index", + "type": "number" + } + ] + }, + { + "name": "insertBefore", + "returnType": "number", + "parameters": [ + { + "name": "obj", + "type": "Renderable" + }, + { + "name": "anchor", + "type": "Renderable" + } + ] + }, + { + "name": "propagateContext", + "returnType": "void", + "parameters": [ + { + "name": "ctx", + "type": "RenderContext | null" + } + ] + }, + { + "name": "getRenderable", + "returnType": "Renderable", + "parameters": [ + { + "name": "id", + "type": "string" + } + ] + }, + { + "name": "remove", + "returnType": "void", + "parameters": [ + { + "name": "id", + "type": "string" + } + ] + }, + { + "name": "getChildren", + "returnType": "Renderable[]", + "parameters": [] + }, + { + "name": "render", + "returnType": "void", + "parameters": [ + { + "name": "buffer", + "type": "OptimizedBuffer" + }, + { + "name": "deltaTime", + "type": "number" + } + ] + }, + { + "name": "destroy", + "returnType": "void", + "parameters": [] + }, + { + "name": "destroyRecursively", + "returnType": "void", + "parameters": [] + }, + { + "name": "processMouseEvent", + "returnType": "void", + "parameters": [ + { + "name": "event", + "type": "MouseEvent" + } + ] + } + ], + "properties": [ + { + "name": "renderablesByNumber", + "type": "Map" + }, + { + "name": "id", + "type": "string" + }, + { + "name": "num", + "type": "number" + }, + { + "name": "selectable", + "type": "boolean" + }, + { + "name": "parent", + "type": "Renderable | null" + } + ], + "constructor": { + "parameters": [ + { + "name": "id", + "type": "string" + }, + { + "name": "options", + "type": "RenderableOptions" + } + ] + } + }, + { + "name": "RootRenderable", + "methods": [ + { + "name": "requestLayout", + "returnType": "void", + "parameters": [] + }, + { + "name": "calculateLayout", + "returnType": "void", + "parameters": [] + }, + { + "name": "resize", + "returnType": "void", + "parameters": [ + { + "name": "width", + "type": "number" + }, + { + "name": "height", + "type": "number" + } + ] + } + ], + "properties": [], + "constructor": { + "parameters": [ + { + "name": "width", + "type": "number" + }, + { + "name": "height", + "type": "number" + }, + { + "name": "ctx", + "type": "RenderContext" + }, + { + "name": "rootContext", + "type": "RootContext" + } + ] + } + }, + { + "name": "MouseEvent", + "methods": [ + { + "name": "preventDefault", + "returnType": "void", + "parameters": [] + } + ], + "properties": [ + { + "name": "type", + "type": "MouseEventType" + }, + { + "name": "button", + "type": "number" + }, + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "source", + "type": "Renderable" + }, + { + "name": "modifiers", + "type": "{\n shift: boolean\n alt: boolean\n ctrl: boolean\n }" + }, + { + "name": "scroll", + "type": "ScrollInfo" + }, + { + "name": "target", + "type": "Renderable | null" + } + ], + "constructor": { + "parameters": [ + { + "name": "target", + "type": "Renderable | null" + }, + { + "name": "attributes", + "type": "RawMouseEvent & { source?: Renderable }" + } + ] + } + }, + { + "name": "CliRenderer", + "methods": [ + { + "name": "needsUpdate", + "returnType": "void", + "parameters": [] + }, + { + "name": "setMemorySnapshotInterval", + "returnType": "void", + "parameters": [ + { + "name": "interval", + "type": "number" + } + ] + }, + { + "name": "setBackgroundColor", + "returnType": "void", + "parameters": [ + { + "name": "color", + "type": "ColorInput" + } + ] + }, + { + "name": "toggleDebugOverlay", + "returnType": "void", + "parameters": [] + }, + { + "name": "configureDebugOverlay", + "returnType": "void", + "parameters": [ + { + "name": "options", + "type": "{ enabled?: boolean; corner?: DebugOverlayCorner }" + } + ] + }, + { + "name": "clearTerminal", + "returnType": "void", + "parameters": [] + }, + { + "name": "dumpHitGrid", + "returnType": "void", + "parameters": [] + }, + { + "name": "dumpBuffers", + "returnType": "void", + "parameters": [ + { + "name": "timestamp", + "type": "number" + } + ] + }, + { + "name": "dumpStdoutBuffer", + "returnType": "void", + "parameters": [ + { + "name": "timestamp", + "type": "number" + } + ] + }, + { + "name": "setCursorPosition", + "returnType": "void", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "visible", + "type": "boolean" + } + ] + }, + { + "name": "setCursorStyle", + "returnType": "void", + "parameters": [ + { + "name": "style", + "type": "CursorStyle" + }, + { + "name": "blinking", + "type": "boolean" + }, + { + "name": "color", + "type": "RGBA" + } + ] + }, + { + "name": "setCursorColor", + "returnType": "void", + "parameters": [ + { + "name": "color", + "type": "RGBA" + } + ] + }, + { + "name": "setCursorPosition", + "returnType": "void", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "visible", + "type": "boolean" + } + ] + }, + { + "name": "setCursorStyle", + "returnType": "void", + "parameters": [ + { + "name": "style", + "type": "CursorStyle" + }, + { + "name": "blinking", + "type": "boolean" + }, + { + "name": "color", + "type": "RGBA" + } + ] + }, + { + "name": "setCursorColor", + "returnType": "void", + "parameters": [ + { + "name": "color", + "type": "RGBA" + } + ] + }, + { + "name": "addPostProcessFn", + "returnType": "void", + "parameters": [ + { + "name": "processFn", + "type": "(buffer: OptimizedBuffer, deltaTime: number) => void" + } + ] + }, + { + "name": "removePostProcessFn", + "returnType": "void", + "parameters": [ + { + "name": "processFn", + "type": "(buffer: OptimizedBuffer, deltaTime: number) => void" + } + ] + }, + { + "name": "clearPostProcessFns", + "returnType": "void", + "parameters": [] + }, + { + "name": "setFrameCallback", + "returnType": "void", + "parameters": [ + { + "name": "callback", + "type": "(deltaTime: number) => Promise" + } + ] + }, + { + "name": "removeFrameCallback", + "returnType": "void", + "parameters": [ + { + "name": "callback", + "type": "(deltaTime: number) => Promise" + } + ] + }, + { + "name": "clearFrameCallbacks", + "returnType": "void", + "parameters": [] + }, + { + "name": "requestLive", + "returnType": "void", + "parameters": [] + }, + { + "name": "dropLive", + "returnType": "void", + "parameters": [] + }, + { + "name": "start", + "returnType": "void", + "parameters": [] + }, + { + "name": "pause", + "returnType": "void", + "parameters": [] + }, + { + "name": "stop", + "returnType": "void", + "parameters": [] + }, + { + "name": "destroy", + "returnType": "void", + "parameters": [] + }, + { + "name": "intermediateRender", + "returnType": "void", + "parameters": [] + }, + { + "name": "getStats", + "returnType": "{ fps: number; frameCount: number; frameTimes: number[]; averageFrameTime: number; minFrameTime: number; maxFrameTime: number; }", + "parameters": [] + }, + { + "name": "resetStats", + "returnType": "void", + "parameters": [] + }, + { + "name": "setGatherStats", + "returnType": "void", + "parameters": [ + { + "name": "enabled", + "type": "boolean" + } + ] + }, + { + "name": "getSelection", + "returnType": "Selection", + "parameters": [] + }, + { + "name": "getSelectionContainer", + "returnType": "Renderable", + "parameters": [] + }, + { + "name": "hasSelection", + "returnType": "boolean", + "parameters": [] + }, + { + "name": "clearSelection", + "returnType": "void", + "parameters": [] + } + ], + "properties": [ + { + "name": "rendererPtr", + "type": "Pointer" + }, + { + "name": "nextRenderBuffer", + "type": "OptimizedBuffer" + }, + { + "name": "currentRenderBuffer", + "type": "OptimizedBuffer" + }, + { + "name": "root", + "type": "RootRenderable" + }, + { + "name": "width", + "type": "number" + }, + { + "name": "height", + "type": "number" + }, + { + "name": "debugOverlay", + "type": "any" + } + ], + "constructor": { + "parameters": [ + { + "name": "lib", + "type": "RenderLib" + }, + { + "name": "rendererPtr", + "type": "Pointer" + }, + { + "name": "stdin", + "type": "NodeJS.ReadStream" + }, + { + "name": "stdout", + "type": "NodeJS.WriteStream" + }, + { + "name": "width", + "type": "number" + }, + { + "name": "height", + "type": "number" + }, + { + "name": "config", + "type": "CliRendererConfig" + } + ] + } + }, + { + "name": "OptimizedBuffer", + "methods": [ + { + "name": "create", + "returnType": "OptimizedBuffer", + "parameters": [ + { + "name": "width", + "type": "number" + }, + { + "name": "height", + "type": "number" + }, + { + "name": "options", + "type": "{ respectAlpha?: boolean }" + } + ] + }, + { + "name": "getWidth", + "returnType": "number", + "parameters": [] + }, + { + "name": "getHeight", + "returnType": "number", + "parameters": [] + }, + { + "name": "setRespectAlpha", + "returnType": "void", + "parameters": [ + { + "name": "respectAlpha", + "type": "boolean" + } + ] + }, + { + "name": "clear", + "returnType": "void", + "parameters": [ + { + "name": "bg", + "type": "RGBA" + }, + { + "name": "clearChar", + "type": "string" + } + ] + }, + { + "name": "clearLocal", + "returnType": "void", + "parameters": [ + { + "name": "bg", + "type": "RGBA" + }, + { + "name": "clearChar", + "type": "string" + } + ] + }, + { + "name": "setCell", + "returnType": "void", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "char", + "type": "string" + }, + { + "name": "fg", + "type": "RGBA" + }, + { + "name": "bg", + "type": "RGBA" + }, + { + "name": "attributes", + "type": "number" + } + ] + }, + { + "name": "get", + "returnType": "{ char: number; fg: RGBA; bg: RGBA; attributes: number; }", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + } + ] + }, + { + "name": "setCellWithAlphaBlending", + "returnType": "void", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "char", + "type": "string" + }, + { + "name": "fg", + "type": "RGBA" + }, + { + "name": "bg", + "type": "RGBA" + }, + { + "name": "attributes", + "type": "number" + } + ] + }, + { + "name": "setCellWithAlphaBlendingLocal", + "returnType": "void", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "char", + "type": "string" + }, + { + "name": "fg", + "type": "RGBA" + }, + { + "name": "bg", + "type": "RGBA" + }, + { + "name": "attributes", + "type": "number" + } + ] + }, + { + "name": "drawText", + "returnType": "void", + "parameters": [ + { + "name": "text", + "type": "string" + }, + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "fg", + "type": "RGBA" + }, + { + "name": "bg", + "type": "RGBA" + }, + { + "name": "attributes", + "type": "number" + }, + { + "name": "selection", + "type": "{ start: number; end: number; bgColor?: RGBA; fgColor?: RGBA } | null" + } + ] + }, + { + "name": "fillRect", + "returnType": "void", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "width", + "type": "number" + }, + { + "name": "height", + "type": "number" + }, + { + "name": "bg", + "type": "RGBA" + } + ] + }, + { + "name": "fillRectLocal", + "returnType": "void", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "width", + "type": "number" + }, + { + "name": "height", + "type": "number" + }, + { + "name": "bg", + "type": "RGBA" + } + ] + }, + { + "name": "drawFrameBuffer", + "returnType": "void", + "parameters": [ + { + "name": "destX", + "type": "number" + }, + { + "name": "destY", + "type": "number" + }, + { + "name": "frameBuffer", + "type": "OptimizedBuffer" + }, + { + "name": "sourceX", + "type": "number" + }, + { + "name": "sourceY", + "type": "number" + }, + { + "name": "sourceWidth", + "type": "number" + }, + { + "name": "sourceHeight", + "type": "number" + } + ] + }, + { + "name": "drawFrameBufferLocal", + "returnType": "void", + "parameters": [ + { + "name": "destX", + "type": "number" + }, + { + "name": "destY", + "type": "number" + }, + { + "name": "frameBuffer", + "type": "OptimizedBuffer" + }, + { + "name": "sourceX", + "type": "number" + }, + { + "name": "sourceY", + "type": "number" + }, + { + "name": "sourceWidth", + "type": "number" + }, + { + "name": "sourceHeight", + "type": "number" + } + ] + }, + { + "name": "destroy", + "returnType": "void", + "parameters": [] + }, + { + "name": "drawTextBuffer", + "returnType": "void", + "parameters": [ + { + "name": "textBuffer", + "type": "TextBuffer" + }, + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "clipRect", + "type": "{ x: number; y: number; width: number; height: number }" + } + ] + }, + { + "name": "drawSuperSampleBuffer", + "returnType": "void", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "pixelDataPtr", + "type": "Pointer" + }, + { + "name": "pixelDataLength", + "type": "number" + }, + { + "name": "format", + "type": "\"bgra8unorm\" | \"rgba8unorm\"" + }, + { + "name": "alignedBytesPerRow", + "type": "number" + } + ] + }, + { + "name": "drawSuperSampleBufferFFI", + "returnType": "void", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "pixelDataPtr", + "type": "Pointer" + }, + { + "name": "pixelDataLength", + "type": "number" + }, + { + "name": "format", + "type": "\"bgra8unorm\" | \"rgba8unorm\"" + }, + { + "name": "alignedBytesPerRow", + "type": "number" + } + ] + }, + { + "name": "drawPackedBuffer", + "returnType": "void", + "parameters": [ + { + "name": "dataPtr", + "type": "Pointer" + }, + { + "name": "dataLen", + "type": "number" + }, + { + "name": "posX", + "type": "number" + }, + { + "name": "posY", + "type": "number" + }, + { + "name": "terminalWidthCells", + "type": "number" + }, + { + "name": "terminalHeightCells", + "type": "number" + } + ] + }, + { + "name": "setCellWithAlphaBlendingFFI", + "returnType": "void", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "char", + "type": "string" + }, + { + "name": "fg", + "type": "RGBA" + }, + { + "name": "bg", + "type": "RGBA" + }, + { + "name": "attributes", + "type": "number" + } + ] + }, + { + "name": "fillRectFFI", + "returnType": "void", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "width", + "type": "number" + }, + { + "name": "height", + "type": "number" + }, + { + "name": "bg", + "type": "RGBA" + } + ] + }, + { + "name": "resize", + "returnType": "void", + "parameters": [ + { + "name": "width", + "type": "number" + }, + { + "name": "height", + "type": "number" + } + ] + }, + { + "name": "clearFFI", + "returnType": "void", + "parameters": [ + { + "name": "bg", + "type": "RGBA" + } + ] + }, + { + "name": "drawTextFFI", + "returnType": "void", + "parameters": [ + { + "name": "text", + "type": "string" + }, + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + }, + { + "name": "fg", + "type": "RGBA" + }, + { + "name": "bg", + "type": "RGBA" + }, + { + "name": "attributes", + "type": "number" + } + ] + }, + { + "name": "drawFrameBufferFFI", + "returnType": "void", + "parameters": [ + { + "name": "destX", + "type": "number" + }, + { + "name": "destY", + "type": "number" + }, + { + "name": "frameBuffer", + "type": "OptimizedBuffer" + }, + { + "name": "sourceX", + "type": "number" + }, + { + "name": "sourceY", + "type": "number" + }, + { + "name": "sourceWidth", + "type": "number" + }, + { + "name": "sourceHeight", + "type": "number" + } + ] + }, + { + "name": "drawBox", + "returnType": "void", + "parameters": [ + { + "name": "options", + "type": "{\n x: number\n y: number\n width: number\n height: number\n borderStyle?: BorderStyle\n customBorderChars?: Uint32Array\n border: boolean | BorderSides[]\n borderColor: RGBA\n backgroundColor: RGBA\n shouldFill?: boolean\n title?: string\n titleAlignment?: \"left\" | \"center\" | \"right\"\n }" + } + ] + } + ], + "properties": [ + { + "name": "id", + "type": "string" + }, + { + "name": "lib", + "type": "RenderLib" + }, + { + "name": "respectAlpha", + "type": "boolean" + } + ], + "constructor": { + "parameters": [ + { + "name": "lib", + "type": "RenderLib" + }, + { + "name": "ptr", + "type": "Pointer" + }, + { + "name": "buffer", + "type": "{\n char: Uint32Array\n fg: Float32Array\n bg: Float32Array\n attributes: Uint8Array\n }" + }, + { + "name": "width", + "type": "number" + }, + { + "name": "height", + "type": "number" + }, + { + "name": "options", + "type": "{ respectAlpha?: boolean }" + } + ] + } + }, + { + "name": "BoxRenderable", + "methods": [], + "properties": [ + { + "name": "shouldFill", + "type": "boolean" + } + ], + "constructor": { + "parameters": [ + { + "name": "id", + "type": "string" + }, + { + "name": "options", + "type": "BoxOptions" + } + ] + } + }, + { + "name": "TextRenderable", + "methods": [ + { + "name": "shouldStartSelection", + "returnType": "boolean", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + } + ] + }, + { + "name": "onSelectionChanged", + "returnType": "boolean", + "parameters": [ + { + "name": "selection", + "type": "SelectionState | null" + } + ] + }, + { + "name": "getSelectedText", + "returnType": "string", + "parameters": [] + }, + { + "name": "hasSelection", + "returnType": "boolean", + "parameters": [] + }, + { + "name": "destroy", + "returnType": "void", + "parameters": [] + } + ], + "properties": [ + { + "name": "selectable", + "type": "boolean" + } + ], + "constructor": { + "parameters": [ + { + "name": "id", + "type": "string" + }, + { + "name": "options", + "type": "TextOptions" + } + ] + } + }, + { + "name": "ASCIIFontRenderable", + "methods": [ + { + "name": "shouldStartSelection", + "returnType": "boolean", + "parameters": [ + { + "name": "x", + "type": "number" + }, + { + "name": "y", + "type": "number" + } + ] + }, + { + "name": "onSelectionChanged", + "returnType": "boolean", + "parameters": [ + { + "name": "selection", + "type": "SelectionState | null" + } + ] + }, + { + "name": "getSelectedText", + "returnType": "string", + "parameters": [] + }, + { + "name": "hasSelection", + "returnType": "boolean", + "parameters": [] + } + ], + "properties": [ + { + "name": "selectable", + "type": "boolean" + } + ], + "constructor": { + "parameters": [ + { + "name": "id", + "type": "string" + }, + { + "name": "options", + "type": "ASCIIFontOptions" + } + ] + } + }, + { + "name": "InputRenderable", + "methods": [ + { + "name": "focus", + "returnType": "void", + "parameters": [] + }, + { + "name": "blur", + "returnType": "void", + "parameters": [] + }, + { + "name": "handleKeyPress", + "returnType": "boolean", + "parameters": [ + { + "name": "key", + "type": "ParsedKey | string" + } + ] + } + ], + "properties": [], + "constructor": { + "parameters": [ + { + "name": "id", + "type": "string" + }, + { + "name": "options", + "type": "InputRenderableOptions" + } + ] + } + }, + { + "name": "Timeline", + "methods": [ + { + "name": "add", + "returnType": "this", + "parameters": [ + { + "name": "target", + "type": "any" + }, + { + "name": "properties", + "type": "AnimationOptions" + }, + { + "name": "startTime", + "type": "number | string" + } + ] + }, + { + "name": "once", + "returnType": "this", + "parameters": [ + { + "name": "target", + "type": "any" + }, + { + "name": "properties", + "type": "AnimationOptions" + } + ] + }, + { + "name": "call", + "returnType": "this", + "parameters": [ + { + "name": "callback", + "type": "() => void" + }, + { + "name": "startTime", + "type": "number | string" + } + ] + }, + { + "name": "sync", + "returnType": "this", + "parameters": [ + { + "name": "timeline", + "type": "Timeline" + }, + { + "name": "startTime", + "type": "number" + } + ] + }, + { + "name": "play", + "returnType": "this", + "parameters": [] + }, + { + "name": "pause", + "returnType": "this", + "parameters": [] + }, + { + "name": "resetItems", + "returnType": "void", + "parameters": [] + }, + { + "name": "restart", + "returnType": "this", + "parameters": [] + }, + { + "name": "update", + "returnType": "void", + "parameters": [ + { + "name": "deltaTime", + "type": "number" + } + ] + } + ], + "properties": [ + { + "name": "items", + "type": "(TimelineAnimationItem | TimelineCallbackItem)[]" + }, + { + "name": "subTimelines", + "type": "TimelineTimelineItem[]" + }, + { + "name": "currentTime", + "type": "number" + }, + { + "name": "isPlaying", + "type": "boolean" + }, + { + "name": "isComplete", + "type": "boolean" + }, + { + "name": "duration", + "type": "number" + }, + { + "name": "loop", + "type": "boolean" + }, + { + "name": "synced", + "type": "boolean" + } + ], + "constructor": { + "parameters": [ + { + "name": "options", + "type": "TimelineOptions" + } + ] + } + } + ], + "interfaces": [ + { + "name": "RootContext", + "members": [ + { + "name": "requestLive", + "type": "void" + }, + { + "name": "dropLive", + "type": "void" + } + ] + }, + { + "name": "Position", + "members": [ + { + "name": "top", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "right", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "bottom", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "left", + "type": "number | \"auto\" | `${number}%`" + } + ] + }, + { + "name": "LayoutOptions", + "members": [ + { + "name": "flexGrow", + "type": "number" + }, + { + "name": "flexShrink", + "type": "number" + }, + { + "name": "flexDirection", + "type": "FlexDirectionString" + }, + { + "name": "alignItems", + "type": "AlignString" + }, + { + "name": "justifyContent", + "type": "JustifyString" + }, + { + "name": "flexBasis", + "type": "number | \"auto\" | undefined" + }, + { + "name": "position", + "type": "PositionTypeString" + }, + { + "name": "top", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "right", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "bottom", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "left", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "minWidth", + "type": "number" + }, + { + "name": "minHeight", + "type": "number" + }, + { + "name": "maxWidth", + "type": "number" + }, + { + "name": "maxHeight", + "type": "number" + }, + { + "name": "margin", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "marginTop", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "marginRight", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "marginBottom", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "marginLeft", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "padding", + "type": "number | `${number}%`" + }, + { + "name": "paddingTop", + "type": "number | `${number}%`" + }, + { + "name": "paddingRight", + "type": "number | `${number}%`" + }, + { + "name": "paddingBottom", + "type": "number | `${number}%`" + }, + { + "name": "paddingLeft", + "type": "number | `${number}%`" + }, + { + "name": "enableLayout", + "type": "boolean" + } + ] + }, + { + "name": "RenderableOptions", + "members": [ + { + "name": "width", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "height", + "type": "number | \"auto\" | `${number}%`" + }, + { + "name": "zIndex", + "type": "number" + }, + { + "name": "visible", + "type": "boolean" + }, + { + "name": "buffered", + "type": "boolean" + }, + { + "name": "live", + "type": "boolean" + }, + { + "name": "onMouseDown", + "type": "(event: MouseEvent) => void" + }, + { + "name": "onMouseUp", + "type": "(event: MouseEvent) => void" + }, + { + "name": "onMouseMove", + "type": "(event: MouseEvent) => void" + }, + { + "name": "onMouseDrag", + "type": "(event: MouseEvent) => void" + }, + { + "name": "onMouseDragEnd", + "type": "(event: MouseEvent) => void" + }, + { + "name": "onMouseDrop", + "type": "(event: MouseEvent) => void" + }, + { + "name": "onMouseOver", + "type": "(event: MouseEvent) => void" + }, + { + "name": "onMouseOut", + "type": "(event: MouseEvent) => void" + }, + { + "name": "onMouseScroll", + "type": "(event: MouseEvent) => void" + }, + { + "name": "onKeyDown", + "type": "(key: ParsedKey) => void" + } + ] + }, + { + "name": "CliRendererConfig", + "members": [ + { + "name": "stdin", + "type": "NodeJS.ReadStream" + }, + { + "name": "stdout", + "type": "NodeJS.WriteStream" + }, + { + "name": "exitOnCtrlC", + "type": "boolean" + }, + { + "name": "debounceDelay", + "type": "number" + }, + { + "name": "targetFps", + "type": "number" + }, + { + "name": "memorySnapshotInterval", + "type": "number" + }, + { + "name": "useThread", + "type": "boolean" + }, + { + "name": "gatherStats", + "type": "boolean" + }, + { + "name": "maxStatSamples", + "type": "number" + }, + { + "name": "consoleOptions", + "type": "ConsoleOptions" + }, + { + "name": "postProcessFns", + "type": "((buffer: OptimizedBuffer, deltaTime: number) => void)[]" + }, + { + "name": "enableMouseMovement", + "type": "boolean" + }, + { + "name": "useMouse", + "type": "boolean" + }, + { + "name": "useAlternateScreen", + "type": "boolean" + }, + { + "name": "useConsole", + "type": "boolean" + }, + { + "name": "experimental_splitHeight", + "type": "number" + } + ] + }, + { + "name": "BoxOptions", + "members": [ + { + "name": "backgroundColor", + "type": "string | RGBA" + }, + { + "name": "borderStyle", + "type": "BorderStyle" + }, + { + "name": "border", + "type": "boolean | BorderSides[]" + }, + { + "name": "borderColor", + "type": "string | RGBA" + }, + { + "name": "customBorderChars", + "type": "BorderCharacters" + }, + { + "name": "shouldFill", + "type": "boolean" + }, + { + "name": "title", + "type": "string" + }, + { + "name": "titleAlignment", + "type": "\"left\" | \"center\" | \"right\"" + }, + { + "name": "focusedBorderColor", + "type": "ColorInput" + } + ] + }, + { + "name": "TextOptions", + "members": [ + { + "name": "content", + "type": "StyledText | string" + }, + { + "name": "fg", + "type": "string | RGBA" + }, + { + "name": "bg", + "type": "string | RGBA" + }, + { + "name": "selectionBg", + "type": "string | RGBA" + }, + { + "name": "selectionFg", + "type": "string | RGBA" + }, + { + "name": "selectable", + "type": "boolean" + }, + { + "name": "attributes", + "type": "number" + } + ] + }, + { + "name": "ASCIIFontOptions", + "members": [ + { + "name": "text", + "type": "string" + }, + { + "name": "font", + "type": "\"tiny\" | \"block\" | \"shade\" | \"slick\"" + }, + { + "name": "fg", + "type": "RGBA | RGBA[]" + }, + { + "name": "bg", + "type": "RGBA" + }, + { + "name": "selectionBg", + "type": "string | RGBA" + }, + { + "name": "selectionFg", + "type": "string | RGBA" + }, + { + "name": "selectable", + "type": "boolean" + } + ] + }, + { + "name": "InputRenderableOptions", + "members": [ + { + "name": "backgroundColor", + "type": "ColorInput" + }, + { + "name": "textColor", + "type": "ColorInput" + }, + { + "name": "focusedBackgroundColor", + "type": "ColorInput" + }, + { + "name": "focusedTextColor", + "type": "ColorInput" + }, + { + "name": "placeholder", + "type": "string" + }, + { + "name": "placeholderColor", + "type": "ColorInput" + }, + { + "name": "cursorColor", + "type": "ColorInput" + }, + { + "name": "maxLength", + "type": "number" + }, + { + "name": "value", + "type": "string" + } + ] + }, + { + "name": "TimelineOptions", + "members": [ + { + "name": "duration", + "type": "number" + }, + { + "name": "loop", + "type": "boolean" + }, + { + "name": "autoplay", + "type": "boolean" + }, + { + "name": "onComplete", + "type": "() => void" + }, + { + "name": "onPause", + "type": "() => void" + } + ] + }, + { + "name": "AnimationOptions", + "members": [ + { + "name": "duration", + "type": "number" + }, + { + "name": "ease", + "type": "EasingFunctions" + }, + { + "name": "onUpdate", + "type": "(animation: JSAnimation) => void" + }, + { + "name": "onComplete", + "type": "() => void" + }, + { + "name": "onStart", + "type": "() => void" + }, + { + "name": "onLoop", + "type": "() => void" + }, + { + "name": "loop", + "type": "boolean | number" + }, + { + "name": "loopDelay", + "type": "number" + }, + { + "name": "alternate", + "type": "boolean" + }, + { + "name": "once", + "type": "boolean" + }, + { + "name": "", + "type": "any" + } + ] + }, + { + "name": "JSAnimation", + "members": [ + { + "name": "targets", + "type": "any[]" + }, + { + "name": "deltaTime", + "type": "number" + }, + { + "name": "progress", + "type": "number" + }, + { + "name": "currentTime", + "type": "number" + } + ] + } + ], + "functions": [ + { + "name": "isMarginType", + "parameters": [ + { + "name": "value", + "type": "any" + } + ], + "returnType": "value is number | \"auto\" | `${number}%`" + }, + { + "name": "isPaddingType", + "parameters": [ + { + "name": "value", + "type": "any" + } + ], + "returnType": "value is number | `${number}%`" + }, + { + "name": "isPositionType", + "parameters": [ + { + "name": "value", + "type": "any" + } + ], + "returnType": "value is number | \"auto\" | `${number}%`" + }, + { + "name": "isPostionTypeType", + "parameters": [ + { + "name": "value", + "type": "any" + } + ], + "returnType": "value is PositionTypeString" + }, + { + "name": "isDimensionType", + "parameters": [ + { + "name": "value", + "type": "any" + } + ], + "returnType": "value is number | \"auto\" | `${number}%`" + }, + { + "name": "isFlexBasisType", + "parameters": [ + { + "name": "value", + "type": "any" + } + ], + "returnType": "value is number | \"auto\" | undefined" + }, + { + "name": "isSizeType", + "parameters": [ + { + "name": "value", + "type": "any" + } + ], + "returnType": "value is number | `${number}%` | undefined" + }, + { + "name": "createCliRenderer", + "parameters": [ + { + "name": "config", + "type": "CliRendererConfig" + } + ], + "returnType": "Promise" + }, + { + "name": "createTimeline", + "parameters": [ + { + "name": "options", + "type": "TimelineOptions" + } + ], + "returnType": "Timeline" + } + ], + "enums": [], + "types": [] +} \ No newline at end of file diff --git a/packages/core/docs/api/index.md b/packages/core/docs/api/index.md new file mode 100644 index 00000000..027818b1 --- /dev/null +++ b/packages/core/docs/api/index.md @@ -0,0 +1,145 @@ +# OpenTUI API Documentation + +OpenTUI is a modern terminal UI framework that brings React-like component architecture to the terminal. + +## Quick Links + +### Module Documentation +Learn how to use OpenTUI with practical guides and examples: + +- [Getting Started](../modules/guide.md) - Installation and basic usage +- [Components](../modules/components.md) - Built-in UI components +- [Layout System](../modules/layout.md) - Flexbox layout in the terminal +- [Event Handling](../modules/events.md) - Mouse and keyboard input +- [Animation](../modules/animation.md) - Smooth animations and transitions +- [Rendering](../modules/rendering.md) - Rendering pipeline and optimization + +### API Reference + +#### Core Classes +- [CliRenderer](./reference/classes/CliRenderer.md) - Main renderer managing the terminal +- [Renderable](./reference/classes/Renderable.md) - Base class for all components +- [OptimizedBuffer](./reference/classes/OptimizedBuffer.md) - High-performance rendering buffer + +#### Components +- [BoxRenderable](./reference/classes/BoxRenderable.md) - Container component with borders +- [TextRenderable](./reference/classes/TextRenderable.md) - Text display with styling +- [InputRenderable](./reference/classes/InputRenderable.md) - Text input field +- [ASCIIFontRenderable](./reference/classes/ASCIIFontRenderable.md) - ASCII art text + +#### Events +- [MouseEvent](./reference/classes/MouseEvent.md) - Mouse interaction handling +- [MouseEventType](./reference/types/MouseEventType.md) - Types of mouse events + +#### Animation +- [Timeline](./reference/classes/Timeline.md) - Animation timeline system + +#### Configuration Interfaces +- [BoxOptions](./reference/interfaces/BoxOptions.md) - Box component configuration +- [TextOptions](./reference/interfaces/TextOptions.md) - Text component configuration +- [InputRenderableOptions](./reference/interfaces/InputRenderableOptions.md) - Input field configuration +- [ASCIIFontOptions](./reference/interfaces/ASCIIFontOptions.md) - ASCII font configuration +- [CliRendererConfig](./reference/interfaces/CliRendererConfig.md) - Renderer configuration + +#### Type Definitions +- [BorderStyle](./reference/types/BorderStyle.md) - Available border styles +- [MouseEventType](./reference/types/MouseEventType.md) - Mouse event types + +## Quick Start Example + +```typescript +import { CliRenderer, BoxRenderable, TextRenderable } from '@opentui/core'; +import { RGBA } from '@opentui/core'; + +// Create the renderer +const renderer = new CliRenderer(lib, ptr, stdin, stdout, 80, 24, { + backgroundColor: '#1e1e1e' +}); + +// Create a main container +const mainBox = new BoxRenderable('main', { + width: '100%', + height: '100%', + border: true, + borderStyle: 'rounded', + title: 'My App', + padding: 1 +}); + +// Add some text +const text = new TextRenderable('greeting', { + text: 'Welcome to OpenTUI!', + color: RGBA.fromHex('#00ff00'), + align: 'center' +}); + +// Build the UI tree +mainBox.add(text, 0); +renderer.root.add(mainBox, 0); + +// Start rendering +renderer.start(); +``` + +## Framework Integrations + +OpenTUI provides React and Solid.js bindings for declarative UI development: + +### React +```tsx +import { render, Box, Text } from '@opentui/react'; + +function App() { + return ( + + Hello from React! + + ); +} + +render(); +``` + +### Solid.js +```tsx +import { render, Box, Text } from '@opentui/solid'; + +function App() { + return ( + + Hello from Solid! + + ); +} + +render(() => ); +``` + +## Features + +- šŸŽØ **Rich Styling** - Colors, borders, backgrounds, and ASCII fonts +- šŸ“ **Flexbox Layout** - Powered by Yoga layout engine +- šŸ–±ļø **Mouse Support** - Full mouse interaction including drag & drop +- āŒØļø **Keyboard Input** - Comprehensive keyboard handling +- šŸŽ¬ **Animations** - Smooth transitions and effects +- ⚔ **Performance** - Optimized double-buffered rendering +- šŸ”§ **Framework Support** - React and Solid.js bindings +- šŸŽÆ **TypeScript** - Full type safety and IntelliSense + +## Architecture + +OpenTUI uses a component-based architecture similar to web frameworks: + +1. **Components** inherit from `Renderable` base class +2. **Layout** calculated using Yoga flexbox engine +3. **Rendering** uses double-buffered `OptimizedBuffer` +4. **Events** bubble up through component tree +5. **Animations** managed by `Timeline` system + +## Contributing + +See [CONTRIBUTING.md](https://github.com/sst/opentui/blob/main/CONTRIBUTING.md) for development setup and guidelines. + +## License + +MIT - See [LICENSE](https://github.com/sst/opentui/blob/main/LICENSE) diff --git a/packages/core/docs/api/reference/README.md b/packages/core/docs/api/reference/README.md new file mode 100644 index 00000000..f8dac632 --- /dev/null +++ b/packages/core/docs/api/reference/README.md @@ -0,0 +1,10 @@ +# API Reference + +This directory contains the complete API reference for OpenTUI, automatically generated from the source code. + +## Structure + +- **[index.md](./index.md)** - Main index of all API components +- **classes/** - Documentation for all classes +- **interfaces/** - Documentation for all interfaces +- **types/** - Documentation for type definitions diff --git a/packages/core/docs/api/reference/classes/ASCIIFontRenderable.md b/packages/core/docs/api/reference/classes/ASCIIFontRenderable.md new file mode 100644 index 00000000..afa183b4 --- /dev/null +++ b/packages/core/docs/api/reference/classes/ASCIIFontRenderable.md @@ -0,0 +1,265 @@ +# ASCIIFontRenderable + +Renders text using ASCII art fonts for decorative headers and titles. Supports both built-in and custom font definitions. + +## Constructor + +```typescript +new ASCIIFontRenderable(id: string, options: ASCIIFontOptions) +``` + +### Parameters + +#### id + +Type: `string` + +Unique identifier for this ASCII font component + +#### options + +Type: `ASCIIFontOptions` + +Configuration options for ASCII font rendering. Key properties include: + +| Property | Type | Description | +|----------|------|-------------| +| `text` | `string` | Text to render in ASCII art | +| `font` | `string \| FontDefinition` | Font name or custom font definition | +| `color` | `string \| RGBA` | Text color | +| `backgroundColor` | `string \| RGBA` | Background color | +| `align` | `'left' \| 'center' \| 'right'` | Text alignment | +| `letterSpacing` | `number` | Extra space between characters | +| `lineHeight` | `number` | Multiplier for line spacing | + +## Properties + +### text + +Type: `string` + +Current text being displayed + +### font + +Type: `string | FontDefinition` + +Active font for rendering + +### height + +Type: `number` + +Calculated height of the ASCII art text + +## Methods + +### setText() + +Update the displayed text + +#### Signature + +```typescript +setText(text: string): void +``` + +#### Parameters + +- **text**: `string` - New text to render + +### setFont() + +Change the font + +#### Signature + +```typescript +setFont(font: string | FontDefinition): void +``` + +#### Parameters + +- **font**: `string | FontDefinition` - Font name or custom definition + +### registerFont() + +Register a custom font for use + +#### Signature + +```typescript +static registerFont(name: string, definition: FontDefinition): void +``` + +#### Parameters + +- **name**: `string` - Name to register the font under +- **definition**: `FontDefinition` - Font character definitions + +## Built-in Fonts + +OpenTUI includes several built-in ASCII fonts: + +### default +Standard block letters, clean and readable + +### bulky +Bold, heavy characters for emphasis + +### chrome +Metallic-style letters with shine effects + +### huge +Extra large letters for maximum impact + +## Examples + +### Basic ASCII Title + +```typescript +const title = new ASCIIFontRenderable('title', { + text: 'WELCOME', + font: 'default', + color: '#00ff00', + align: 'center' +}); +``` + +### Styled Banner + +```typescript +const banner = new ASCIIFontRenderable('banner', { + text: 'GAME OVER', + font: 'huge', + color: '#ff0000', + backgroundColor: '#000000', + align: 'center', + letterSpacing: 1 +}); +``` + +### Custom Font Definition + +```typescript +const customFont: FontDefinition = { + height: 5, + chars: { + 'A': [ + ' ā–ˆ ', + ' ā–ˆ ā–ˆ ', + 'ā–ˆā–ˆā–ˆā–ˆā–ˆ', + 'ā–ˆ ā–ˆ', + 'ā–ˆ ā–ˆ' + ], + 'B': [ + 'ā–ˆā–ˆā–ˆā–ˆ ', + 'ā–ˆ ā–ˆ', + 'ā–ˆā–ˆā–ˆā–ˆ ', + 'ā–ˆ ā–ˆ', + 'ā–ˆā–ˆā–ˆā–ˆ ' + ] + // ... more characters + } +}; + +const customText = new ASCIIFontRenderable('custom', { + text: 'AB', + font: customFont, + color: '#ffffff' +}); +``` + +### Registering Custom Fonts + +```typescript +// Register a custom font globally +ASCIIFontRenderable.registerFont('pixel', { + height: 3, + chars: { + 'A': ['ā–ˆā–€ā–ˆ', 'ā–ˆā–ˆā–ˆ', 'ā–€ ā–€'], + 'B': ['ā–ˆā–ˆā–„', 'ā–ˆā–ˆā–„', 'ā–ˆā–ˆā–€'], + 'C': ['ā–„ā–ˆā–ˆ', 'ā–ˆ ', 'ā–€ā–ˆā–ˆ'], + // ... more characters + } +}); + +// Use the registered font +const pixelText = new ASCIIFontRenderable('pixel-text', { + text: 'ABC', + font: 'pixel', + color: '#00ffff' +}); +``` + +### Animated ASCII Text + +```typescript +const animatedTitle = new ASCIIFontRenderable('animated', { + text: 'LOADING', + font: 'chrome', + color: '#ffffff' +}); + +// Animate color +let hue = 0; +setInterval(() => { + hue = (hue + 10) % 360; + animatedTitle.setColor(RGBA.fromHSL(hue, 100, 50)); + animatedTitle.needsUpdate(); +}, 100); + +// Animate text +const frames = ['LOADING', 'LOADING.', 'LOADING..', 'LOADING...']; +let frame = 0; +setInterval(() => { + animatedTitle.setText(frames[frame]); + frame = (frame + 1) % frames.length; +}, 500); +``` + +## Font Definition Structure + +```typescript +interface FontDefinition { + height: number; // Height of each character in lines + chars: { + [char: string]: string[]; // Array of strings, one per line + }; + kerning?: { + [pair: string]: number; // Spacing adjustment for character pairs + }; +} +``` + +### Creating Font Definitions + +1. Each character is an array of strings +2. All strings must have the same width +3. The array length must match the font height +4. Use Unicode box-drawing characters for best results + +```typescript +const miniFont: FontDefinition = { + height: 3, + chars: { + 'H': [ + 'ā–ˆ ā–ˆ', + 'ā–ˆā–ˆā–ˆ', + 'ā–ˆ ā–ˆ' + ], + 'I': [ + 'ā–ˆā–ˆā–ˆ', + ' ā–ˆ ', + 'ā–ˆā–ˆā–ˆ' + ] + } +}; +``` + +## See Also + +- [ASCIIFontOptions](../interfaces/ASCIIFontOptions.md) - Configuration options +- [FontDefinition](../interfaces/FontDefinition.md) - Custom font structure +- [TextRenderable](./TextRenderable.md) - Standard text component +- [Renderable](./Renderable.md) - Base component class \ No newline at end of file diff --git a/packages/core/docs/api/reference/classes/BoxRenderable.md b/packages/core/docs/api/reference/classes/BoxRenderable.md new file mode 100644 index 00000000..9a5fe606 --- /dev/null +++ b/packages/core/docs/api/reference/classes/BoxRenderable.md @@ -0,0 +1,344 @@ +# BoxRenderable + +Container component that provides borders, padding, and flexbox layout. The most fundamental building block for OpenTUI interfaces, similar to a `div` element in HTML. + +## Constructor + +```typescript +new BoxRenderable(id: string, options: BoxOptions) +``` + +### Parameters + +#### id + +Type: `string` + +Unique identifier for this box component + +#### options + +Type: `BoxOptions` + +Configuration options for the box. See [BoxOptions](../interfaces/BoxOptions.md) for full details. + +## Properties + +### border + +Type: `boolean | [boolean, boolean, boolean, boolean]` + +Border configuration - either all sides or [top, right, bottom, left] + +### borderStyle + +Type: `BorderStyle` + +Style of border characters ('single', 'double', 'rounded', 'heavy') + +### title + +Type: `string` + +Optional title displayed in the top border + +### padding + +Type: `number | { top: number, right: number, bottom: number, left: number }` + +Internal spacing between border and content + +### children + +Type: `Renderable[]` + +Child components contained within this box + +## Methods + +### setBorderStyle() + +Change the border style + +#### Signature + +```typescript +setBorderStyle(style: BorderStyle): void +``` + +#### Parameters + +- **style**: `BorderStyle` - New border style to apply + +### setTitle() + +Update the box title + +#### Signature + +```typescript +setTitle(title: string): void +``` + +#### Parameters + +- **title**: `string` - New title text + +### setPadding() + +Adjust internal padding + +#### Signature + +```typescript +setPadding(padding: number | { top: number, right: number, bottom: number, left: number }): void +``` + +#### Parameters + +- **padding**: `number | object` - Uniform padding or individual sides + +### showBorder() + +Show or hide the border + +#### Signature + +```typescript +showBorder(show: boolean): void +``` + +#### Parameters + +- **show**: `boolean` - Whether to display the border + +## Layout Properties + +BoxRenderable supports flexbox layout for arranging child components: + +### flexDirection +- `'row'` - Horizontal layout (default) +- `'column'` - Vertical layout +- `'row-reverse'` - Horizontal, reversed +- `'column-reverse'` - Vertical, reversed + +### justifyContent +- `'flex-start'` - Align to start +- `'flex-end'` - Align to end +- `'center'` - Center items +- `'space-between'` - Space between items +- `'space-around'` - Space around items +- `'space-evenly'` - Even spacing + +### alignItems +- `'flex-start'` - Align to cross-axis start +- `'flex-end'` - Align to cross-axis end +- `'center'` - Center on cross-axis +- `'stretch'` - Stretch to fill +- `'baseline'` - Align text baselines + +## Examples + +### Basic Container + +```typescript +const container = new BoxRenderable('container', { + width: 50, + height: 10, + border: true, + borderStyle: 'single' +}); +``` + +### Titled Panel + +```typescript +const panel = new BoxRenderable('panel', { + width: '100%', + height: 20, + border: true, + borderStyle: 'double', + title: 'āš™ Settings', + titleAlignment: 'center', + padding: 2, + backgroundColor: '#1e1e1e' +}); +``` + +### Flexbox Layout + +```typescript +const layout = new BoxRenderable('layout', { + width: '100%', + height: '100%', + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + padding: 1 +}); + +// Add child components +const sidebar = new BoxRenderable('sidebar', { + width: 20, + height: '100%', + border: true, + borderStyle: 'single' +}); + +const content = new BoxRenderable('content', { + flexGrow: 1, + height: '100%', + border: true, + borderStyle: 'single', + margin: { left: 1 } +}); + +layout.add(sidebar, 0); +layout.add(content, 1); +``` + +### Nested Boxes + +```typescript +const outer = new BoxRenderable('outer', { + width: 60, + height: 30, + border: true, + borderStyle: 'heavy', + borderColor: '#ff0000', + padding: 2 +}); + +const inner = new BoxRenderable('inner', { + width: '100%', + height: '100%', + border: true, + borderStyle: 'rounded', + borderColor: '#00ff00', + backgroundColor: '#002200', + padding: 1 +}); + +outer.add(inner, 0); +``` + +### Custom Border Characters + +```typescript +const customBox = new BoxRenderable('custom', { + width: 40, + height: 10, + border: true, + customBorderChars: { + topLeft: 'ā•”', + topRight: 'ā•—', + bottomLeft: 'ā•š', + bottomRight: 'ā•', + horizontal: '═', + vertical: 'ā•‘', + topT: '╦', + bottomT: 'ā•©', + leftT: 'ā• ', + rightT: 'ā•£', + cross: '╬' + } +}); +``` + +### Interactive Box + +```typescript +const interactive = new BoxRenderable('interactive', { + width: 30, + height: 10, + border: true, + borderColor: '#808080', + focusedBorderColor: '#00ff00', + backgroundColor: '#1e1e1e', + padding: 1, + + onMouseDown: (event) => { + console.log('Box clicked at:', event.x, event.y); + }, + + onMouseOver: (event) => { + interactive.setBorderColor('#ffff00'); + interactive.needsUpdate(); + }, + + onMouseOut: (event) => { + interactive.setBorderColor('#808080'); + interactive.needsUpdate(); + }, + + onKeyDown: (key) => { + if (key.name === 'space') { + // Handle spacebar + } + } +}); + +// Make it focusable +interactive.focus(); +``` + +### Responsive Grid + +```typescript +class GridLayout extends BoxRenderable { + constructor() { + super('grid', { + width: '100%', + height: '100%', + flexDirection: 'column' + }); + + // Create rows + for (let row = 0; row < 3; row++) { + const rowBox = new BoxRenderable(`row-${row}`, { + width: '100%', + flexGrow: 1, + flexDirection: 'row' + }); + + // Create columns in each row + for (let col = 0; col < 3; col++) { + const cell = new BoxRenderable(`cell-${row}-${col}`, { + flexGrow: 1, + height: '100%', + border: true, + borderStyle: 'single', + padding: 1, + margin: 0.5 + }); + + rowBox.add(cell, col); + } + + this.add(rowBox, row); + } + } +} +``` + +## Styling Priority + +When multiple style properties conflict, they are applied in this order: +1. Inline styles (set via methods) +2. Focus styles (when component has focus) +3. Hover styles (when mouse is over) +4. Default styles (from options) + +## Performance Tips + +1. Use `buffered: true` for boxes that update frequently +2. Minimize deeply nested boxes for better rendering performance +3. Use percentage-based sizing for responsive layouts +4. Enable `shouldFill: false` if the box doesn't need to clear its background + +## See Also + +- [BoxOptions](../interfaces/BoxOptions.md) - Configuration options +- [BorderStyle](../types/BorderStyle.md) - Border style types +- [Renderable](./Renderable.md) - Base component class +- [TextRenderable](./TextRenderable.md) - Text content component \ No newline at end of file diff --git a/packages/core/docs/api/reference/classes/CliRenderer.md b/packages/core/docs/api/reference/classes/CliRenderer.md new file mode 100644 index 00000000..bd173084 --- /dev/null +++ b/packages/core/docs/api/reference/classes/CliRenderer.md @@ -0,0 +1,486 @@ +# CliRenderer + +Main renderer class that manages the terminal output, input handling, and render loop. + +## Constructor + +```typescript +new CliRenderer(lib: RenderLib, rendererPtr: Pointer, stdin: NodeJS.ReadStream, stdout: NodeJS.WriteStream, width: number, height: number, config: CliRendererConfig) +``` + +### Parameters + +#### lib + +Type: `RenderLib` + +#### rendererPtr + +Type: `Pointer` + +#### stdin + +Type: `NodeJS.ReadStream` + +#### stdout + +Type: `NodeJS.WriteStream` + +#### width + +Type: `number` + +#### height + +Type: `number` + +#### config + +Type: `CliRendererConfig` + +## Properties + +### rendererPtr + +Type: `Pointer` + +### nextRenderBuffer + +Type: `OptimizedBuffer` + +Buffer being prepared for next frame + +### currentRenderBuffer + +Type: `OptimizedBuffer` + +Currently displayed buffer + +### root + +Type: `RootRenderable` + +Root renderable that contains all UI components + +### width + +Type: `number` + +Current terminal width in characters + +### height + +Type: `number` + +Current terminal height in characters + +### debugOverlay + +Type: `any` + +Debug information overlay component + +## Methods + +### needsUpdate() + +Mark the renderer as needing to re-render + +#### Signature + +```typescript +needsUpdate(): void +``` + +### setMemorySnapshotInterval() + +#### Signature + +```typescript +setMemorySnapshotInterval(interval: number): void +``` + +#### Parameters + +- **interval**: `number` + +### setBackgroundColor() + +Set the default background color + +#### Signature + +```typescript +setBackgroundColor(color: ColorInput): void +``` + +#### Parameters + +- **color**: `ColorInput` + +### toggleDebugOverlay() + +Toggle debug information display + +#### Signature + +```typescript +toggleDebugOverlay(): void +``` + +### configureDebugOverlay() + +#### Signature + +```typescript +configureDebugOverlay(options: { enabled?: boolean; corner?: DebugOverlayCorner }): void +``` + +#### Parameters + +- **options**: `{ enabled?: boolean; corner?: DebugOverlayCorner }` + +### clearTerminal() + +#### Signature + +```typescript +clearTerminal(): void +``` + +### dumpHitGrid() + +#### Signature + +```typescript +dumpHitGrid(): void +``` + +### dumpBuffers() + +#### Signature + +```typescript +dumpBuffers(timestamp: number): void +``` + +#### Parameters + +- **timestamp**: `number` + +### dumpStdoutBuffer() + +#### Signature + +```typescript +dumpStdoutBuffer(timestamp: number): void +``` + +#### Parameters + +- **timestamp**: `number` + +### setCursorPosition() + +#### Signature + +```typescript +setCursorPosition(x: number, y: number, visible: boolean): void +``` + +#### Parameters + +- **x**: `number` +- **y**: `number` +- **visible**: `boolean` + +### setCursorStyle() + +#### Signature + +```typescript +setCursorStyle(style: CursorStyle, blinking: boolean, color: RGBA): void +``` + +#### Parameters + +- **style**: `CursorStyle` +- **blinking**: `boolean` +- **color**: `RGBA` + +### setCursorColor() + +#### Signature + +```typescript +setCursorColor(color: RGBA): void +``` + +#### Parameters + +- **color**: `RGBA` + +### setCursorPosition() + +#### Signature + +```typescript +setCursorPosition(x: number, y: number, visible: boolean): void +``` + +#### Parameters + +- **x**: `number` +- **y**: `number` +- **visible**: `boolean` + +### setCursorStyle() + +#### Signature + +```typescript +setCursorStyle(style: CursorStyle, blinking: boolean, color: RGBA): void +``` + +#### Parameters + +- **style**: `CursorStyle` +- **blinking**: `boolean` +- **color**: `RGBA` + +### setCursorColor() + +#### Signature + +```typescript +setCursorColor(color: RGBA): void +``` + +#### Parameters + +- **color**: `RGBA` + +### addPostProcessFn() + +#### Signature + +```typescript +addPostProcessFn(processFn: (buffer: OptimizedBuffer, deltaTime: number) => void): void +``` + +#### Parameters + +- **processFn**: `(buffer: OptimizedBuffer, deltaTime: number) => void` + +### removePostProcessFn() + +#### Signature + +```typescript +removePostProcessFn(processFn: (buffer: OptimizedBuffer, deltaTime: number) => void): void +``` + +#### Parameters + +- **processFn**: `(buffer: OptimizedBuffer, deltaTime: number) => void` + +### clearPostProcessFns() + +#### Signature + +```typescript +clearPostProcessFns(): void +``` + +### setFrameCallback() + +#### Signature + +```typescript +setFrameCallback(callback: (deltaTime: number) => Promise): void +``` + +#### Parameters + +- **callback**: `(deltaTime: number) => Promise` + +### removeFrameCallback() + +#### Signature + +```typescript +removeFrameCallback(callback: (deltaTime: number) => Promise): void +``` + +#### Parameters + +- **callback**: `(deltaTime: number) => Promise` + +### clearFrameCallbacks() + +#### Signature + +```typescript +clearFrameCallbacks(): void +``` + +### requestLive() + +#### Signature + +```typescript +requestLive(): void +``` + +### dropLive() + +#### Signature + +```typescript +dropLive(): void +``` + +### start() + +Start the render loop + +#### Signature + +```typescript +start(): void +``` + +### pause() + +#### Signature + +```typescript +pause(): void +``` + +### stop() + +Stop the render loop and clean up + +#### Signature + +```typescript +stop(): void +``` + +### destroy() + +#### Signature + +```typescript +destroy(): void +``` + +### intermediateRender() + +#### Signature + +```typescript +intermediateRender(): void +``` + +### getStats() + +#### Signature + +```typescript +getStats(): { fps: number; frameCount: number; frameTimes: number[]; averageFrameTime: number; minFrameTime: number; maxFrameTime: number; } +``` + +#### Returns + +`{ fps: number; frameCount: number; frameTimes: number[]; averageFrameTime: number; minFrameTime: number; maxFrameTime: number; }` + +### resetStats() + +#### Signature + +```typescript +resetStats(): void +``` + +### setGatherStats() + +#### Signature + +```typescript +setGatherStats(enabled: boolean): void +``` + +#### Parameters + +- **enabled**: `boolean` + +### getSelection() + +#### Signature + +```typescript +getSelection(): Selection +``` + +#### Returns + +`Selection` + +### getSelectionContainer() + +#### Signature + +```typescript +getSelectionContainer(): Renderable +``` + +#### Returns + +`Renderable` + +### hasSelection() + +#### Signature + +```typescript +hasSelection(): boolean +``` + +#### Returns + +`boolean` + +### clearSelection() + +#### Signature + +```typescript +clearSelection(): void +``` + +## Examples + +```typescript +// Create and configure renderer +const renderer = new CliRenderer(lib, ptr, stdin, stdout, 80, 24, { + backgroundColor: '#1e1e1e', + showFPS: true, + debugOverlayCorner: DebugOverlayCorner.TOP_RIGHT +}); + +// Add components +renderer.root.add(new BoxRenderable('main', { + width: '100%', + height: '100%', + border: true, + borderStyle: 'rounded' +})); + +// Start rendering +renderer.start(); +``` + +## See Also + diff --git a/packages/core/docs/api/reference/classes/InputRenderable.md b/packages/core/docs/api/reference/classes/InputRenderable.md new file mode 100644 index 00000000..6065c32a --- /dev/null +++ b/packages/core/docs/api/reference/classes/InputRenderable.md @@ -0,0 +1,311 @@ +# InputRenderable + +Single-line text input component with cursor management, selection, and validation support. Provides a terminal-based text field similar to HTML input elements. + +## Constructor + +```typescript +new InputRenderable(id: string, options: InputRenderableOptions) +``` + +### Parameters + +#### id + +Type: `string` + +Unique identifier for this input component + +#### options + +Type: `InputRenderableOptions` + +Configuration options for the input field. Key properties include: + +| Property | Type | Description | +|----------|------|-------------| +| `value` | `string` | Initial input value | +| `placeholder` | `string` | Placeholder text when empty | +| `maxLength` | `number` | Maximum character limit | +| `password` | `boolean` | Mask input for passwords | +| `cursorStyle` | `'block' \| 'line' \| 'underline'` | Cursor appearance | +| `cursorColor` | `string \| RGBA` | Cursor color | +| `focusedBorderColor` | `string \| RGBA` | Border color when focused | +| `backgroundColor` | `string \| RGBA` | Input background color | +| `textColor` | `string \| RGBA` | Input text color | +| `placeholderColor` | `string \| RGBA` | Placeholder text color | +| `pattern` | `RegExp` | Validation pattern | +| `onChange` | `(value: string) => void` | Value change callback | +| `onSubmit` | `(value: string) => void` | Enter key callback | + +## Properties + +### value + +Type: `string` + +Current input value + +### cursorPosition + +Type: `number` + +Current cursor position in the text + +### selectionStart + +Type: `number` + +Start position of text selection + +### selectionEnd + +Type: `number` + +End position of text selection + +## Methods + +### focus() + +Give keyboard focus to the input field + +#### Signature + +```typescript +focus(): void +``` + +### blur() + +Remove keyboard focus from the input field + +#### Signature + +```typescript +blur(): void +``` + +### setValue() + +Set the input value programmatically + +#### Signature + +```typescript +setValue(value: string): void +``` + +#### Parameters + +- **value**: `string` - New value to set + +### clear() + +Clear the input value + +#### Signature + +```typescript +clear(): void +``` + +### selectAll() + +Select all text in the input + +#### Signature + +```typescript +selectAll(): void +``` + +### setCursorPosition() + +Move cursor to specific position + +#### Signature + +```typescript +setCursorPosition(position: number): void +``` + +#### Parameters + +- **position**: `number` - Character position (0-based) + +### insertText() + +Insert text at cursor position + +#### Signature + +```typescript +insertText(text: string): void +``` + +#### Parameters + +- **text**: `string` - Text to insert + +### deleteSelection() + +Delete currently selected text + +#### Signature + +```typescript +deleteSelection(): void +``` + +### handleKeyPress() + +Process keyboard input + +#### Signature + +```typescript +handleKeyPress(key: ParsedKey | string): boolean +``` + +#### Parameters + +- **key**: `ParsedKey | string` - Keyboard event + +#### Returns + +`boolean` - True if the input handled the key + +### validate() + +Check if current value is valid + +#### Signature + +```typescript +validate(): boolean +``` + +#### Returns + +`boolean` - True if value passes validation + +## Examples + +### Basic Input Field + +```typescript +const nameInput = new InputRenderable('name', { + placeholder: 'Enter your name...', + width: 30, + onChange: (value) => { + console.log('Name:', value); + } +}); +``` + +### Password Input + +```typescript +const passwordInput = new InputRenderable('password', { + placeholder: 'Password', + password: true, + minLength: 8, + maxLength: 32, + onSubmit: (value) => { + login(value); + } +}); +``` + +### Validated Input + +```typescript +const emailInput = new InputRenderable('email', { + placeholder: 'Email address', + pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, + onChange: (value) => { + if (!emailInput.validate()) { + emailInput.setBorderColor('#ff0000'); + } else { + emailInput.setBorderColor('#00ff00'); + } + } +}); +``` + +### Styled Input + +```typescript +const styledInput = new InputRenderable('styled', { + value: 'Initial text', + backgroundColor: '#2e2e2e', + textColor: '#ffffff', + cursorColor: '#00ff00', + cursorStyle: 'block', + focusedBorderColor: '#00aaff', + border: true, + borderStyle: 'rounded', + padding: 1 +}); +``` + +### Form with Multiple Inputs + +```typescript +class LoginForm extends BoxRenderable { + private usernameInput: InputRenderable; + private passwordInput: InputRenderable; + + constructor() { + super('login-form', { + flexDirection: 'column', + gap: 1, + padding: 2, + border: true, + title: 'Login' + }); + + this.usernameInput = new InputRenderable('username', { + placeholder: 'Username', + width: '100%', + onSubmit: () => this.passwordInput.focus() + }); + + this.passwordInput = new InputRenderable('password', { + placeholder: 'Password', + password: true, + width: '100%', + onSubmit: () => this.submit() + }); + + this.add(this.usernameInput, 0); + this.add(this.passwordInput, 1); + } + + private submit() { + const username = this.usernameInput.value; + const password = this.passwordInput.value; + // Handle login + } +} +``` + +## Keyboard Shortcuts + +- **Left/Right Arrow** - Move cursor +- **Home/End** - Jump to start/end +- **Backspace** - Delete before cursor +- **Delete** - Delete after cursor +- **Ctrl+A** - Select all +- **Ctrl+C** - Copy selection +- **Ctrl+V** - Paste +- **Ctrl+X** - Cut selection +- **Enter** - Submit (triggers onSubmit) +- **Escape** - Blur input + +## See Also + +- [InputRenderableOptions](../interfaces/InputRenderableOptions.md) - Configuration options +- [Renderable](./Renderable.md) - Base component class +- [TextRenderable](./TextRenderable.md) - Text display component \ No newline at end of file diff --git a/packages/core/docs/api/reference/classes/MouseEvent.md b/packages/core/docs/api/reference/classes/MouseEvent.md new file mode 100644 index 00000000..eebaf1f3 --- /dev/null +++ b/packages/core/docs/api/reference/classes/MouseEvent.md @@ -0,0 +1,109 @@ +# MouseEvent + +Represents a mouse event in the terminal UI. Handles mouse interactions including clicks, drags, scrolls, and hover events. + +## Constructor + +```typescript +new MouseEvent(target: Renderable | null, attributes: RawMouseEvent & { source?: Renderable }) +``` + +### Parameters + +#### target + +Type: `Renderable | null` + +#### attributes + +Type: `RawMouseEvent & { source?: Renderable }` + +## Properties + +### type + +Type: `MouseEventType` + +The type of mouse event (down, up, move, drag, drag-end, drop, over, out, scroll) + +### button + +Type: `number` + +Which mouse button was pressed (0=left, 1=middle, 2=right) + +### x + +Type: `number` + +X coordinate of the mouse event relative to the terminal + +### y + +Type: `number` + +Y coordinate of the mouse event relative to the terminal + +### source + +Type: `Renderable` + +The renderable that originally received the event + +### modifiers + +Type: `{ + shift: boolean + alt: boolean + ctrl: boolean + }` + +Keyboard modifiers active during the event + +### scroll + +Type: `ScrollInfo` + +Scroll information if this is a scroll event + +### target + +Type: `Renderable | null` + +The renderable that is the target of the event (may be different from source due to bubbling) + +## Methods + +### preventDefault() + +Prevents the default action for this event from occurring + +#### Signature + +```typescript +preventDefault(): void +``` + +## Examples + +```typescript +// Handle mouse clicks +renderable.onMouseDown = (event: MouseEvent) => { + if (event.button === 0) { // Left click + console.log(`Clicked at ${event.x}, ${event.y}`); + event.preventDefault(); + } +}; + +// Handle mouse scroll +renderable.onMouseScroll = (event: MouseEvent) => { + if (event.scroll.direction === 'up') { + scrollUp(); + } +}; +``` + +## See Also + +- [Renderable](./Renderable.md) - Base class that handles mouse events +- [MouseEventType](../types/MouseEventType.md) - Event type enumeration diff --git a/packages/core/docs/api/reference/classes/OptimizedBuffer.md b/packages/core/docs/api/reference/classes/OptimizedBuffer.md new file mode 100644 index 00000000..3cd21c29 --- /dev/null +++ b/packages/core/docs/api/reference/classes/OptimizedBuffer.md @@ -0,0 +1,511 @@ +# OptimizedBuffer + +High-performance buffer for terminal rendering. Manages character cells, colors, and dirty regions for efficient updates. + +## Constructor + +```typescript +new OptimizedBuffer(lib: RenderLib, ptr: Pointer, buffer: { + char: Uint32Array + fg: Float32Array + bg: Float32Array + attributes: Uint8Array + }, width: number, height: number, options: { respectAlpha?: boolean }) +``` + +### Parameters + +#### lib + +Type: `RenderLib` + +#### ptr + +Type: `Pointer` + +#### buffer + +Type: `{ + char: Uint32Array + fg: Float32Array + bg: Float32Array + attributes: Uint8Array + }` + +#### width + +Type: `number` + +#### height + +Type: `number` + +#### options + +Type: `{ respectAlpha?: boolean }` + +## Properties + +### id + +Type: `string` + +### lib + +Type: `RenderLib` + +### respectAlpha + +Type: `boolean` + +## Methods + +### create() + +#### Signature + +```typescript +create(width: number, height: number, options: { respectAlpha?: boolean }): OptimizedBuffer +``` + +#### Parameters + +- **width**: `number` +- **height**: `number` +- **options**: `{ respectAlpha?: boolean }` + +#### Returns + +`OptimizedBuffer` + +### getWidth() + +#### Signature + +```typescript +getWidth(): number +``` + +#### Returns + +`number` + +### getHeight() + +#### Signature + +```typescript +getHeight(): number +``` + +#### Returns + +`number` + +### setRespectAlpha() + +#### Signature + +```typescript +setRespectAlpha(respectAlpha: boolean): void +``` + +#### Parameters + +- **respectAlpha**: `boolean` + +### clear() + +Clear the entire buffer or a region + +#### Signature + +```typescript +clear(bg: RGBA, clearChar: string): void +``` + +#### Parameters + +- **bg**: `RGBA` +- **clearChar**: `string` + +### clearLocal() + +#### Signature + +```typescript +clearLocal(bg: RGBA, clearChar: string): void +``` + +#### Parameters + +- **bg**: `RGBA` +- **clearChar**: `string` + +### setCell() + +Set a single character cell + +#### Signature + +```typescript +setCell(x: number, y: number, char: string, fg: RGBA, bg: RGBA, attributes: number): void +``` + +#### Parameters + +- **x**: `number` +- **y**: `number` +- **char**: `string` +- **fg**: `RGBA` +- **bg**: `RGBA` +- **attributes**: `number` + +### get() + +#### Signature + +```typescript +get(x: number, y: number): { char: number; fg: RGBA; bg: RGBA; attributes: number; } +``` + +#### Parameters + +- **x**: `number` +- **y**: `number` + +#### Returns + +`{ char: number; fg: RGBA; bg: RGBA; attributes: number; }` + +### setCellWithAlphaBlending() + +#### Signature + +```typescript +setCellWithAlphaBlending(x: number, y: number, char: string, fg: RGBA, bg: RGBA, attributes: number): void +``` + +#### Parameters + +- **x**: `number` +- **y**: `number` +- **char**: `string` +- **fg**: `RGBA` +- **bg**: `RGBA` +- **attributes**: `number` + +### setCellWithAlphaBlendingLocal() + +#### Signature + +```typescript +setCellWithAlphaBlendingLocal(x: number, y: number, char: string, fg: RGBA, bg: RGBA, attributes: number): void +``` + +#### Parameters + +- **x**: `number` +- **y**: `number` +- **char**: `string` +- **fg**: `RGBA` +- **bg**: `RGBA` +- **attributes**: `number` + +### drawText() + +Draw text at specified position with color + +#### Signature + +```typescript +drawText(text: string, x: number, y: number, fg: RGBA, bg: RGBA, attributes: number, selection: { start: number; end: number; bgColor?: RGBA; fgColor?: RGBA } | null): void +``` + +#### Parameters + +- **text**: `string` +- **x**: `number` +- **y**: `number` +- **fg**: `RGBA` +- **bg**: `RGBA` +- **attributes**: `number` +- **selection**: `{ start: number; end: number; bgColor?: RGBA; fgColor?: RGBA } | null` + +### fillRect() + +#### Signature + +```typescript +fillRect(x: number, y: number, width: number, height: number, bg: RGBA): void +``` + +#### Parameters + +- **x**: `number` +- **y**: `number` +- **width**: `number` +- **height**: `number` +- **bg**: `RGBA` + +### fillRectLocal() + +#### Signature + +```typescript +fillRectLocal(x: number, y: number, width: number, height: number, bg: RGBA): void +``` + +#### Parameters + +- **x**: `number` +- **y**: `number` +- **width**: `number` +- **height**: `number` +- **bg**: `RGBA` + +### drawFrameBuffer() + +#### Signature + +```typescript +drawFrameBuffer(destX: number, destY: number, frameBuffer: OptimizedBuffer, sourceX: number, sourceY: number, sourceWidth: number, sourceHeight: number): void +``` + +#### Parameters + +- **destX**: `number` +- **destY**: `number` +- **frameBuffer**: `OptimizedBuffer` +- **sourceX**: `number` +- **sourceY**: `number` +- **sourceWidth**: `number` +- **sourceHeight**: `number` + +### drawFrameBufferLocal() + +#### Signature + +```typescript +drawFrameBufferLocal(destX: number, destY: number, frameBuffer: OptimizedBuffer, sourceX: number, sourceY: number, sourceWidth: number, sourceHeight: number): void +``` + +#### Parameters + +- **destX**: `number` +- **destY**: `number` +- **frameBuffer**: `OptimizedBuffer` +- **sourceX**: `number` +- **sourceY**: `number` +- **sourceWidth**: `number` +- **sourceHeight**: `number` + +### destroy() + +#### Signature + +```typescript +destroy(): void +``` + +### drawTextBuffer() + +#### Signature + +```typescript +drawTextBuffer(textBuffer: TextBuffer, x: number, y: number, clipRect: { x: number; y: number; width: number; height: number }): void +``` + +#### Parameters + +- **textBuffer**: `TextBuffer` +- **x**: `number` +- **y**: `number` +- **clipRect**: `{ x: number; y: number; width: number; height: number }` + +### drawSuperSampleBuffer() + +#### Signature + +```typescript +drawSuperSampleBuffer(x: number, y: number, pixelDataPtr: Pointer, pixelDataLength: number, format: "bgra8unorm" | "rgba8unorm", alignedBytesPerRow: number): void +``` + +#### Parameters + +- **x**: `number` +- **y**: `number` +- **pixelDataPtr**: `Pointer` +- **pixelDataLength**: `number` +- **format**: `"bgra8unorm" | "rgba8unorm"` +- **alignedBytesPerRow**: `number` + +### drawSuperSampleBufferFFI() + +#### Signature + +```typescript +drawSuperSampleBufferFFI(x: number, y: number, pixelDataPtr: Pointer, pixelDataLength: number, format: "bgra8unorm" | "rgba8unorm", alignedBytesPerRow: number): void +``` + +#### Parameters + +- **x**: `number` +- **y**: `number` +- **pixelDataPtr**: `Pointer` +- **pixelDataLength**: `number` +- **format**: `"bgra8unorm" | "rgba8unorm"` +- **alignedBytesPerRow**: `number` + +### drawPackedBuffer() + +#### Signature + +```typescript +drawPackedBuffer(dataPtr: Pointer, dataLen: number, posX: number, posY: number, terminalWidthCells: number, terminalHeightCells: number): void +``` + +#### Parameters + +- **dataPtr**: `Pointer` +- **dataLen**: `number` +- **posX**: `number` +- **posY**: `number` +- **terminalWidthCells**: `number` +- **terminalHeightCells**: `number` + +### setCellWithAlphaBlendingFFI() + +#### Signature + +```typescript +setCellWithAlphaBlendingFFI(x: number, y: number, char: string, fg: RGBA, bg: RGBA, attributes: number): void +``` + +#### Parameters + +- **x**: `number` +- **y**: `number` +- **char**: `string` +- **fg**: `RGBA` +- **bg**: `RGBA` +- **attributes**: `number` + +### fillRectFFI() + +#### Signature + +```typescript +fillRectFFI(x: number, y: number, width: number, height: number, bg: RGBA): void +``` + +#### Parameters + +- **x**: `number` +- **y**: `number` +- **width**: `number` +- **height**: `number` +- **bg**: `RGBA` + +### resize() + +#### Signature + +```typescript +resize(width: number, height: number): void +``` + +#### Parameters + +- **width**: `number` +- **height**: `number` + +### clearFFI() + +#### Signature + +```typescript +clearFFI(bg: RGBA): void +``` + +#### Parameters + +- **bg**: `RGBA` + +### drawTextFFI() + +#### Signature + +```typescript +drawTextFFI(text: string, x: number, y: number, fg: RGBA, bg: RGBA, attributes: number): void +``` + +#### Parameters + +- **text**: `string` +- **x**: `number` +- **y**: `number` +- **fg**: `RGBA` +- **bg**: `RGBA` +- **attributes**: `number` + +### drawFrameBufferFFI() + +#### Signature + +```typescript +drawFrameBufferFFI(destX: number, destY: number, frameBuffer: OptimizedBuffer, sourceX: number, sourceY: number, sourceWidth: number, sourceHeight: number): void +``` + +#### Parameters + +- **destX**: `number` +- **destY**: `number` +- **frameBuffer**: `OptimizedBuffer` +- **sourceX**: `number` +- **sourceY**: `number` +- **sourceWidth**: `number` +- **sourceHeight**: `number` + +### drawBox() + +Draw a box with optional border + +#### Signature + +```typescript +drawBox(options: { + x: number + y: number + width: number + height: number + borderStyle?: BorderStyle + customBorderChars?: Uint32Array + border: boolean | BorderSides[] + borderColor: RGBA + backgroundColor: RGBA + shouldFill?: boolean + title?: string + titleAlignment?: "left" | "center" | "right" + }): void +``` + +#### Parameters + +- **options**: `{ + x: number + y: number + width: number + height: number + borderStyle?: BorderStyle + customBorderChars?: Uint32Array + border: boolean | BorderSides[] + borderColor: RGBA + backgroundColor: RGBA + shouldFill?: boolean + title?: string + titleAlignment?: "left" | "center" | "right" + }` + +## See Also + diff --git a/packages/core/docs/api/reference/classes/Renderable.md b/packages/core/docs/api/reference/classes/Renderable.md new file mode 100644 index 00000000..b19ef36b --- /dev/null +++ b/packages/core/docs/api/reference/classes/Renderable.md @@ -0,0 +1,392 @@ +# Renderable + +Base class for all visual components in OpenTUI. Provides layout, rendering, and event handling capabilities. + +## Constructor + +```typescript +new Renderable(id: string, options: RenderableOptions) +``` + +### Parameters + +#### id + +Type: `string` + +#### options + +Type: `RenderableOptions` + +Available options: + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `alignItems` | `AlignString` | | | +| `bottom` | `any` | | | +| `buffered` | `boolean` | | | +| `enableLayout` | `boolean` | | | +| `flexBasis` | `any` | | | +| `flexDirection` | `FlexDirectionString` | | | +| `flexGrow` | `number` | | | +| `flexShrink` | `number` | | | +| `height` | `any` | | | +| `justifyContent` | `JustifyString` | | | + +...and 32 more properties + +## Properties + +### renderablesByNumber + +Type: `Map` + +Static map for fast renderable lookups by numeric ID + +### id + +Type: `string` + +Unique identifier for this renderable + +### num + +Type: `number` + +Internal numeric identifier used for fast lookups + +### selectable + +Type: `boolean` + +Whether this component can receive text selection + +### parent + +Type: `Renderable | null` + +Parent renderable in the component tree + +## Methods + +### hasSelection() + +Check if this renderable has active text selection + +#### Signature + +```typescript +hasSelection(): boolean +``` + +#### Returns + +`boolean` + +### onSelectionChanged() + +#### Signature + +```typescript +onSelectionChanged(selection: SelectionState | null): boolean +``` + +#### Parameters + +- **selection**: `SelectionState | null` + +#### Returns + +`boolean` + +### getSelectedText() + +Get currently selected text if any + +#### Signature + +```typescript +getSelectedText(): string +``` + +#### Returns + +`string` + +### shouldStartSelection() + +#### Signature + +```typescript +shouldStartSelection(x: number, y: number): boolean +``` + +#### Parameters + +- **x**: `number` +- **y**: `number` + +#### Returns + +`boolean` + +### focus() + +Give keyboard focus to this renderable + +#### Signature + +```typescript +focus(): void +``` + +### blur() + +Remove keyboard focus from this renderable + +#### Signature + +```typescript +blur(): void +``` + +### handleKeyPress() + +Process keyboard input - returns true if handled + +#### Signature + +```typescript +handleKeyPress(key: ParsedKey | string): boolean +``` + +#### Parameters + +- **key**: `ParsedKey | string` + +#### Returns + +`boolean` + +### needsUpdate() + +Mark this renderable as needing re-render + +#### Signature + +```typescript +needsUpdate(): void +``` + +### requestZIndexSort() + +#### Signature + +```typescript +requestZIndexSort(): void +``` + +### setPosition() + +#### Signature + +```typescript +setPosition(position: Position): void +``` + +#### Parameters + +- **position**: `Position` + +### getLayoutNode() + +#### Signature + +```typescript +getLayoutNode(): TrackedNode +``` + +#### Returns + +`TrackedNode` + +### updateFromLayout() + +#### Signature + +```typescript +updateFromLayout(): void +``` + +### add() + +Add a child renderable at the specified index + +#### Signature + +```typescript +add(obj: Renderable, index: number): number +``` + +#### Parameters + +- **obj**: `Renderable` +- **index**: `number` + +#### Returns + +`number` + +### insertBefore() + +#### Signature + +```typescript +insertBefore(obj: Renderable, anchor: Renderable): number +``` + +#### Parameters + +- **obj**: `Renderable` +- **anchor**: `Renderable` + +#### Returns + +`number` + +### propagateContext() + +#### Signature + +```typescript +propagateContext(ctx: RenderContext | null): void +``` + +#### Parameters + +- **ctx**: `RenderContext | null` + +### getRenderable() + +#### Signature + +```typescript +getRenderable(id: string): Renderable +``` + +#### Parameters + +- **id**: `string` + +#### Returns + +`Renderable` + +### remove() + +Remove a child renderable by ID + +#### Signature + +```typescript +remove(id: string): void +``` + +#### Parameters + +- **id**: `string` + +### getChildren() + +#### Signature + +```typescript +getChildren(): Renderable[] +``` + +#### Returns + +`Renderable[]` + +### render() + +Render this component and its children to the buffer + +#### Signature + +```typescript +render(buffer: OptimizedBuffer, deltaTime: number): void +``` + +#### Parameters + +- **buffer**: `OptimizedBuffer` +- **deltaTime**: `number` + +### destroy() + +Clean up resources and remove from parent + +#### Signature + +```typescript +destroy(): void +``` + +### destroyRecursively() + +#### Signature + +```typescript +destroyRecursively(): void +``` + +### processMouseEvent() + +Process mouse events and propagate to children + +#### Signature + +```typescript +processMouseEvent(event: MouseEvent): void +``` + +#### Parameters + +- **event**: `MouseEvent` + +## Examples + +```typescript +// Create a custom renderable +class MyComponent extends Renderable { + constructor(id: string, options: RenderableOptions) { + super(id, options); + } + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + // Custom rendering logic + buffer.drawText('Hello World', this.x, this.y, RGBA.white()); + } +} + +// Add event handlers +const component = new MyComponent('my-comp', { + width: 20, + height: 10, + onMouseDown: (event) => { + console.log('Clicked!'); + }, + onKeyDown: (key) => { + if (key.name === 'escape') { + component.blur(); + } + } +}); +``` + +## See Also + +- [RenderableOptions](../interfaces/RenderableOptions.md) - Configuration options +- [MouseEvent](./MouseEvent.md) - Mouse event handling +- [OptimizedBuffer](./OptimizedBuffer.md) - Rendering target diff --git a/packages/core/docs/api/reference/classes/RootRenderable.md b/packages/core/docs/api/reference/classes/RootRenderable.md new file mode 100644 index 00000000..7349b865 --- /dev/null +++ b/packages/core/docs/api/reference/classes/RootRenderable.md @@ -0,0 +1,59 @@ +# RootRenderable + +## Constructor + +```typescript +new RootRenderable(width: number, height: number, ctx: RenderContext, rootContext: RootContext) +``` + +### Parameters + +#### width + +Type: `number` + +#### height + +Type: `number` + +#### ctx + +Type: `RenderContext` + +#### rootContext + +Type: `RootContext` + +## Methods + +### requestLayout() + +#### Signature + +```typescript +requestLayout(): void +``` + +### calculateLayout() + +#### Signature + +```typescript +calculateLayout(): void +``` + +### resize() + +#### Signature + +```typescript +resize(width: number, height: number): void +``` + +#### Parameters + +- **width**: `number` +- **height**: `number` + +## See Also + diff --git a/packages/core/docs/api/reference/classes/TextRenderable.md b/packages/core/docs/api/reference/classes/TextRenderable.md new file mode 100644 index 00000000..d23ac25f --- /dev/null +++ b/packages/core/docs/api/reference/classes/TextRenderable.md @@ -0,0 +1,228 @@ +# TextRenderable + +Text display component with support for styling, word wrapping, and text selection. Extends Renderable to provide rich text rendering capabilities in the terminal. + +## Constructor + +```typescript +new TextRenderable(id: string, options: TextOptions) +``` + +### Parameters + +#### id + +Type: `string` + +Unique identifier for this text component + +#### options + +Type: `TextOptions` + +Configuration options for the text component. Key properties include: + +| Property | Type | Description | +|----------|------|-------------| +| `text` | `string` | The text content to display | +| `color` | `string \| RGBA` | Text foreground color | +| `backgroundColor` | `string \| RGBA` | Text background color | +| `align` | `'left' \| 'center' \| 'right'` | Text alignment | +| `wrap` | `boolean` | Enable word wrapping | +| `selectable` | `boolean` | Allow text selection | +| `bold` | `boolean` | Bold text style | +| `italic` | `boolean` | Italic text style | +| `underline` | `boolean` | Underline text style | +| `parseMarkup` | `boolean` | Parse style markup in text | + +## Properties + +### selectable + +Type: `boolean` + +Whether text selection is enabled for this component + +### text + +Type: `string` + +The current text content + +### wrap + +Type: `boolean` + +Whether word wrapping is enabled + +## Methods + +### setText() + +Update the text content + +#### Signature + +```typescript +setText(text: string): void +``` + +#### Parameters + +- **text**: `string` - New text content to display + +### shouldStartSelection() + +Determine if selection should start at given coordinates + +#### Signature + +```typescript +shouldStartSelection(x: number, y: number): boolean +``` + +#### Parameters + +- **x**: `number` - X coordinate relative to component +- **y**: `number` - Y coordinate relative to component + +#### Returns + +`boolean` - True if selection can start at this position + +### onSelectionChanged() + +Handle selection state changes + +#### Signature + +```typescript +onSelectionChanged(selection: SelectionState | null): boolean +``` + +#### Parameters + +- **selection**: `SelectionState | null` - New selection state or null to clear + +#### Returns + +`boolean` - True if selection was handled + +### getSelectedText() + +Get currently selected text + +#### Signature + +```typescript +getSelectedText(): string +``` + +#### Returns + +`string` - The selected text content, empty string if no selection + +### hasSelection() + +Check if any text is currently selected + +#### Signature + +```typescript +hasSelection(): boolean +``` + +#### Returns + +`boolean` - True if text is selected + +### destroy() + +Clean up resources and remove from parent + +#### Signature + +```typescript +destroy(): void +``` + +## Examples + +### Basic Text + +```typescript +const label = new TextRenderable('label', { + text: 'Hello World', + color: '#ffffff', + backgroundColor: '#0000ff' +}); +``` + +### Centered Text with Wrapping + +```typescript +const paragraph = new TextRenderable('paragraph', { + text: 'This is a long paragraph that will wrap to multiple lines when displayed in the terminal.', + align: 'center', + wrap: true, + width: 40 +}); +``` + +### Styled Text with Markup + +```typescript +const styledText = new TextRenderable('styled', { + text: '{bold}Important:{/} {red}Error{/} - {underline}Please fix{/}', + parseMarkup: true +}); +``` + +### Selectable Text + +```typescript +const selectableText = new TextRenderable('selectable', { + text: 'You can select this text with the mouse', + selectable: true, + selectionBg: '#ffff00', + selectionFg: '#000000', + onSelectionChanged: (selection) => { + if (selection) { + console.log('Selected:', selectableText.getSelectedText()); + } + } +}); +``` + +### Dynamic Text Updates + +```typescript +const counter = new TextRenderable('counter', { + text: 'Count: 0', + color: '#00ff00' +}); + +let count = 0; +setInterval(() => { + count++; + counter.setText(`Count: ${count}`); + counter.needsUpdate(); +}, 1000); +``` + +## Markup Syntax + +When `parseMarkup` is enabled, you can use inline styles: + +- `{bold}text{/}` - Bold text +- `{italic}text{/}` - Italic text +- `{underline}text{/}` - Underlined text +- `{red}text{/}` - Red text (supports all CSS color names) +- `{#ff0000}text{/}` - Hex color codes +- `{bg:blue}text{/}` - Background colors + +## See Also + +- [TextOptions](../interfaces/TextOptions.md) - Configuration options +- [Renderable](./Renderable.md) - Base component class +- [RGBA](./RGBA.md) - Color utilities \ No newline at end of file diff --git a/packages/core/docs/api/reference/classes/Timeline.md b/packages/core/docs/api/reference/classes/Timeline.md new file mode 100644 index 00000000..3b2abc58 --- /dev/null +++ b/packages/core/docs/api/reference/classes/Timeline.md @@ -0,0 +1,225 @@ +# Timeline + +Animation timeline system for orchestrating complex animations and transitions. + +## Constructor + +```typescript +new Timeline(options: TimelineOptions) +``` + +### Parameters + +#### options + +Type: `TimelineOptions` + +Available options: + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `autoplay` | `boolean` | | | +| `duration` | `number` | | | +| `loop` | `boolean` | | | +| `onComplete` | `any` | | () => void | +| `onPause` | `any` | | () => void | + +## Properties + +### items + +Type: `(TimelineAnimationItem | TimelineCallbackItem)[]` + +### subTimelines + +Type: `TimelineTimelineItem[]` + +### currentTime + +Type: `number` + +Current playback position + +### isPlaying + +Type: `boolean` + +Whether the timeline is currently playing + +### isComplete + +Type: `boolean` + +### duration + +Type: `number` + +Total duration of the timeline in milliseconds + +### loop + +Type: `boolean` + +Whether to loop when reaching the end + +### synced + +Type: `boolean` + +## Methods + +### add() + +Add an animation to the timeline + +#### Signature + +```typescript +add(target: any, properties: AnimationOptions, startTime: number | string): this +``` + +#### Parameters + +- **target**: `any` +- **properties**: `AnimationOptions` +- **startTime**: `number | string` + +#### Returns + +`this` + +### once() + +#### Signature + +```typescript +once(target: any, properties: AnimationOptions): this +``` + +#### Parameters + +- **target**: `any` +- **properties**: `AnimationOptions` + +#### Returns + +`this` + +### call() + +#### Signature + +```typescript +call(callback: () => void, startTime: number | string): this +``` + +#### Parameters + +- **callback**: `() => void` +- **startTime**: `number | string` + +#### Returns + +`this` + +### sync() + +#### Signature + +```typescript +sync(timeline: Timeline, startTime: number): this +``` + +#### Parameters + +- **timeline**: `Timeline` +- **startTime**: `number` + +#### Returns + +`this` + +### play() + +Start or resume playback + +#### Signature + +```typescript +play(): this +``` + +#### Returns + +`this` + +### pause() + +Pause playback + +#### Signature + +```typescript +pause(): this +``` + +#### Returns + +`this` + +### resetItems() + +#### Signature + +```typescript +resetItems(): void +``` + +### restart() + +#### Signature + +```typescript +restart(): this +``` + +#### Returns + +`this` + +### update() + +#### Signature + +```typescript +update(deltaTime: number): void +``` + +#### Parameters + +- **deltaTime**: `number` + +## Examples + +```typescript +// Create animation timeline +const timeline = new Timeline({ + duration: 2000, + loop: true, + autoplay: true +}); + +// Add animations +timeline.add({ + target: myComponent, + properties: { + x: { from: 0, to: 100 }, + opacity: { from: 0, to: 1 } + }, + duration: 1000, + easing: 'easeInOutQuad' +}); +``` + +## See Also + diff --git a/packages/core/docs/api/reference/index.md b/packages/core/docs/api/reference/index.md new file mode 100644 index 00000000..19d543ad --- /dev/null +++ b/packages/core/docs/api/reference/index.md @@ -0,0 +1,43 @@ +# OpenTUI API Reference + +Complete API documentation for OpenTUI, generated from source code. + +## Classes + +- [Renderable](./classes/Renderable.md) - 22 methods +- [RootRenderable](./classes/RootRenderable.md) - 3 methods +- [MouseEvent](./classes/MouseEvent.md) - 1 methods +- [CliRenderer](./classes/CliRenderer.md) - 35 methods +- [OptimizedBuffer](./classes/OptimizedBuffer.md) - 27 methods +- [BoxRenderable](./classes/BoxRenderable.md) - 0 methods +- [TextRenderable](./classes/TextRenderable.md) - 5 methods +- [ASCIIFontRenderable](./classes/ASCIIFontRenderable.md) - 4 methods +- [InputRenderable](./classes/InputRenderable.md) - 3 methods +- [Timeline](./classes/Timeline.md) - 9 methods + +## Interfaces + +- [RootContext](./interfaces/RootContext.md) +- [Position](./interfaces/Position.md) +- [LayoutOptions](./interfaces/LayoutOptions.md) +- [RenderableOptions](./interfaces/RenderableOptions.md) +- [CliRendererConfig](./interfaces/CliRendererConfig.md) +- [BoxOptions](./interfaces/BoxOptions.md) +- [TextOptions](./interfaces/TextOptions.md) +- [ASCIIFontOptions](./interfaces/ASCIIFontOptions.md) +- [InputRenderableOptions](./interfaces/InputRenderableOptions.md) +- [TimelineOptions](./interfaces/TimelineOptions.md) +- [AnimationOptions](./interfaces/AnimationOptions.md) +- [JSAnimation](./interfaces/JSAnimation.md) + +## Type Definitions + +- [BorderConfig](./types/BorderConfig.md) +- [BoxDrawOptions](./types/BoxDrawOptions.md) +- [ConsoleOptions](./types/ConsoleOptions.md) +- [ExplosionEffectParameters](./types/ExplosionEffectParameters.md) +- [FrameBufferOptions](./types/FrameBufferOptions.md) +- [Renderable.class](./types/Renderable.class.md) +- [SelectRenderableOptions](./types/SelectRenderableOptions.md) +- [TabSelectRenderableOptions](./types/TabSelectRenderableOptions.md) +- [ThreeCliRendererOptions](./types/ThreeCliRendererOptions.md) diff --git a/packages/core/docs/api/reference/interfaces/ASCIIFontOptions.md b/packages/core/docs/api/reference/interfaces/ASCIIFontOptions.md new file mode 100644 index 00000000..c2096c70 --- /dev/null +++ b/packages/core/docs/api/reference/interfaces/ASCIIFontOptions.md @@ -0,0 +1,222 @@ +# ASCIIFontOptions + +Interface defining the structure for ASCIIFontOptions. + +## Properties + +### alignItems? + +**Type:** `AlignString` + +### bg? + +**Type:** `RGBA` + +### bottom? + +**Type:** `number | string | string` + +### buffered? + +**Type:** `boolean` + +### enableLayout? + +**Type:** `boolean` + +### fg? + +**Type:** `RGBA | array` + +### flexBasis? + +**Type:** `number | string` + +### flexDirection? + +**Type:** `FlexDirectionString` + +### flexGrow? + +**Type:** `number` + +### flexShrink? + +**Type:** `number` + +### font? + +**Type:** `string` + +### height? + +**Type:** `number | string | string` + +### justifyContent? + +**Type:** `JustifyString` + +### left? + +**Type:** `number | string | string` + +### live? + +**Type:** `boolean` + +### margin? + +**Type:** `number | string | string` + +### marginBottom? + +**Type:** `number | string | string` + +### marginLeft? + +**Type:** `number | string | string` + +### marginRight? + +**Type:** `number | string | string` + +### marginTop? + +**Type:** `number | string | string` + +### maxHeight? + +**Type:** `number` + +### maxWidth? + +**Type:** `number` + +### minHeight? + +**Type:** `number` + +### minWidth? + +**Type:** `number` + +### onKeyDown? + +**Type:** `object` + +(key: ParsedKey) => void + +### onMouseDown? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDrag? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDragEnd? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDrop? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseMove? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseOut? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseOver? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseScroll? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseUp? + +**Type:** `object` + +(event: MouseEvent) => void + +### padding? + +**Type:** `number | string` + +### paddingBottom? + +**Type:** `number | string` + +### paddingLeft? + +**Type:** `number | string` + +### paddingRight? + +**Type:** `number | string` + +### paddingTop? + +**Type:** `number | string` + +### position? + +**Type:** `PositionTypeString` + +### right? + +**Type:** `number | string | string` + +### selectable? + +**Type:** `boolean` + +### selectionBg? + +**Type:** `string | RGBA` + +### selectionFg? + +**Type:** `string | RGBA` + +### text? + +**Type:** `string` + +### top? + +**Type:** `number | string | string` + +### visible? + +**Type:** `boolean` + +### width? + +**Type:** `number | string | string` + +### zIndex? + +**Type:** `number` + diff --git a/packages/core/docs/api/reference/interfaces/AnimationOptions.md b/packages/core/docs/api/reference/interfaces/AnimationOptions.md new file mode 100644 index 00000000..c21c3e10 --- /dev/null +++ b/packages/core/docs/api/reference/interfaces/AnimationOptions.md @@ -0,0 +1,54 @@ +# AnimationOptions + +Interface defining the structure for AnimationOptions. + +## Properties + +### alternate? + +**Type:** `boolean` + +### duration + +**Type:** `number` + +### ease? + +**Type:** `EasingFunctions` + +### loop? + +**Type:** `boolean | number` + +### loopDelay? + +**Type:** `number` + +### onComplete? + +**Type:** `any` + +() => void + +### onLoop? + +**Type:** `any` + +() => void + +### onStart? + +**Type:** `any` + +() => void + +### onUpdate? + +**Type:** `object` + +(animation: JSAnimation) => void + +### once? + +**Type:** `boolean` + diff --git a/packages/core/docs/api/reference/interfaces/BoxOptions.md b/packages/core/docs/api/reference/interfaces/BoxOptions.md new file mode 100644 index 00000000..3325f381 --- /dev/null +++ b/packages/core/docs/api/reference/interfaces/BoxOptions.md @@ -0,0 +1,305 @@ +# BoxOptions + +Configuration options for creating BoxRenderable components. Extends RenderableOptions with box-specific styling like borders, padding, and title support. + +## Properties + +### alignItems? + +**Type:** `AlignString` + +Controls alignment of child items along the cross axis in flexbox layout. Options: 'flex-start', 'flex-end', 'center', 'stretch', 'baseline' + +### backgroundColor? + +**Type:** `string | RGBA` + +Background color of the box. Accepts CSS color strings ('#ffffff', 'red') or RGBA objects + +### border? + +**Type:** `boolean | array` + +Enable border rendering. Can be boolean for all sides or array to specify individual sides: [top, right, bottom, left] + +### borderColor? + +**Type:** `string | RGBA` + +Color of the border when enabled. Accepts CSS color strings or RGBA objects + +### borderStyle? + +**Type:** `BorderStyle` + +Style of border characters: 'single' (─│), 'double' (═║), 'rounded' (ā•­ā•®), 'heavy' (ā”ā”ƒ) + +### bottom? + +**Type:** `number | string | string` + +### buffered? + +**Type:** `boolean` + +### customBorderChars? + +**Type:** `BorderCharacters` + +### enableLayout? + +**Type:** `boolean` + +### flexBasis? + +**Type:** `number | string` + +### flexDirection? + +**Type:** `FlexDirectionString` + +### flexGrow? + +**Type:** `number` + +### flexShrink? + +**Type:** `number` + +### focusedBorderColor? + +**Type:** `ColorInput` + +Border color when the box has keyboard focus. Useful for indicating active state + +### height? + +**Type:** `number | string | string` + +### justifyContent? + +**Type:** `JustifyString` + +### left? + +**Type:** `number | string | string` + +### live? + +**Type:** `boolean` + +### margin? + +**Type:** `number | string | string` + +### marginBottom? + +**Type:** `number | string | string` + +### marginLeft? + +**Type:** `number | string | string` + +### marginRight? + +**Type:** `number | string | string` + +### marginTop? + +**Type:** `number | string | string` + +### maxHeight? + +**Type:** `number` + +### maxWidth? + +**Type:** `number` + +### minHeight? + +**Type:** `number` + +### minWidth? + +**Type:** `number` + +### onKeyDown? + +**Type:** `object` + +(key: ParsedKey) => void + +### onMouseDown? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDrag? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDragEnd? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDrop? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseMove? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseOut? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseOver? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseScroll? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseUp? + +**Type:** `object` + +(event: MouseEvent) => void + +### padding? + +**Type:** `number | string` + +### paddingBottom? + +**Type:** `number | string` + +### paddingLeft? + +**Type:** `number | string` + +### paddingRight? + +**Type:** `number | string` + +### paddingTop? + +**Type:** `number | string` + +### position? + +**Type:** `PositionTypeString` + +### right? + +**Type:** `number | string | string` + +### shouldFill? + +**Type:** `boolean` + +### title? + +**Type:** `string` + +Optional title text displayed in the top border of the box + +### titleAlignment? + +**Type:** `string` + +Alignment of the title within the top border: 'left', 'center', 'right' + +### top? + +**Type:** `number | string | string` + +### visible? + +**Type:** `boolean` + +### width? + +**Type:** `number | string | string` + +### zIndex? + +**Type:** `number` + +Layer order for overlapping components. Higher values appear on top + +## Examples + +```typescript +// Basic box with border +const box = new BoxRenderable('my-box', { + width: 40, + height: 10, + border: true, + borderStyle: 'rounded', + borderColor: '#00ff00' +}); + +// Box with title and padding +const titledBox = new BoxRenderable('titled', { + width: '50%', + height: 15, + border: true, + title: 'Settings', + titleAlignment: 'center', + padding: 1, + backgroundColor: '#1e1e1e' +}); + +// Flexbox container +const container = new BoxRenderable('container', { + width: '100%', + height: '100%', + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + padding: 2 +}); + +// Interactive box with focus highlight +const interactiveBox = new BoxRenderable('interactive', { + width: 30, + height: 5, + border: true, + borderColor: '#808080', + focusedBorderColor: '#00ff00', + onMouseDown: (event) => { + console.log('Box clicked!'); + }, + onKeyDown: (key) => { + if (key.name === 'enter') { + // Handle enter key + } + } +}); +``` + +## See Also + +- [RenderableOptions](./RenderableOptions.md) - Base options inherited by BoxOptions +- [BoxRenderable](../classes/BoxRenderable.md) - Box component class +- [BorderStyle](../types/BorderStyle.md) - Available border styles + diff --git a/packages/core/docs/api/reference/interfaces/CliRendererConfig.md b/packages/core/docs/api/reference/interfaces/CliRendererConfig.md new file mode 100644 index 00000000..96b4f0a5 --- /dev/null +++ b/packages/core/docs/api/reference/interfaces/CliRendererConfig.md @@ -0,0 +1,70 @@ +# CliRendererConfig + +Interface defining the structure for CliRendererConfig. + +## Properties + +### consoleOptions? + +**Type:** `ConsoleOptions` + +### debounceDelay? + +**Type:** `number` + +### enableMouseMovement? + +**Type:** `boolean` + +### exitOnCtrlC? + +**Type:** `boolean` + +### experimental_splitHeight? + +**Type:** `number` + +### gatherStats? + +**Type:** `boolean` + +### maxStatSamples? + +**Type:** `number` + +### memorySnapshotInterval? + +**Type:** `number` + +### postProcessFns? + +**Type:** `array` + +### stdin? + +**Type:** `global.NodeJS.ReadStream` + +### stdout? + +**Type:** `global.NodeJS.WriteStream` + +### targetFps? + +**Type:** `number` + +### useAlternateScreen? + +**Type:** `boolean` + +### useConsole? + +**Type:** `boolean` + +### useMouse? + +**Type:** `boolean` + +### useThread? + +**Type:** `boolean` + diff --git a/packages/core/docs/api/reference/interfaces/InputRenderableOptions.md b/packages/core/docs/api/reference/interfaces/InputRenderableOptions.md new file mode 100644 index 00000000..07c5691e --- /dev/null +++ b/packages/core/docs/api/reference/interfaces/InputRenderableOptions.md @@ -0,0 +1,230 @@ +# InputRenderableOptions + +Interface defining the structure for InputRenderableOptions. + +## Properties + +### alignItems? + +**Type:** `AlignString` + +### backgroundColor? + +**Type:** `ColorInput` + +### bottom? + +**Type:** `number | string | string` + +### buffered? + +**Type:** `boolean` + +### cursorColor? + +**Type:** `ColorInput` + +### enableLayout? + +**Type:** `boolean` + +### flexBasis? + +**Type:** `number | string` + +### flexDirection? + +**Type:** `FlexDirectionString` + +### flexGrow? + +**Type:** `number` + +### flexShrink? + +**Type:** `number` + +### focusedBackgroundColor? + +**Type:** `ColorInput` + +### focusedTextColor? + +**Type:** `ColorInput` + +### height? + +**Type:** `number | string | string` + +### justifyContent? + +**Type:** `JustifyString` + +### left? + +**Type:** `number | string | string` + +### live? + +**Type:** `boolean` + +### margin? + +**Type:** `number | string | string` + +### marginBottom? + +**Type:** `number | string | string` + +### marginLeft? + +**Type:** `number | string | string` + +### marginRight? + +**Type:** `number | string | string` + +### marginTop? + +**Type:** `number | string | string` + +### maxHeight? + +**Type:** `number` + +### maxLength? + +**Type:** `number` + +### maxWidth? + +**Type:** `number` + +### minHeight? + +**Type:** `number` + +### minWidth? + +**Type:** `number` + +### onKeyDown? + +**Type:** `object` + +(key: ParsedKey) => void + +### onMouseDown? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDrag? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDragEnd? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDrop? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseMove? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseOut? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseOver? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseScroll? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseUp? + +**Type:** `object` + +(event: MouseEvent) => void + +### padding? + +**Type:** `number | string` + +### paddingBottom? + +**Type:** `number | string` + +### paddingLeft? + +**Type:** `number | string` + +### paddingRight? + +**Type:** `number | string` + +### paddingTop? + +**Type:** `number | string` + +### placeholder? + +**Type:** `string` + +### placeholderColor? + +**Type:** `ColorInput` + +### position? + +**Type:** `PositionTypeString` + +### right? + +**Type:** `number | string | string` + +### textColor? + +**Type:** `ColorInput` + +### top? + +**Type:** `number | string | string` + +### value? + +**Type:** `string` + +### visible? + +**Type:** `boolean` + +### width? + +**Type:** `number | string | string` + +### zIndex? + +**Type:** `number` + diff --git a/packages/core/docs/api/reference/interfaces/JSAnimation.md b/packages/core/docs/api/reference/interfaces/JSAnimation.md new file mode 100644 index 00000000..7160638f --- /dev/null +++ b/packages/core/docs/api/reference/interfaces/JSAnimation.md @@ -0,0 +1,22 @@ +# JSAnimation + +Interface defining the structure for JSAnimation. + +## Properties + +### targets + +**Type:** `any[]` + +### deltaTime + +**Type:** `number` + +### progress + +**Type:** `number` + +### currentTime + +**Type:** `number` + diff --git a/packages/core/docs/api/reference/interfaces/LayoutOptions.md b/packages/core/docs/api/reference/interfaces/LayoutOptions.md new file mode 100644 index 00000000..4fb95280 --- /dev/null +++ b/packages/core/docs/api/reference/interfaces/LayoutOptions.md @@ -0,0 +1,110 @@ +# LayoutOptions + +Interface defining the structure for LayoutOptions. + +## Properties + +### alignItems? + +**Type:** `AlignString` + +### bottom? + +**Type:** `number | string | string` + +### enableLayout? + +**Type:** `boolean` + +### flexBasis? + +**Type:** `number | string` + +### flexDirection? + +**Type:** `FlexDirectionString` + +### flexGrow? + +**Type:** `number` + +### flexShrink? + +**Type:** `number` + +### justifyContent? + +**Type:** `JustifyString` + +### left? + +**Type:** `number | string | string` + +### margin? + +**Type:** `number | string | string` + +### marginBottom? + +**Type:** `number | string | string` + +### marginLeft? + +**Type:** `number | string | string` + +### marginRight? + +**Type:** `number | string | string` + +### marginTop? + +**Type:** `number | string | string` + +### maxHeight? + +**Type:** `number` + +### maxWidth? + +**Type:** `number` + +### minHeight? + +**Type:** `number` + +### minWidth? + +**Type:** `number` + +### padding? + +**Type:** `number | string` + +### paddingBottom? + +**Type:** `number | string` + +### paddingLeft? + +**Type:** `number | string` + +### paddingRight? + +**Type:** `number | string` + +### paddingTop? + +**Type:** `number | string` + +### position? + +**Type:** `PositionTypeString` + +### right? + +**Type:** `number | string | string` + +### top? + +**Type:** `number | string | string` + diff --git a/packages/core/docs/api/reference/interfaces/Position.md b/packages/core/docs/api/reference/interfaces/Position.md new file mode 100644 index 00000000..f74a4556 --- /dev/null +++ b/packages/core/docs/api/reference/interfaces/Position.md @@ -0,0 +1,22 @@ +# Position + +Interface defining the structure for Position. + +## Properties + +### top + +**Type:** `number | "auto" | `${number}%`` + +### right + +**Type:** `number | "auto" | `${number}%`` + +### bottom + +**Type:** `number | "auto" | `${number}%`` + +### left + +**Type:** `number | "auto" | `${number}%`` + diff --git a/packages/core/docs/api/reference/interfaces/RenderableOptions.md b/packages/core/docs/api/reference/interfaces/RenderableOptions.md new file mode 100644 index 00000000..f724c86f --- /dev/null +++ b/packages/core/docs/api/reference/interfaces/RenderableOptions.md @@ -0,0 +1,194 @@ +# RenderableOptions + +Interface defining the structure for RenderableOptions. + +## Properties + +### alignItems? + +**Type:** `AlignString` + +### bottom? + +**Type:** `number | string | string` + +### buffered? + +**Type:** `boolean` + +### enableLayout? + +**Type:** `boolean` + +### flexBasis? + +**Type:** `number | string` + +### flexDirection? + +**Type:** `FlexDirectionString` + +### flexGrow? + +**Type:** `number` + +### flexShrink? + +**Type:** `number` + +### height? + +**Type:** `number | string | string` + +### justifyContent? + +**Type:** `JustifyString` + +### left? + +**Type:** `number | string | string` + +### live? + +**Type:** `boolean` + +### margin? + +**Type:** `number | string | string` + +### marginBottom? + +**Type:** `number | string | string` + +### marginLeft? + +**Type:** `number | string | string` + +### marginRight? + +**Type:** `number | string | string` + +### marginTop? + +**Type:** `number | string | string` + +### maxHeight? + +**Type:** `number` + +### maxWidth? + +**Type:** `number` + +### minHeight? + +**Type:** `number` + +### minWidth? + +**Type:** `number` + +### onKeyDown? + +**Type:** `object` + +(key: ParsedKey) => void + +### onMouseDown? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDrag? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDragEnd? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDrop? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseMove? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseOut? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseOver? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseScroll? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseUp? + +**Type:** `object` + +(event: MouseEvent) => void + +### padding? + +**Type:** `number | string` + +### paddingBottom? + +**Type:** `number | string` + +### paddingLeft? + +**Type:** `number | string` + +### paddingRight? + +**Type:** `number | string` + +### paddingTop? + +**Type:** `number | string` + +### position? + +**Type:** `PositionTypeString` + +### right? + +**Type:** `number | string | string` + +### top? + +**Type:** `number | string | string` + +### visible? + +**Type:** `boolean` + +### width? + +**Type:** `number | string | string` + +### zIndex? + +**Type:** `number` + diff --git a/packages/core/docs/api/reference/interfaces/RootContext.md b/packages/core/docs/api/reference/interfaces/RootContext.md new file mode 100644 index 00000000..2e32d822 --- /dev/null +++ b/packages/core/docs/api/reference/interfaces/RootContext.md @@ -0,0 +1,14 @@ +# RootContext + +Interface defining the structure for RootContext. + +## Properties + +### requestLive + +**Type:** `void` + +### dropLive + +**Type:** `void` + diff --git a/packages/core/docs/api/reference/interfaces/TextOptions.md b/packages/core/docs/api/reference/interfaces/TextOptions.md new file mode 100644 index 00000000..4eb91c45 --- /dev/null +++ b/packages/core/docs/api/reference/interfaces/TextOptions.md @@ -0,0 +1,222 @@ +# TextOptions + +Interface defining the structure for TextOptions. + +## Properties + +### alignItems? + +**Type:** `AlignString` + +### attributes? + +**Type:** `number` + +### bg? + +**Type:** `string | RGBA` + +### bottom? + +**Type:** `number | string | string` + +### buffered? + +**Type:** `boolean` + +### content? + +**Type:** `StyledText | string` + +### enableLayout? + +**Type:** `boolean` + +### fg? + +**Type:** `string | RGBA` + +### flexBasis? + +**Type:** `number | string` + +### flexDirection? + +**Type:** `FlexDirectionString` + +### flexGrow? + +**Type:** `number` + +### flexShrink? + +**Type:** `number` + +### height? + +**Type:** `number | string | string` + +### justifyContent? + +**Type:** `JustifyString` + +### left? + +**Type:** `number | string | string` + +### live? + +**Type:** `boolean` + +### margin? + +**Type:** `number | string | string` + +### marginBottom? + +**Type:** `number | string | string` + +### marginLeft? + +**Type:** `number | string | string` + +### marginRight? + +**Type:** `number | string | string` + +### marginTop? + +**Type:** `number | string | string` + +### maxHeight? + +**Type:** `number` + +### maxWidth? + +**Type:** `number` + +### minHeight? + +**Type:** `number` + +### minWidth? + +**Type:** `number` + +### onKeyDown? + +**Type:** `object` + +(key: ParsedKey) => void + +### onMouseDown? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDrag? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDragEnd? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseDrop? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseMove? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseOut? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseOver? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseScroll? + +**Type:** `object` + +(event: MouseEvent) => void + +### onMouseUp? + +**Type:** `object` + +(event: MouseEvent) => void + +### padding? + +**Type:** `number | string` + +### paddingBottom? + +**Type:** `number | string` + +### paddingLeft? + +**Type:** `number | string` + +### paddingRight? + +**Type:** `number | string` + +### paddingTop? + +**Type:** `number | string` + +### position? + +**Type:** `PositionTypeString` + +### right? + +**Type:** `number | string | string` + +### selectable? + +**Type:** `boolean` + +### selectionBg? + +**Type:** `string | RGBA` + +### selectionFg? + +**Type:** `string | RGBA` + +### top? + +**Type:** `number | string | string` + +### visible? + +**Type:** `boolean` + +### width? + +**Type:** `number | string | string` + +### zIndex? + +**Type:** `number` + diff --git a/packages/core/docs/api/reference/interfaces/TimelineOptions.md b/packages/core/docs/api/reference/interfaces/TimelineOptions.md new file mode 100644 index 00000000..59dbc0c4 --- /dev/null +++ b/packages/core/docs/api/reference/interfaces/TimelineOptions.md @@ -0,0 +1,30 @@ +# TimelineOptions + +Interface defining the structure for TimelineOptions. + +## Properties + +### autoplay? + +**Type:** `boolean` + +### duration? + +**Type:** `number` + +### loop? + +**Type:** `boolean` + +### onComplete? + +**Type:** `any` + +() => void + +### onPause? + +**Type:** `any` + +() => void + diff --git a/packages/core/docs/api/reference/types/BorderConfig.md b/packages/core/docs/api/reference/types/BorderConfig.md new file mode 100644 index 00000000..f9b55a6a --- /dev/null +++ b/packages/core/docs/api/reference/types/BorderConfig.md @@ -0,0 +1,27 @@ +# BorderConfig + +## Properties + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `border` | `boolean | array` | āœ“ | | +| `borderColor` | `ColorInput` | | | +| `borderStyle` | `BorderStyle` | āœ“ | | +| `customBorderChars` | `BorderCharacters` | | | + +## Example + +```typescript +const options: BorderConfig = { + border: undefined, + borderStyle: undefined +}; +``` + +## Related Types + +- `BorderCharacters` +- `BorderSides` +- `BorderStyle` +- `ColorInput` +- `RGBA` diff --git a/packages/core/docs/api/reference/types/BorderStyle.md b/packages/core/docs/api/reference/types/BorderStyle.md new file mode 100644 index 00000000..5002cb41 --- /dev/null +++ b/packages/core/docs/api/reference/types/BorderStyle.md @@ -0,0 +1,71 @@ +# BorderStyle + +Defines the visual style of borders used in box components. + +## Type Definition + +```typescript +type BorderStyle = 'single' | 'double' | 'rounded' | 'heavy'; +``` + +## Values + +### single +Single-line border using standard box-drawing characters: +- Horizontal: ─ +- Vertical: │ +- Corners: ā”Œ ┐ ā”” ā”˜ + +### double +Double-line border for emphasis: +- Horizontal: ═ +- Vertical: ā•‘ +- Corners: ā•” ā•— ā•š ā• + +### rounded +Single-line border with rounded corners for a softer appearance: +- Horizontal: ─ +- Vertical: │ +- Corners: ā•­ ā•® ā•° ╯ + +### heavy +Bold/thick border for strong emphasis: +- Horizontal: ━ +- Vertical: ā”ƒ +- Corners: ā” ┓ ā”— ā”› + +## Examples + +```typescript +// Basic single border +const box1 = new BoxRenderable('box1', { + border: true, + borderStyle: 'single' +}); + +// Double border for important content +const dialog = new BoxRenderable('dialog', { + border: true, + borderStyle: 'double', + title: 'Confirm Action' +}); + +// Rounded border for friendly UI +const tooltip = new BoxRenderable('tooltip', { + border: true, + borderStyle: 'rounded', + padding: 1 +}); + +// Heavy border for critical alerts +const alert = new BoxRenderable('alert', { + border: true, + borderStyle: 'heavy', + borderColor: '#ff0000' +}); +``` + +## See Also + +- [BoxOptions](../interfaces/BoxOptions.md) - Box configuration options +- [BorderCharacters](../interfaces/BorderCharacters.md) - Custom border character definitions \ No newline at end of file diff --git a/packages/core/docs/api/reference/types/BoxDrawOptions.md b/packages/core/docs/api/reference/types/BoxDrawOptions.md new file mode 100644 index 00000000..f8a12762 --- /dev/null +++ b/packages/core/docs/api/reference/types/BoxDrawOptions.md @@ -0,0 +1,37 @@ +# BoxDrawOptions + +## Properties + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `backgroundColor` | `ColorInput` | āœ“ | | +| `border` | `boolean | array` | āœ“ | | +| `borderColor` | `ColorInput` | āœ“ | | +| `borderStyle` | `BorderStyle` | āœ“ | | +| `customBorderChars` | `BorderCharacters` | | | +| `height` | `number` | āœ“ | | +| `shouldFill` | `boolean` | | | +| `title` | `string` | | | +| `titleAlignment` | `string` | | | +| `width` | `number` | āœ“ | | +| `x` | `number` | āœ“ | | +| `y` | `number` | āœ“ | | + +## Example + +```typescript +const options: BoxDrawOptions = { + backgroundColor: undefined, + border: undefined, + borderColor: undefined, + borderStyle: undefined +}; +``` + +## Related Types + +- `BorderCharacters` +- `BorderSides` +- `BorderStyle` +- `ColorInput` +- `RGBA` diff --git a/packages/core/docs/api/reference/types/ConsoleOptions.md b/packages/core/docs/api/reference/types/ConsoleOptions.md new file mode 100644 index 00000000..ed68cc44 --- /dev/null +++ b/packages/core/docs/api/reference/types/ConsoleOptions.md @@ -0,0 +1,36 @@ +# ConsoleOptions + +## Properties + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `backgroundColor` | `ColorInput` | | | +| `colorDebug` | `ColorInput` | | | +| `colorDefault` | `ColorInput` | | | +| `colorError` | `ColorInput` | | | +| `colorInfo` | `ColorInput` | | | +| `colorWarn` | `ColorInput` | | | +| `cursorColor` | `ColorInput` | | | +| `maxDisplayLines` | `number` | | | +| `maxStoredLogs` | `number` | | | +| `position` | `ConsolePosition` | | | +| `sizePercent` | `number` | | | +| `startInDebugMode` | `boolean` | | | +| `title` | `string` | | | +| `titleBarColor` | `ColorInput` | | | +| `titleBarTextColor` | `ColorInput` | | | +| `zIndex` | `number` | | | + +## Example + +```typescript +const options: ConsoleOptions = { + +}; +``` + +## Related Types + +- `ColorInput` +- `ConsolePosition` +- `RGBA` diff --git a/packages/core/docs/api/reference/types/ExplosionEffectParameters.md b/packages/core/docs/api/reference/types/ExplosionEffectParameters.md new file mode 100644 index 00000000..4b9b5003 --- /dev/null +++ b/packages/core/docs/api/reference/types/ExplosionEffectParameters.md @@ -0,0 +1,35 @@ +# ExplosionEffectParameters + +## Properties + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `angularVelocityMax` | `Vector3` | āœ“ | | +| `angularVelocityMin` | `Vector3` | āœ“ | | +| `durationMs` | `number` | āœ“ | | +| `fadeOut` | `boolean` | āœ“ | | +| `gravity` | `number` | āœ“ | | +| `gravityScale` | `number` | āœ“ | | +| `initialVelocityYBoost` | `number` | āœ“ | | +| `materialFactory` | `any` | āœ“ | () => NodeMaterial | +| `numCols` | `number` | āœ“ | | +| `numRows` | `number` | āœ“ | | +| `strength` | `number` | āœ“ | | +| `strengthVariation` | `number` | āœ“ | | +| `zVariationStrength` | `number` | āœ“ | | + +## Example + +```typescript +const options: ExplosionEffectParameters = { + angularVelocityMax: undefined, + angularVelocityMin: undefined, + durationMs: 0, + fadeOut: false, + gravity: 0 +}; +``` + +## Related Types + +- `Vector3` diff --git a/packages/core/docs/api/reference/types/FrameBufferOptions.md b/packages/core/docs/api/reference/types/FrameBufferOptions.md new file mode 100644 index 00000000..6aaef55c --- /dev/null +++ b/packages/core/docs/api/reference/types/FrameBufferOptions.md @@ -0,0 +1,69 @@ +# FrameBufferOptions + +## Properties + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `alignItems` | `AlignString` | | | +| `bottom` | `number | string | string` | | | +| `buffered` | `boolean` | | | +| `enableLayout` | `boolean` | | | +| `flexBasis` | `number | string` | | | +| `flexDirection` | `FlexDirectionString` | | | +| `flexGrow` | `number` | | | +| `flexShrink` | `number` | | | +| `height` | `number` | āœ“ | | +| `justifyContent` | `JustifyString` | | | +| `left` | `number | string | string` | | | +| `live` | `boolean` | | | +| `margin` | `number | string | string` | | | +| `marginBottom` | `number | string | string` | | | +| `marginLeft` | `number | string | string` | | | +| `marginRight` | `number | string | string` | | | +| `marginTop` | `number | string | string` | | | +| `maxHeight` | `number` | | | +| `maxWidth` | `number` | | | +| `minHeight` | `number` | | | +| `minWidth` | `number` | | | +| `onKeyDown` | `object` | | (key: ParsedKey) => void | +| `onMouseDown` | `object` | | (event: MouseEvent) => void | +| `onMouseDrag` | `object` | | (event: MouseEvent) => void | +| `onMouseDragEnd` | `object` | | (event: MouseEvent) => void | +| `onMouseDrop` | `object` | | (event: MouseEvent) => void | +| `onMouseMove` | `object` | | (event: MouseEvent) => void | +| `onMouseOut` | `object` | | (event: MouseEvent) => void | +| `onMouseOver` | `object` | | (event: MouseEvent) => void | +| `onMouseScroll` | `object` | | (event: MouseEvent) => void | +| `onMouseUp` | `object` | | (event: MouseEvent) => void | +| `padding` | `number | string` | | | +| `paddingBottom` | `number | string` | | | +| `paddingLeft` | `number | string` | | | +| `paddingRight` | `number | string` | | | +| `paddingTop` | `number | string` | | | +| `position` | `PositionTypeString` | | | +| `respectAlpha` | `boolean` | | | +| `right` | `number | string | string` | | | +| `top` | `number | string | string` | | | +| `visible` | `boolean` | | | +| `width` | `number` | āœ“ | | +| `zIndex` | `number` | | | + +## Example + +```typescript +const options: FrameBufferOptions = { + +}; +``` + +## Related Types + +- `AlignString` +- `FlexDirectionString` +- `JustifyString` +- `MouseEvent` +- `MouseEventType` +- `ParsedKey` +- `PositionTypeString` +- `Renderable` +- `ScrollInfo` diff --git a/packages/core/docs/api/reference/types/MouseEventType.md b/packages/core/docs/api/reference/types/MouseEventType.md new file mode 100644 index 00000000..3b8503ec --- /dev/null +++ b/packages/core/docs/api/reference/types/MouseEventType.md @@ -0,0 +1,118 @@ +# MouseEventType + +Enumeration of all mouse event types supported by OpenTUI. + +## Type Definition + +```typescript +type MouseEventType = + | 'down' + | 'up' + | 'move' + | 'drag' + | 'drag-end' + | 'drop' + | 'over' + | 'out' + | 'scroll'; +``` + +## Values + +### down +Mouse button pressed down. Triggered when user presses any mouse button. + +### up +Mouse button released. Triggered when user releases a pressed mouse button. + +### move +Mouse cursor moved without any buttons pressed. Used for hover effects. + +### drag +Mouse moved while button is held down. Enables drag operations. + +### drag-end +Drag operation completed. Fired when mouse button is released after dragging. + +### drop +Item dropped onto a target. Fired on drop target when drag-end occurs over it. + +### over +Mouse cursor entered a component's bounds. Used for hover states. + +### out +Mouse cursor left a component's bounds. Used to clear hover states. + +### scroll +Mouse wheel scrolled. Includes scroll direction and delta information. + +## Examples + +```typescript +// Handle different mouse events +renderable.onMouseDown = (event: MouseEvent) => { + if (event.type === 'down' && event.button === 0) { + console.log('Left button pressed'); + } +}; + +renderable.onMouseMove = (event: MouseEvent) => { + if (event.type === 'move') { + updateHoverPosition(event.x, event.y); + } +}; + +renderable.onMouseDrag = (event: MouseEvent) => { + if (event.type === 'drag') { + updateDragPosition(event.x, event.y); + } +}; + +renderable.onMouseScroll = (event: MouseEvent) => { + if (event.type === 'scroll') { + if (event.scroll.direction === 'up') { + scrollUp(event.scroll.delta); + } else { + scrollDown(event.scroll.delta); + } + } +}; + +// Complete drag and drop implementation +class DraggableBox extends BoxRenderable { + private dragging = false; + private dragOffset = { x: 0, y: 0 }; + + constructor(id: string, options: BoxOptions) { + super(id, { + ...options, + onMouseDown: (event) => { + if (event.type === 'down') { + this.dragging = true; + this.dragOffset = { + x: event.x - this.x, + y: event.y - this.y + }; + } + }, + onMouseDrag: (event) => { + if (event.type === 'drag' && this.dragging) { + this.x = event.x - this.dragOffset.x; + this.y = event.y - this.dragOffset.y; + this.needsUpdate(); + } + }, + onMouseDragEnd: (event) => { + if (event.type === 'drag-end') { + this.dragging = false; + } + } + }); + } +} +``` + +## See Also + +- [MouseEvent](../classes/MouseEvent.md) - Mouse event class +- [Renderable](../classes/Renderable.md) - Base class handling mouse events \ No newline at end of file diff --git a/packages/core/docs/api/reference/types/Renderable.class.md b/packages/core/docs/api/reference/types/Renderable.class.md new file mode 100644 index 00000000..6bf196ca --- /dev/null +++ b/packages/core/docs/api/reference/types/Renderable.class.md @@ -0,0 +1,22 @@ +# Renderable.class + +## Properties + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `id` | `string` | āœ“ | | +| `num` | `number` | āœ“ | | +| `parent` | `Renderable | null` | āœ“ | | +| `selectable` | `boolean` | āœ“ | | + +## Example + +```typescript +const options: Renderable.class = { + id: "example", + num: 0, + parent: undefined, + selectable: false +}; +``` + diff --git a/packages/core/docs/api/reference/types/SelectRenderableOptions.md b/packages/core/docs/api/reference/types/SelectRenderableOptions.md new file mode 100644 index 00000000..15d0209c --- /dev/null +++ b/packages/core/docs/api/reference/types/SelectRenderableOptions.md @@ -0,0 +1,86 @@ +# SelectRenderableOptions + +## Properties + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `alignItems` | `AlignString` | | | +| `backgroundColor` | `ColorInput` | | | +| `bottom` | `number | string | string` | | | +| `buffered` | `boolean` | | | +| `descriptionColor` | `ColorInput` | | | +| `enableLayout` | `boolean` | | | +| `fastScrollStep` | `number` | | | +| `flexBasis` | `number | string` | | | +| `flexDirection` | `FlexDirectionString` | | | +| `flexGrow` | `number` | | | +| `flexShrink` | `number` | | | +| `focusedBackgroundColor` | `ColorInput` | | | +| `focusedTextColor` | `ColorInput` | | | +| `font` | `string` | | | +| `height` | `number | string | string` | | | +| `itemSpacing` | `number` | | | +| `justifyContent` | `JustifyString` | | | +| `left` | `number | string | string` | | | +| `live` | `boolean` | | | +| `margin` | `number | string | string` | | | +| `marginBottom` | `number | string | string` | | | +| `marginLeft` | `number | string | string` | | | +| `marginRight` | `number | string | string` | | | +| `marginTop` | `number | string | string` | | | +| `maxHeight` | `number` | | | +| `maxWidth` | `number` | | | +| `minHeight` | `number` | | | +| `minWidth` | `number` | | | +| `onKeyDown` | `object` | | (key: ParsedKey) => void | +| `onMouseDown` | `object` | | (event: MouseEvent) => void | +| `onMouseDrag` | `object` | | (event: MouseEvent) => void | +| `onMouseDragEnd` | `object` | | (event: MouseEvent) => void | +| `onMouseDrop` | `object` | | (event: MouseEvent) => void | +| `onMouseMove` | `object` | | (event: MouseEvent) => void | +| `onMouseOut` | `object` | | (event: MouseEvent) => void | +| `onMouseOver` | `object` | | (event: MouseEvent) => void | +| `onMouseScroll` | `object` | | (event: MouseEvent) => void | +| `onMouseUp` | `object` | | (event: MouseEvent) => void | +| `options` | `array` | | | +| `padding` | `number | string` | | | +| `paddingBottom` | `number | string` | | | +| `paddingLeft` | `number | string` | | | +| `paddingRight` | `number | string` | | | +| `paddingTop` | `number | string` | | | +| `position` | `PositionTypeString` | | | +| `right` | `number | string | string` | | | +| `selectedBackgroundColor` | `ColorInput` | | | +| `selectedDescriptionColor` | `ColorInput` | | | +| `selectedTextColor` | `ColorInput` | | | +| `showDescription` | `boolean` | | | +| `showScrollIndicator` | `boolean` | | | +| `textColor` | `ColorInput` | | | +| `top` | `number | string | string` | | | +| `visible` | `boolean` | | | +| `width` | `number | string | string` | | | +| `wrapSelection` | `boolean` | | | +| `zIndex` | `number` | | | + +## Example + +```typescript +const options: SelectRenderableOptions = { + +}; +``` + +## Related Types + +- `AlignString` +- `ColorInput` +- `FlexDirectionString` +- `JustifyString` +- `MouseEvent` +- `MouseEventType` +- `ParsedKey` +- `PositionTypeString` +- `RGBA` +- `Renderable` +- `ScrollInfo` +- `SelectOption` diff --git a/packages/core/docs/api/reference/types/TabSelectRenderableOptions.md b/packages/core/docs/api/reference/types/TabSelectRenderableOptions.md new file mode 100644 index 00000000..5b211322 --- /dev/null +++ b/packages/core/docs/api/reference/types/TabSelectRenderableOptions.md @@ -0,0 +1,84 @@ +# TabSelectRenderableOptions + +## Properties + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `alignItems` | `AlignString` | | | +| `backgroundColor` | `ColorInput` | | | +| `bottom` | `number | string | string` | | | +| `buffered` | `boolean` | | | +| `enableLayout` | `boolean` | | | +| `flexBasis` | `number | string` | | | +| `flexDirection` | `FlexDirectionString` | | | +| `flexGrow` | `number` | | | +| `flexShrink` | `number` | | | +| `focusedBackgroundColor` | `ColorInput` | | | +| `focusedTextColor` | `ColorInput` | | | +| `height` | `number` | | | +| `justifyContent` | `JustifyString` | | | +| `left` | `number | string | string` | | | +| `live` | `boolean` | | | +| `margin` | `number | string | string` | | | +| `marginBottom` | `number | string | string` | | | +| `marginLeft` | `number | string | string` | | | +| `marginRight` | `number | string | string` | | | +| `marginTop` | `number | string | string` | | | +| `maxHeight` | `number` | | | +| `maxWidth` | `number` | | | +| `minHeight` | `number` | | | +| `minWidth` | `number` | | | +| `onKeyDown` | `object` | | (key: ParsedKey) => void | +| `onMouseDown` | `object` | | (event: MouseEvent) => void | +| `onMouseDrag` | `object` | | (event: MouseEvent) => void | +| `onMouseDragEnd` | `object` | | (event: MouseEvent) => void | +| `onMouseDrop` | `object` | | (event: MouseEvent) => void | +| `onMouseMove` | `object` | | (event: MouseEvent) => void | +| `onMouseOut` | `object` | | (event: MouseEvent) => void | +| `onMouseOver` | `object` | | (event: MouseEvent) => void | +| `onMouseScroll` | `object` | | (event: MouseEvent) => void | +| `onMouseUp` | `object` | | (event: MouseEvent) => void | +| `options` | `array` | | | +| `padding` | `number | string` | | | +| `paddingBottom` | `number | string` | | | +| `paddingLeft` | `number | string` | | | +| `paddingRight` | `number | string` | | | +| `paddingTop` | `number | string` | | | +| `position` | `PositionTypeString` | | | +| `right` | `number | string | string` | | | +| `selectedBackgroundColor` | `ColorInput` | | | +| `selectedDescriptionColor` | `ColorInput` | | | +| `selectedTextColor` | `ColorInput` | | | +| `showDescription` | `boolean` | | | +| `showScrollArrows` | `boolean` | | | +| `showUnderline` | `boolean` | | | +| `tabWidth` | `number` | | | +| `textColor` | `ColorInput` | | | +| `top` | `number | string | string` | | | +| `visible` | `boolean` | | | +| `width` | `number | string | string` | | | +| `wrapSelection` | `boolean` | | | +| `zIndex` | `number` | | | + +## Example + +```typescript +const options: TabSelectRenderableOptions = { + +}; +``` + +## Related Types + +- `AlignString` +- `ColorInput` +- `FlexDirectionString` +- `JustifyString` +- `MouseEvent` +- `MouseEventType` +- `ParsedKey` +- `PositionTypeString` +- `RGBA` +- `Renderable` +- `ScrollInfo` +- `TabSelectOption` diff --git a/packages/core/docs/api/reference/types/ThreeCliRendererOptions.md b/packages/core/docs/api/reference/types/ThreeCliRendererOptions.md new file mode 100644 index 00000000..e6016062 --- /dev/null +++ b/packages/core/docs/api/reference/types/ThreeCliRendererOptions.md @@ -0,0 +1,27 @@ +# ThreeCliRendererOptions + +## Properties + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `alpha` | `boolean` | | | +| `autoResize` | `boolean` | | | +| `backgroundColor` | `RGBA` | | | +| `focalLength` | `number` | | | +| `height` | `number` | āœ“ | | +| `libPath` | `string` | | | +| `superSample` | `SuperSampleType` | | | +| `width` | `number` | āœ“ | | + +## Example + +```typescript +const options: ThreeCliRendererOptions = { + height: 0 +}; +``` + +## Related Types + +- `RGBA` +- `SuperSampleType` diff --git a/packages/core/docs/api/schemas/ASCIIFontOptions.json b/packages/core/docs/api/schemas/ASCIIFontOptions.json new file mode 100644 index 00000000..94176121 --- /dev/null +++ b/packages/core/docs/api/schemas/ASCIIFontOptions.json @@ -0,0 +1,745 @@ +{ + "$ref": "#/definitions/ASCIIFontOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "ASCIIFontOptions": { + "additionalProperties": false, + "properties": { + "alignItems": { + "$ref": "#/definitions/AlignString" + }, + "bg": { + "$ref": "#/definitions/RGBA" + }, + "bottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "buffered": { + "type": "boolean" + }, + "enableLayout": { + "type": "boolean" + }, + "fg": { + "anyOf": [ + { + "$ref": "#/definitions/RGBA" + }, + { + "items": { + "$ref": "#/definitions/RGBA" + }, + "type": "array" + } + ] + }, + "flexBasis": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + } + ] + }, + "flexDirection": { + "$ref": "#/definitions/FlexDirectionString" + }, + "flexGrow": { + "type": "number" + }, + "flexShrink": { + "type": "number" + }, + "font": { + "enum": [ + "tiny", + "block", + "shade", + "slick" + ], + "type": "string" + }, + "height": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "justifyContent": { + "$ref": "#/definitions/JustifyString" + }, + "left": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "live": { + "type": "boolean" + }, + "margin": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginBottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginLeft": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginRight": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginTop": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "maxHeight": { + "type": "number" + }, + "maxWidth": { + "type": "number" + }, + "minHeight": { + "type": "number" + }, + "minWidth": { + "type": "number" + }, + "onKeyDown": { + "$comment": "(key: ParsedKey) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "key": { + "$ref": "#/definitions/ParsedKey" + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDown": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrag": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDragEnd": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrop": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseMove": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOut": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOver": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseScroll": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseUp": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "padding": { + "type": [ + "number", + "string" + ] + }, + "paddingBottom": { + "type": [ + "number", + "string" + ] + }, + "paddingLeft": { + "type": [ + "number", + "string" + ] + }, + "paddingRight": { + "type": [ + "number", + "string" + ] + }, + "paddingTop": { + "type": [ + "number", + "string" + ] + }, + "position": { + "$ref": "#/definitions/PositionTypeString" + }, + "right": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "selectable": { + "type": "boolean" + }, + "selectionBg": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "selectionFg": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "text": { + "type": "string" + }, + "top": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "visible": { + "type": "boolean" + }, + "width": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "zIndex": { + "type": "number" + } + }, + "type": "object" + }, + "AlignString": { + "enum": [ + "auto", + "flex-start", + "center", + "flex-end", + "stretch", + "baseline", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "FlexDirectionString": { + "enum": [ + "column", + "column-reverse", + "row", + "row-reverse" + ], + "type": "string" + }, + "JustifyString": { + "enum": [ + "flex-start", + "center", + "flex-end", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "MouseEvent": { + "additionalProperties": false, + "properties": { + "button": { + "type": "number" + }, + "modifiers": { + "additionalProperties": false, + "properties": { + "alt": { + "type": "boolean" + }, + "ctrl": { + "type": "boolean" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "shift", + "alt", + "ctrl" + ], + "type": "object" + }, + "scroll": { + "$ref": "#/definitions/ScrollInfo" + }, + "source": { + "$ref": "#/definitions/Renderable" + }, + "target": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "type": { + "$ref": "#/definitions/MouseEventType" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "type", + "button", + "x", + "y", + "modifiers", + "target" + ], + "type": "object" + }, + "MouseEventType": { + "enum": [ + "down", + "up", + "move", + "drag", + "drag-end", + "drop", + "over", + "out", + "scroll" + ], + "type": "string" + }, + "ParsedKey": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "ctrl": { + "type": "boolean" + }, + "meta": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "number": { + "type": "boolean" + }, + "option": { + "type": "boolean" + }, + "raw": { + "type": "string" + }, + "sequence": { + "type": "string" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "name", + "ctrl", + "meta", + "shift", + "option", + "sequence", + "number", + "raw" + ], + "type": "object" + }, + "PositionTypeString": { + "enum": [ + "static", + "relative", + "absolute" + ], + "type": "string" + }, + "RGBA": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + } + }, + "required": [ + "buffer" + ], + "type": "object" + }, + "Renderable": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "num": { + "type": "number" + }, + "parent": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "selectable": { + "type": "boolean" + } + }, + "required": [ + "id", + "num", + "selectable", + "parent" + ], + "type": "object" + }, + "ScrollInfo": { + "additionalProperties": false, + "properties": { + "delta": { + "type": "number" + }, + "direction": { + "enum": [ + "up", + "down", + "left", + "right" + ], + "type": "string" + } + }, + "required": [ + "direction", + "delta" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/AnimationOptions.json b/packages/core/docs/api/schemas/AnimationOptions.json new file mode 100644 index 00000000..36fa7d86 --- /dev/null +++ b/packages/core/docs/api/schemas/AnimationOptions.json @@ -0,0 +1,108 @@ +{ + "$ref": "#/definitions/AnimationOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "AnimationOptions": { + "properties": { + "alternate": { + "type": "boolean" + }, + "duration": { + "type": "number" + }, + "ease": { + "$ref": "#/definitions/EasingFunctions" + }, + "loop": { + "type": [ + "boolean", + "number" + ] + }, + "loopDelay": { + "type": "number" + }, + "onComplete": { + "$comment": "() => void" + }, + "onLoop": { + "$comment": "() => void" + }, + "onStart": { + "$comment": "() => void" + }, + "onUpdate": { + "$comment": "(animation: JSAnimation) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "animation": { + "$ref": "#/definitions/JSAnimation" + } + }, + "required": [ + "animation" + ], + "type": "object" + } + }, + "type": "object" + }, + "once": { + "type": "boolean" + } + }, + "required": [ + "duration" + ], + "type": "object" + }, + "EasingFunctions": { + "enum": [ + "linear", + "inQuad", + "outQuad", + "inOutQuad", + "inExpo", + "outExpo", + "inOutSine", + "outBounce", + "outElastic", + "inBounce", + "inCirc", + "outCirc", + "inOutCirc", + "inBack", + "outBack", + "inOutBack" + ], + "type": "string" + }, + "JSAnimation": { + "additionalProperties": false, + "properties": { + "currentTime": { + "type": "number" + }, + "deltaTime": { + "type": "number" + }, + "progress": { + "type": "number" + }, + "targets": { + "items": {}, + "type": "array" + } + }, + "required": [ + "targets", + "deltaTime", + "progress", + "currentTime" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/BorderConfig.json b/packages/core/docs/api/schemas/BorderConfig.json new file mode 100644 index 00000000..4c197fb0 --- /dev/null +++ b/packages/core/docs/api/schemas/BorderConfig.json @@ -0,0 +1,166 @@ +{ + "$ref": "#/definitions/BorderConfig", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "BorderCharacters": { + "additionalProperties": false, + "properties": { + "bottomLeft": { + "type": "string" + }, + "bottomRight": { + "type": "string" + }, + "bottomT": { + "type": "string" + }, + "cross": { + "type": "string" + }, + "horizontal": { + "type": "string" + }, + "leftT": { + "type": "string" + }, + "rightT": { + "type": "string" + }, + "topLeft": { + "type": "string" + }, + "topRight": { + "type": "string" + }, + "topT": { + "type": "string" + }, + "vertical": { + "type": "string" + } + }, + "required": [ + "topLeft", + "topRight", + "bottomLeft", + "bottomRight", + "horizontal", + "vertical", + "topT", + "bottomT", + "leftT", + "rightT", + "cross" + ], + "type": "object" + }, + "BorderConfig": { + "additionalProperties": false, + "properties": { + "border": { + "anyOf": [ + { + "type": "boolean" + }, + { + "items": { + "$ref": "#/definitions/BorderSides" + }, + "type": "array" + } + ] + }, + "borderColor": { + "$ref": "#/definitions/ColorInput" + }, + "borderStyle": { + "$ref": "#/definitions/BorderStyle" + }, + "customBorderChars": { + "$ref": "#/definitions/BorderCharacters" + } + }, + "required": [ + "borderStyle", + "border" + ], + "type": "object" + }, + "BorderSides": { + "enum": [ + "top", + "right", + "bottom", + "left" + ], + "type": "string" + }, + "BorderStyle": { + "enum": [ + "single", + "double", + "rounded", + "heavy" + ], + "type": "string" + }, + "ColorInput": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "RGBA": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/BoxDrawOptions.json b/packages/core/docs/api/schemas/BoxDrawOptions.json new file mode 100644 index 00000000..24fdf218 --- /dev/null +++ b/packages/core/docs/api/schemas/BoxDrawOptions.json @@ -0,0 +1,201 @@ +{ + "$ref": "#/definitions/BoxDrawOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "BorderCharacters": { + "additionalProperties": false, + "properties": { + "bottomLeft": { + "type": "string" + }, + "bottomRight": { + "type": "string" + }, + "bottomT": { + "type": "string" + }, + "cross": { + "type": "string" + }, + "horizontal": { + "type": "string" + }, + "leftT": { + "type": "string" + }, + "rightT": { + "type": "string" + }, + "topLeft": { + "type": "string" + }, + "topRight": { + "type": "string" + }, + "topT": { + "type": "string" + }, + "vertical": { + "type": "string" + } + }, + "required": [ + "topLeft", + "topRight", + "bottomLeft", + "bottomRight", + "horizontal", + "vertical", + "topT", + "bottomT", + "leftT", + "rightT", + "cross" + ], + "type": "object" + }, + "BorderSides": { + "enum": [ + "top", + "right", + "bottom", + "left" + ], + "type": "string" + }, + "BorderStyle": { + "enum": [ + "single", + "double", + "rounded", + "heavy" + ], + "type": "string" + }, + "BoxDrawOptions": { + "additionalProperties": false, + "properties": { + "backgroundColor": { + "$ref": "#/definitions/ColorInput" + }, + "border": { + "anyOf": [ + { + "type": "boolean" + }, + { + "items": { + "$ref": "#/definitions/BorderSides" + }, + "type": "array" + } + ] + }, + "borderColor": { + "$ref": "#/definitions/ColorInput" + }, + "borderStyle": { + "$ref": "#/definitions/BorderStyle" + }, + "customBorderChars": { + "$ref": "#/definitions/BorderCharacters" + }, + "height": { + "type": "number" + }, + "shouldFill": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "titleAlignment": { + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "width": { + "type": "number" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y", + "width", + "height", + "borderStyle", + "border", + "borderColor", + "backgroundColor" + ], + "type": "object" + }, + "ColorInput": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "RGBA": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/BoxOptions.json b/packages/core/docs/api/schemas/BoxOptions.json new file mode 100644 index 00000000..09721428 --- /dev/null +++ b/packages/core/docs/api/schemas/BoxOptions.json @@ -0,0 +1,830 @@ +{ + "$ref": "#/definitions/BoxOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "AlignString": { + "enum": [ + "auto", + "flex-start", + "center", + "flex-end", + "stretch", + "baseline", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "BorderCharacters": { + "additionalProperties": false, + "properties": { + "bottomLeft": { + "type": "string" + }, + "bottomRight": { + "type": "string" + }, + "bottomT": { + "type": "string" + }, + "cross": { + "type": "string" + }, + "horizontal": { + "type": "string" + }, + "leftT": { + "type": "string" + }, + "rightT": { + "type": "string" + }, + "topLeft": { + "type": "string" + }, + "topRight": { + "type": "string" + }, + "topT": { + "type": "string" + }, + "vertical": { + "type": "string" + } + }, + "required": [ + "topLeft", + "topRight", + "bottomLeft", + "bottomRight", + "horizontal", + "vertical", + "topT", + "bottomT", + "leftT", + "rightT", + "cross" + ], + "type": "object" + }, + "BorderSides": { + "enum": [ + "top", + "right", + "bottom", + "left" + ], + "type": "string" + }, + "BorderStyle": { + "enum": [ + "single", + "double", + "rounded", + "heavy" + ], + "type": "string" + }, + "BoxOptions": { + "additionalProperties": false, + "properties": { + "alignItems": { + "$ref": "#/definitions/AlignString" + }, + "backgroundColor": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "border": { + "anyOf": [ + { + "type": "boolean" + }, + { + "items": { + "$ref": "#/definitions/BorderSides" + }, + "type": "array" + } + ] + }, + "borderColor": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "borderStyle": { + "$ref": "#/definitions/BorderStyle" + }, + "bottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "buffered": { + "type": "boolean" + }, + "customBorderChars": { + "$ref": "#/definitions/BorderCharacters" + }, + "enableLayout": { + "type": "boolean" + }, + "flexBasis": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + } + ] + }, + "flexDirection": { + "$ref": "#/definitions/FlexDirectionString" + }, + "flexGrow": { + "type": "number" + }, + "flexShrink": { + "type": "number" + }, + "focusedBorderColor": { + "$ref": "#/definitions/ColorInput" + }, + "height": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "justifyContent": { + "$ref": "#/definitions/JustifyString" + }, + "left": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "live": { + "type": "boolean" + }, + "margin": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginBottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginLeft": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginRight": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginTop": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "maxHeight": { + "type": "number" + }, + "maxWidth": { + "type": "number" + }, + "minHeight": { + "type": "number" + }, + "minWidth": { + "type": "number" + }, + "onKeyDown": { + "$comment": "(key: ParsedKey) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "key": { + "$ref": "#/definitions/ParsedKey" + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDown": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrag": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDragEnd": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrop": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseMove": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOut": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOver": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseScroll": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseUp": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "padding": { + "type": [ + "number", + "string" + ] + }, + "paddingBottom": { + "type": [ + "number", + "string" + ] + }, + "paddingLeft": { + "type": [ + "number", + "string" + ] + }, + "paddingRight": { + "type": [ + "number", + "string" + ] + }, + "paddingTop": { + "type": [ + "number", + "string" + ] + }, + "position": { + "$ref": "#/definitions/PositionTypeString" + }, + "right": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "shouldFill": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "titleAlignment": { + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "top": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "visible": { + "type": "boolean" + }, + "width": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "zIndex": { + "type": "number" + } + }, + "type": "object" + }, + "ColorInput": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "FlexDirectionString": { + "enum": [ + "column", + "column-reverse", + "row", + "row-reverse" + ], + "type": "string" + }, + "JustifyString": { + "enum": [ + "flex-start", + "center", + "flex-end", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "MouseEvent": { + "additionalProperties": false, + "properties": { + "button": { + "type": "number" + }, + "modifiers": { + "additionalProperties": false, + "properties": { + "alt": { + "type": "boolean" + }, + "ctrl": { + "type": "boolean" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "shift", + "alt", + "ctrl" + ], + "type": "object" + }, + "scroll": { + "$ref": "#/definitions/ScrollInfo" + }, + "source": { + "$ref": "#/definitions/Renderable" + }, + "target": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "type": { + "$ref": "#/definitions/MouseEventType" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "type", + "button", + "x", + "y", + "modifiers", + "target" + ], + "type": "object" + }, + "MouseEventType": { + "enum": [ + "down", + "up", + "move", + "drag", + "drag-end", + "drop", + "over", + "out", + "scroll" + ], + "type": "string" + }, + "ParsedKey": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "ctrl": { + "type": "boolean" + }, + "meta": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "number": { + "type": "boolean" + }, + "option": { + "type": "boolean" + }, + "raw": { + "type": "string" + }, + "sequence": { + "type": "string" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "name", + "ctrl", + "meta", + "shift", + "option", + "sequence", + "number", + "raw" + ], + "type": "object" + }, + "PositionTypeString": { + "enum": [ + "static", + "relative", + "absolute" + ], + "type": "string" + }, + "RGBA": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + } + }, + "required": [ + "buffer" + ], + "type": "object" + }, + "Renderable": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "num": { + "type": "number" + }, + "parent": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "selectable": { + "type": "boolean" + } + }, + "required": [ + "id", + "num", + "selectable", + "parent" + ], + "type": "object" + }, + "ScrollInfo": { + "additionalProperties": false, + "properties": { + "delta": { + "type": "number" + }, + "direction": { + "enum": [ + "up", + "down", + "left", + "right" + ], + "type": "string" + } + }, + "required": [ + "direction", + "delta" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/CliRendererConfig.json b/packages/core/docs/api/schemas/CliRendererConfig.json new file mode 100644 index 00000000..56aebbe4 --- /dev/null +++ b/packages/core/docs/api/schemas/CliRendererConfig.json @@ -0,0 +1,2332 @@ +{ + "$ref": "#/definitions/CliRendererConfig", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "CliRendererConfig": { + "additionalProperties": false, + "properties": { + "consoleOptions": { + "$ref": "#/definitions/ConsoleOptions" + }, + "debounceDelay": { + "type": "number" + }, + "enableMouseMovement": { + "type": "boolean" + }, + "exitOnCtrlC": { + "type": "boolean" + }, + "experimental_splitHeight": { + "type": "number" + }, + "gatherStats": { + "type": "boolean" + }, + "maxStatSamples": { + "type": "number" + }, + "memorySnapshotInterval": { + "type": "number" + }, + "postProcessFns": { + "items": { + "$comment": "(buffer: OptimizedBuffer, deltaTime: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/OptimizedBuffer" + }, + "deltaTime": { + "type": "number" + } + }, + "required": [ + "buffer", + "deltaTime" + ], + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + }, + "stdin": { + "$ref": "#/definitions/global.NodeJS.ReadStream" + }, + "stdout": { + "$ref": "#/definitions/global.NodeJS.WriteStream" + }, + "targetFps": { + "type": "number" + }, + "useAlternateScreen": { + "type": "boolean" + }, + "useConsole": { + "type": "boolean" + }, + "useMouse": { + "type": "boolean" + }, + "useThread": { + "type": "boolean" + } + }, + "type": "object" + }, + "ColorInput": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "ConsoleOptions": { + "additionalProperties": false, + "properties": { + "backgroundColor": { + "$ref": "#/definitions/ColorInput" + }, + "colorDebug": { + "$ref": "#/definitions/ColorInput" + }, + "colorDefault": { + "$ref": "#/definitions/ColorInput" + }, + "colorError": { + "$ref": "#/definitions/ColorInput" + }, + "colorInfo": { + "$ref": "#/definitions/ColorInput" + }, + "colorWarn": { + "$ref": "#/definitions/ColorInput" + }, + "cursorColor": { + "$ref": "#/definitions/ColorInput" + }, + "maxDisplayLines": { + "type": "number" + }, + "maxStoredLogs": { + "type": "number" + }, + "position": { + "$ref": "#/definitions/ConsolePosition" + }, + "sizePercent": { + "type": "number" + }, + "startInDebugMode": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "titleBarColor": { + "$ref": "#/definitions/ColorInput" + }, + "titleBarTextColor": { + "$ref": "#/definitions/ColorInput" + }, + "zIndex": { + "type": "number" + } + }, + "type": "object" + }, + "ConsolePosition": { + "enum": [ + "top", + "bottom", + "left", + "right" + ], + "type": "string" + }, + "CursorStyle": { + "enum": [ + "block", + "line", + "underline" + ], + "type": "string" + }, + "DebugOverlayCorner": { + "enum": [ + 0, + 1, + 2, + 3 + ], + "type": "number" + }, + "OptimizedBuffer": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "lib": { + "$ref": "#/definitions/RenderLib" + }, + "respectAlpha": { + "type": "boolean" + } + }, + "required": [ + "id", + "lib", + "respectAlpha" + ], + "type": "object" + }, + "Pointer": { + "type": "number" + }, + "RGBA": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + } + }, + "required": [ + "buffer" + ], + "type": "object" + }, + "RenderLib": { + "additionalProperties": false, + "properties": { + "addToHitGrid": { + "$comment": "(renderer: Pointer, x: number, y: number, width: number, height: number, id: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "height": { + "type": "number" + }, + "id": { + "type": "number" + }, + "renderer": { + "$ref": "#/definitions/Pointer" + }, + "width": { + "type": "number" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "renderer", + "x", + "y", + "width", + "height", + "id" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferClear": { + "$comment": "(buffer: Pointer, color: RGBA) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "color": { + "$ref": "#/definitions/RGBA" + } + }, + "required": [ + "buffer", + "color" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferDrawBox": { + "$comment": "(\n buffer: Pointer,\n x: number,\n y: number,\n width: number,\n height: number,\n borderChars: Uint32Array,\n packedOptions: number,\n borderColor: RGBA,\n backgroundColor: RGBA,\n title: string | null) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "backgroundColor": { + "$ref": "#/definitions/RGBA" + }, + "borderChars": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + }, + "borderColor": { + "$ref": "#/definitions/RGBA" + }, + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "height": { + "type": "number" + }, + "packedOptions": { + "type": "number" + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "width": { + "type": "number" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "buffer", + "x", + "y", + "width", + "height", + "borderChars", + "packedOptions", + "borderColor", + "backgroundColor", + "title" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferDrawPackedBuffer": { + "$comment": "(\n buffer: Pointer,\n dataPtr: Pointer,\n dataLen: number,\n posX: number,\n posY: number,\n terminalWidthCells: number,\n terminalHeightCells: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "dataLen": { + "type": "number" + }, + "dataPtr": { + "$ref": "#/definitions/Pointer" + }, + "posX": { + "type": "number" + }, + "posY": { + "type": "number" + }, + "terminalHeightCells": { + "type": "number" + }, + "terminalWidthCells": { + "type": "number" + } + }, + "required": [ + "buffer", + "dataPtr", + "dataLen", + "posX", + "posY", + "terminalWidthCells", + "terminalHeightCells" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferDrawSuperSampleBuffer": { + "$comment": "(\n buffer: Pointer,\n x: number,\n y: number,\n pixelDataPtr: Pointer,\n pixelDataLength: number,\n format: \"bgra8unorm\" | \"rgba8unorm\",\n alignedBytesPerRow: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "alignedBytesPerRow": { + "type": "number" + }, + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "format": { + "enum": [ + "bgra8unorm", + "rgba8unorm" + ], + "type": "string" + }, + "pixelDataLength": { + "type": "number" + }, + "pixelDataPtr": { + "$ref": "#/definitions/Pointer" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "buffer", + "x", + "y", + "pixelDataPtr", + "pixelDataLength", + "format", + "alignedBytesPerRow" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferDrawText": { + "$comment": "(\n buffer: Pointer,\n text: string,\n x: number,\n y: number,\n color: RGBA,\n bgColor?: RGBA,\n attributes?: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "attributes": { + "type": "number" + }, + "bgColor": { + "$ref": "#/definitions/RGBA" + }, + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "color": { + "$ref": "#/definitions/RGBA" + }, + "text": { + "type": "string" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "buffer", + "text", + "x", + "y", + "color" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferDrawTextBuffer": { + "$comment": "(\n buffer: Pointer,\n textBuffer: Pointer,\n x: number,\n y: number,\n clipRect?: { x: number; y: number; width: number; height: number }) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "clipRect": { + "additionalProperties": false, + "properties": { + "height": { + "type": "number" + }, + "width": { + "type": "number" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y", + "width", + "height" + ], + "type": "object" + }, + "textBuffer": { + "$ref": "#/definitions/Pointer" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "buffer", + "textBuffer", + "x", + "y" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferFillRect": { + "$comment": "(buffer: Pointer, x: number, y: number, width: number, height: number, color: RGBA) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "color": { + "$ref": "#/definitions/RGBA" + }, + "height": { + "type": "number" + }, + "width": { + "type": "number" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "buffer", + "x", + "y", + "width", + "height", + "color" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferGetAttributesPtr": { + "$comment": "(buffer: Pointer) => Pointer", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferGetBgPtr": { + "$comment": "(buffer: Pointer) => Pointer", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferGetCharPtr": { + "$comment": "(buffer: Pointer) => Pointer", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferGetFgPtr": { + "$comment": "(buffer: Pointer) => Pointer", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferGetRespectAlpha": { + "$comment": "(buffer: Pointer) => boolean", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferResize": { + "$comment": "(\n buffer: Pointer,\n width: number,\n height: number) => {\n char: Uint32Array\n fg: Float32Array\n bg: Float32Array\n attributes: Uint8Array\n }", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "height": { + "type": "number" + }, + "width": { + "type": "number" + } + }, + "required": [ + "buffer", + "width", + "height" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferSetCellWithAlphaBlending": { + "$comment": "(\n buffer: Pointer,\n x: number,\n y: number,\n char: string,\n color: RGBA,\n bgColor: RGBA,\n attributes?: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "attributes": { + "type": "number" + }, + "bgColor": { + "$ref": "#/definitions/RGBA" + }, + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "char": { + "type": "string" + }, + "color": { + "$ref": "#/definitions/RGBA" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "buffer", + "x", + "y", + "char", + "color", + "bgColor" + ], + "type": "object" + } + }, + "type": "object" + }, + "bufferSetRespectAlpha": { + "$comment": "(buffer: Pointer, respectAlpha: boolean) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "respectAlpha": { + "type": "boolean" + } + }, + "required": [ + "buffer", + "respectAlpha" + ], + "type": "object" + } + }, + "type": "object" + }, + "checkHit": { + "$comment": "(renderer: Pointer, x: number, y: number) => number", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "renderer": { + "$ref": "#/definitions/Pointer" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "renderer", + "x", + "y" + ], + "type": "object" + } + }, + "type": "object" + }, + "clearTerminal": { + "$comment": "(renderer: Pointer) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "renderer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "renderer" + ], + "type": "object" + } + }, + "type": "object" + }, + "createOptimizedBuffer": { + "$comment": "(width: number, height: number, respectAlpha?: boolean) => OptimizedBuffer", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "height": { + "type": "number" + }, + "respectAlpha": { + "type": "boolean" + }, + "width": { + "type": "number" + } + }, + "required": [ + "width", + "height" + ], + "type": "object" + } + }, + "type": "object" + }, + "createRenderer": { + "$comment": "(width: number, height: number) => Pointer | null", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "height": { + "type": "number" + }, + "width": { + "type": "number" + } + }, + "required": [ + "width", + "height" + ], + "type": "object" + } + }, + "type": "object" + }, + "createTextBuffer": { + "$comment": "(capacity: number) => TextBuffer", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "capacity": { + "type": "number" + } + }, + "required": [ + "capacity" + ], + "type": "object" + } + }, + "type": "object" + }, + "destroyOptimizedBuffer": { + "$comment": "(bufferPtr: Pointer) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "bufferPtr": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "bufferPtr" + ], + "type": "object" + } + }, + "type": "object" + }, + "destroyRenderer": { + "$comment": "(renderer: Pointer, useAlternateScreen: boolean, splitHeight: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "renderer": { + "$ref": "#/definitions/Pointer" + }, + "splitHeight": { + "type": "number" + }, + "useAlternateScreen": { + "type": "boolean" + } + }, + "required": [ + "renderer", + "useAlternateScreen", + "splitHeight" + ], + "type": "object" + } + }, + "type": "object" + }, + "destroyTextBuffer": { + "$comment": "(buffer: Pointer) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "disableMouse": { + "$comment": "(renderer: Pointer) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "renderer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "renderer" + ], + "type": "object" + } + }, + "type": "object" + }, + "drawFrameBuffer": { + "$comment": "(\n targetBufferPtr: Pointer,\n destX: number,\n destY: number,\n bufferPtr: Pointer,\n sourceX?: number,\n sourceY?: number,\n sourceWidth?: number,\n sourceHeight?: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "bufferPtr": { + "$ref": "#/definitions/Pointer" + }, + "destX": { + "type": "number" + }, + "destY": { + "type": "number" + }, + "sourceHeight": { + "type": "number" + }, + "sourceWidth": { + "type": "number" + }, + "sourceX": { + "type": "number" + }, + "sourceY": { + "type": "number" + }, + "targetBufferPtr": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "targetBufferPtr", + "destX", + "destY", + "bufferPtr" + ], + "type": "object" + } + }, + "type": "object" + }, + "dumpBuffers": { + "$comment": "(renderer: Pointer, timestamp?: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "renderer": { + "$ref": "#/definitions/Pointer" + }, + "timestamp": { + "type": "number" + } + }, + "required": [ + "renderer" + ], + "type": "object" + } + }, + "type": "object" + }, + "dumpHitGrid": { + "$comment": "(renderer: Pointer) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "renderer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "renderer" + ], + "type": "object" + } + }, + "type": "object" + }, + "dumpStdoutBuffer": { + "$comment": "(renderer: Pointer, timestamp?: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "renderer": { + "$ref": "#/definitions/Pointer" + }, + "timestamp": { + "type": "number" + } + }, + "required": [ + "renderer" + ], + "type": "object" + } + }, + "type": "object" + }, + "enableMouse": { + "$comment": "(renderer: Pointer, enableMovement: boolean) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "enableMovement": { + "type": "boolean" + }, + "renderer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "renderer", + "enableMovement" + ], + "type": "object" + } + }, + "type": "object" + }, + "getBufferHeight": { + "$comment": "(buffer: Pointer) => number", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "getBufferWidth": { + "$comment": "(buffer: Pointer) => number", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "getCurrentBuffer": { + "$comment": "(renderer: Pointer) => OptimizedBuffer", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "renderer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "renderer" + ], + "type": "object" + } + }, + "type": "object" + }, + "getNextBuffer": { + "$comment": "(renderer: Pointer) => OptimizedBuffer", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "renderer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "renderer" + ], + "type": "object" + } + }, + "type": "object" + }, + "getTextBufferArrays": { + "$comment": "(\n buffer: Pointer,\n size: number) => {\n char: Uint32Array\n fg: Float32Array\n bg: Float32Array\n attributes: Uint16Array\n }", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "size": { + "type": "number" + } + }, + "required": [ + "buffer", + "size" + ], + "type": "object" + } + }, + "type": "object" + }, + "render": { + "$comment": "(renderer: Pointer, force: boolean) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "force": { + "type": "boolean" + }, + "renderer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "renderer", + "force" + ], + "type": "object" + } + }, + "type": "object" + }, + "resizeRenderer": { + "$comment": "(renderer: Pointer, width: number, height: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "height": { + "type": "number" + }, + "renderer": { + "$ref": "#/definitions/Pointer" + }, + "width": { + "type": "number" + } + }, + "required": [ + "renderer", + "width", + "height" + ], + "type": "object" + } + }, + "type": "object" + }, + "setBackgroundColor": { + "$comment": "(renderer: Pointer, color: RGBA) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "color": { + "$ref": "#/definitions/RGBA" + }, + "renderer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "renderer", + "color" + ], + "type": "object" + } + }, + "type": "object" + }, + "setCursorColor": { + "$comment": "(color: RGBA) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "color": { + "$ref": "#/definitions/RGBA" + } + }, + "required": [ + "color" + ], + "type": "object" + } + }, + "type": "object" + }, + "setCursorPosition": { + "$comment": "(x: number, y: number, visible: boolean) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "visible": { + "type": "boolean" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y", + "visible" + ], + "type": "object" + } + }, + "type": "object" + }, + "setCursorStyle": { + "$comment": "(style: CursorStyle, blinking: boolean) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "blinking": { + "type": "boolean" + }, + "style": { + "$ref": "#/definitions/CursorStyle" + } + }, + "required": [ + "style", + "blinking" + ], + "type": "object" + } + }, + "type": "object" + }, + "setDebugOverlay": { + "$comment": "(renderer: Pointer, enabled: boolean, corner: DebugOverlayCorner) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "corner": { + "$ref": "#/definitions/DebugOverlayCorner" + }, + "enabled": { + "type": "boolean" + }, + "renderer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "renderer", + "enabled", + "corner" + ], + "type": "object" + } + }, + "type": "object" + }, + "setRenderOffset": { + "$comment": "(renderer: Pointer, offset: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "offset": { + "type": "number" + }, + "renderer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "renderer", + "offset" + ], + "type": "object" + } + }, + "type": "object" + }, + "setUseThread": { + "$comment": "(renderer: Pointer, useThread: boolean) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "renderer": { + "$ref": "#/definitions/Pointer" + }, + "useThread": { + "type": "boolean" + } + }, + "required": [ + "renderer", + "useThread" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferConcat": { + "$comment": "(buffer1: Pointer, buffer2: Pointer) => TextBuffer", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer1": { + "$ref": "#/definitions/Pointer" + }, + "buffer2": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer1", + "buffer2" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferFinalizeLineInfo": { + "$comment": "(buffer: Pointer) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferGetAttributesPtr": { + "$comment": "(buffer: Pointer) => Pointer", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferGetBgPtr": { + "$comment": "(buffer: Pointer) => Pointer", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferGetCapacity": { + "$comment": "(buffer: Pointer) => number", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferGetCharPtr": { + "$comment": "(buffer: Pointer) => Pointer", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferGetFgPtr": { + "$comment": "(buffer: Pointer) => Pointer", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferGetLength": { + "$comment": "(buffer: Pointer) => number", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferGetLineInfo": { + "$comment": "(buffer: Pointer) => { lineStarts: number[]; lineWidths: number[] }", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferReset": { + "$comment": "(buffer: Pointer) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferResetDefaults": { + "$comment": "(buffer: Pointer) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferResetSelection": { + "$comment": "(buffer: Pointer) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferResize": { + "$comment": "(\n buffer: Pointer,\n newLength: number) => {\n char: Uint32Array\n fg: Float32Array\n bg: Float32Array\n attributes: Uint16Array\n }", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "newLength": { + "type": "number" + } + }, + "required": [ + "buffer", + "newLength" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferSetCell": { + "$comment": "(\n buffer: Pointer,\n index: number,\n char: number,\n fg: Float32Array,\n bg: Float32Array,\n attr: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "attr": { + "type": "number" + }, + "bg": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + }, + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "char": { + "type": "number" + }, + "fg": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + }, + "index": { + "type": "number" + } + }, + "required": [ + "buffer", + "index", + "char", + "fg", + "bg", + "attr" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferSetDefaultAttributes": { + "$comment": "(buffer: Pointer, attributes: number | null) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "attributes": { + "type": [ + "number", + "null" + ] + }, + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer", + "attributes" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferSetDefaultBg": { + "$comment": "(buffer: Pointer, bg: RGBA | null) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "bg": { + "anyOf": [ + { + "$ref": "#/definitions/RGBA" + }, + { + "type": "null" + } + ] + }, + "buffer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "buffer", + "bg" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferSetDefaultFg": { + "$comment": "(buffer: Pointer, fg: RGBA | null) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "fg": { + "anyOf": [ + { + "$ref": "#/definitions/RGBA" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "buffer", + "fg" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferSetSelection": { + "$comment": "(\n buffer: Pointer,\n start: number,\n end: number,\n bgColor: RGBA | null,\n fgColor: RGBA | null) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "bgColor": { + "anyOf": [ + { + "$ref": "#/definitions/RGBA" + }, + { + "type": "null" + } + ] + }, + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "end": { + "type": "number" + }, + "fgColor": { + "anyOf": [ + { + "$ref": "#/definitions/RGBA" + }, + { + "type": "null" + } + ] + }, + "start": { + "type": "number" + } + }, + "required": [ + "buffer", + "start", + "end", + "bgColor", + "fgColor" + ], + "type": "object" + } + }, + "type": "object" + }, + "textBufferWriteChunk": { + "$comment": "(\n buffer: Pointer,\n textBytes: Uint8Array,\n fg: RGBA | null,\n bg: RGBA | null,\n attributes: number | null) => number", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "attributes": { + "type": [ + "number", + "null" + ] + }, + "bg": { + "anyOf": [ + { + "$ref": "#/definitions/RGBA" + }, + { + "type": "null" + } + ] + }, + "buffer": { + "$ref": "#/definitions/Pointer" + }, + "fg": { + "anyOf": [ + { + "$ref": "#/definitions/RGBA" + }, + { + "type": "null" + } + ] + }, + "textBytes": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + } + }, + "required": [ + "buffer", + "textBytes", + "fg", + "bg", + "attributes" + ], + "type": "object" + } + }, + "type": "object" + }, + "updateMemoryStats": { + "$comment": "(renderer: Pointer, heapUsed: number, heapTotal: number, arrayBuffers: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "arrayBuffers": { + "type": "number" + }, + "heapTotal": { + "type": "number" + }, + "heapUsed": { + "type": "number" + }, + "renderer": { + "$ref": "#/definitions/Pointer" + } + }, + "required": [ + "renderer", + "heapUsed", + "heapTotal", + "arrayBuffers" + ], + "type": "object" + } + }, + "type": "object" + }, + "updateStats": { + "$comment": "(renderer: Pointer, time: number, fps: number, frameCallbackTime: number) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "fps": { + "type": "number" + }, + "frameCallbackTime": { + "type": "number" + }, + "renderer": { + "$ref": "#/definitions/Pointer" + }, + "time": { + "type": "number" + } + }, + "required": [ + "renderer", + "time", + "fps", + "frameCallbackTime" + ], + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "createRenderer", + "destroyRenderer", + "setUseThread", + "setBackgroundColor", + "setRenderOffset", + "updateStats", + "updateMemoryStats", + "render", + "getNextBuffer", + "getCurrentBuffer", + "createOptimizedBuffer", + "destroyOptimizedBuffer", + "drawFrameBuffer", + "getBufferWidth", + "getBufferHeight", + "bufferClear", + "bufferGetCharPtr", + "bufferGetFgPtr", + "bufferGetBgPtr", + "bufferGetAttributesPtr", + "bufferGetRespectAlpha", + "bufferSetRespectAlpha", + "bufferDrawText", + "bufferSetCellWithAlphaBlending", + "bufferFillRect", + "bufferDrawSuperSampleBuffer", + "bufferDrawPackedBuffer", + "bufferDrawBox", + "bufferResize", + "resizeRenderer", + "setCursorPosition", + "setCursorStyle", + "setCursorColor", + "setDebugOverlay", + "clearTerminal", + "addToHitGrid", + "checkHit", + "dumpHitGrid", + "dumpBuffers", + "dumpStdoutBuffer", + "enableMouse", + "disableMouse", + "createTextBuffer", + "destroyTextBuffer", + "textBufferGetCharPtr", + "textBufferGetFgPtr", + "textBufferGetBgPtr", + "textBufferGetAttributesPtr", + "textBufferGetLength", + "textBufferSetCell", + "textBufferConcat", + "textBufferResize", + "textBufferReset", + "textBufferSetSelection", + "textBufferResetSelection", + "textBufferSetDefaultFg", + "textBufferSetDefaultBg", + "textBufferSetDefaultAttributes", + "textBufferResetDefaults", + "textBufferWriteChunk", + "textBufferGetCapacity", + "textBufferFinalizeLineInfo", + "textBufferGetLineInfo", + "getTextBufferArrays", + "bufferDrawTextBuffer" + ], + "type": "object" + }, + "SocketReadyState": { + "enum": [ + "opening", + "open", + "readOnly", + "writeOnly", + "closed" + ], + "type": "string" + }, + "global.NodeJS.ReadStream": { + "additionalProperties": false, + "properties": { + "allowHalfOpen": { + "description": "If `false` then the stream will automatically end the writable side when the readable side ends. Set initially by the `allowHalfOpen` constructor option, which defaults to `true`.\n\nThis can be changed manually to change the half-open behavior of an existing `Duplex` stream instance, but must be changed before the `'end'` event is emitted.", + "type": "boolean" + }, + "autoSelectFamilyAttemptedAddresses": { + "description": "This property is only present if the family autoselection algorithm is enabled in `socket.connect(options)` and it is an array of the addresses that have been attempted.\n\nEach address is a string in the form of `$IP:$PORT`. If the connection was successful, then the last address is the one that the socket is currently connected to.", + "items": { + "type": "string" + }, + "type": "array" + }, + "bufferSize": { + "deprecated": "Since v14.6.0 - Use `writableLength` instead.", + "description": "This property shows the number of characters buffered for writing. The buffer may contain strings whose length after encoding is not yet known. So this number is only an approximation of the number of bytes in the buffer.\n\n`net.Socket` has the property that `socket.write()` always works. This is to help users get up and running quickly. The computer cannot always keep up with the amount of data that is written to a socket. The network connection simply might be too slow. Node.js will internally queue up the data written to a socket and send it out over the wire when it is possible.\n\nThe consequence of this internal buffering is that memory may grow. Users who experience large or growing `bufferSize` should attempt to \"throttle\" the data flows in their program with `socket.pause()` and `socket.resume()`.", + "type": "number" + }, + "bytesRead": { + "description": "The amount of received bytes.", + "type": "number" + }, + "bytesWritten": { + "description": "The amount of bytes sent.", + "type": "number" + }, + "connecting": { + "description": "If `true`, `socket.connect(options[, connectListener])` was called and has not yet finished. It will stay `true` until the socket becomes connected, then it is set to `false` and the `'connect'` event is emitted. Note that the `socket.connect(options[, connectListener])` callback is a listener for the `'connect'` event.", + "type": "boolean" + }, + "destroyed": { + "description": "See `writable.destroyed` for further details.", + "type": "boolean" + }, + "isRaw": { + "description": "A `boolean` that is `true` if the TTY is currently configured to operate as a raw device.\n\nThis flag is always `false` when a process starts, even if the terminal is operating in raw mode. Its value will change with subsequent calls to `setRawMode`.", + "type": "boolean" + }, + "isTTY": { + "description": "A `boolean` that is always `true` for `tty.ReadStream` instances.", + "type": "boolean" + }, + "localAddress": { + "description": "The string representation of the local IP address the remote client is connecting on. For example, in a server listening on `'0.0.0.0'`, if a client connects on `'192.168.1.1'`, the value of `socket.localAddress` would be`'192.168.1.1'`.", + "type": "string" + }, + "localFamily": { + "description": "The string representation of the local IP family. `'IPv4'` or `'IPv6'`.", + "type": "string" + }, + "localPort": { + "description": "The numeric representation of the local port. For example, `80` or `21`.", + "type": "number" + }, + "pending": { + "description": "This is `true` if the socket is not connected yet, either because `.connect()`has not yet been called or because it is still in the process of connecting (see `socket.connecting`).", + "type": "boolean" + }, + "readable": { + "type": "boolean" + }, + "readyState": { + "$ref": "#/definitions/SocketReadyState", + "description": "This property represents the state of the connection as a string.\n\n* If the stream is connecting `socket.readyState` is `opening`.\n* If the stream is readable and writable, it is `open`.\n* If the stream is readable and not writable, it is `readOnly`.\n* If the stream is not readable and writable, it is `writeOnly`." + }, + "remoteAddress": { + "description": "The string representation of the remote IP address. For example,`'74.125.127.100'` or `'2001:4860:a005::68'`. Value may be `undefined` if the socket is destroyed (for example, if the client disconnected).", + "type": "string" + }, + "remoteFamily": { + "description": "The string representation of the remote IP family. `'IPv4'` or `'IPv6'`. Value may be `undefined` if the socket is destroyed (for example, if the client disconnected).", + "type": "string" + }, + "remotePort": { + "description": "The numeric representation of the remote port. For example, `80` or `21`. Value may be `undefined` if the socket is destroyed (for example, if the client disconnected).", + "type": "number" + }, + "timeout": { + "description": "The socket timeout in milliseconds as set by `socket.setTimeout()`. It is `undefined` if a timeout has not been set.", + "type": "number" + }, + "writable": { + "type": "boolean" + } + }, + "required": [ + "allowHalfOpen", + "autoSelectFamilyAttemptedAddresses", + "bufferSize", + "bytesRead", + "bytesWritten", + "connecting", + "destroyed", + "isRaw", + "isTTY", + "pending", + "readable", + "readyState", + "writable" + ], + "type": "object" + }, + "global.NodeJS.WriteStream": { + "additionalProperties": false, + "properties": { + "allowHalfOpen": { + "description": "If `false` then the stream will automatically end the writable side when the readable side ends. Set initially by the `allowHalfOpen` constructor option, which defaults to `true`.\n\nThis can be changed manually to change the half-open behavior of an existing `Duplex` stream instance, but must be changed before the `'end'` event is emitted.", + "type": "boolean" + }, + "autoSelectFamilyAttemptedAddresses": { + "description": "This property is only present if the family autoselection algorithm is enabled in `socket.connect(options)` and it is an array of the addresses that have been attempted.\n\nEach address is a string in the form of `$IP:$PORT`. If the connection was successful, then the last address is the one that the socket is currently connected to.", + "items": { + "type": "string" + }, + "type": "array" + }, + "bufferSize": { + "deprecated": "Since v14.6.0 - Use `writableLength` instead.", + "description": "This property shows the number of characters buffered for writing. The buffer may contain strings whose length after encoding is not yet known. So this number is only an approximation of the number of bytes in the buffer.\n\n`net.Socket` has the property that `socket.write()` always works. This is to help users get up and running quickly. The computer cannot always keep up with the amount of data that is written to a socket. The network connection simply might be too slow. Node.js will internally queue up the data written to a socket and send it out over the wire when it is possible.\n\nThe consequence of this internal buffering is that memory may grow. Users who experience large or growing `bufferSize` should attempt to \"throttle\" the data flows in their program with `socket.pause()` and `socket.resume()`.", + "type": "number" + }, + "bytesRead": { + "description": "The amount of received bytes.", + "type": "number" + }, + "bytesWritten": { + "description": "The amount of bytes sent.", + "type": "number" + }, + "columns": { + "description": "A `number` specifying the number of columns the TTY currently has. This property is updated whenever the `'resize'` event is emitted.", + "type": "number" + }, + "connecting": { + "description": "If `true`, `socket.connect(options[, connectListener])` was called and has not yet finished. It will stay `true` until the socket becomes connected, then it is set to `false` and the `'connect'` event is emitted. Note that the `socket.connect(options[, connectListener])` callback is a listener for the `'connect'` event.", + "type": "boolean" + }, + "destroyed": { + "description": "See `writable.destroyed` for further details.", + "type": "boolean" + }, + "isTTY": { + "description": "A `boolean` that is always `true`.", + "type": "boolean" + }, + "localAddress": { + "description": "The string representation of the local IP address the remote client is connecting on. For example, in a server listening on `'0.0.0.0'`, if a client connects on `'192.168.1.1'`, the value of `socket.localAddress` would be`'192.168.1.1'`.", + "type": "string" + }, + "localFamily": { + "description": "The string representation of the local IP family. `'IPv4'` or `'IPv6'`.", + "type": "string" + }, + "localPort": { + "description": "The numeric representation of the local port. For example, `80` or `21`.", + "type": "number" + }, + "pending": { + "description": "This is `true` if the socket is not connected yet, either because `.connect()`has not yet been called or because it is still in the process of connecting (see `socket.connecting`).", + "type": "boolean" + }, + "readable": { + "type": "boolean" + }, + "readyState": { + "$ref": "#/definitions/SocketReadyState", + "description": "This property represents the state of the connection as a string.\n\n* If the stream is connecting `socket.readyState` is `opening`.\n* If the stream is readable and writable, it is `open`.\n* If the stream is readable and not writable, it is `readOnly`.\n* If the stream is not readable and writable, it is `writeOnly`." + }, + "remoteAddress": { + "description": "The string representation of the remote IP address. For example,`'74.125.127.100'` or `'2001:4860:a005::68'`. Value may be `undefined` if the socket is destroyed (for example, if the client disconnected).", + "type": "string" + }, + "remoteFamily": { + "description": "The string representation of the remote IP family. `'IPv4'` or `'IPv6'`. Value may be `undefined` if the socket is destroyed (for example, if the client disconnected).", + "type": "string" + }, + "remotePort": { + "description": "The numeric representation of the remote port. For example, `80` or `21`. Value may be `undefined` if the socket is destroyed (for example, if the client disconnected).", + "type": "number" + }, + "rows": { + "description": "A `number` specifying the number of rows the TTY currently has. This property is updated whenever the `'resize'` event is emitted.", + "type": "number" + }, + "timeout": { + "description": "The socket timeout in milliseconds as set by `socket.setTimeout()`. It is `undefined` if a timeout has not been set.", + "type": "number" + }, + "writable": { + "type": "boolean" + } + }, + "required": [ + "allowHalfOpen", + "autoSelectFamilyAttemptedAddresses", + "bufferSize", + "bytesRead", + "bytesWritten", + "columns", + "connecting", + "destroyed", + "isTTY", + "pending", + "readable", + "readyState", + "rows", + "writable" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/ConsoleOptions.json b/packages/core/docs/api/schemas/ConsoleOptions.json new file mode 100644 index 00000000..b2e9febb --- /dev/null +++ b/packages/core/docs/api/schemas/ConsoleOptions.json @@ -0,0 +1,127 @@ +{ + "$ref": "#/definitions/ConsoleOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "ColorInput": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "ConsoleOptions": { + "additionalProperties": false, + "properties": { + "backgroundColor": { + "$ref": "#/definitions/ColorInput" + }, + "colorDebug": { + "$ref": "#/definitions/ColorInput" + }, + "colorDefault": { + "$ref": "#/definitions/ColorInput" + }, + "colorError": { + "$ref": "#/definitions/ColorInput" + }, + "colorInfo": { + "$ref": "#/definitions/ColorInput" + }, + "colorWarn": { + "$ref": "#/definitions/ColorInput" + }, + "cursorColor": { + "$ref": "#/definitions/ColorInput" + }, + "maxDisplayLines": { + "type": "number" + }, + "maxStoredLogs": { + "type": "number" + }, + "position": { + "$ref": "#/definitions/ConsolePosition" + }, + "sizePercent": { + "type": "number" + }, + "startInDebugMode": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "titleBarColor": { + "$ref": "#/definitions/ColorInput" + }, + "titleBarTextColor": { + "$ref": "#/definitions/ColorInput" + }, + "zIndex": { + "type": "number" + } + }, + "type": "object" + }, + "ConsolePosition": { + "enum": [ + "top", + "bottom", + "left", + "right" + ], + "type": "string" + }, + "RGBA": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + } + }, + "required": [ + "buffer" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/ExplosionEffectParameters.json b/packages/core/docs/api/schemas/ExplosionEffectParameters.json new file mode 100644 index 00000000..b372a6ba --- /dev/null +++ b/packages/core/docs/api/schemas/ExplosionEffectParameters.json @@ -0,0 +1,95 @@ +{ + "$ref": "#/definitions/ExplosionEffectParameters", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "ExplosionEffectParameters": { + "additionalProperties": false, + "properties": { + "angularVelocityMax": { + "$ref": "#/definitions/Vector3" + }, + "angularVelocityMin": { + "$ref": "#/definitions/Vector3" + }, + "durationMs": { + "type": "number" + }, + "fadeOut": { + "type": "boolean" + }, + "gravity": { + "type": "number" + }, + "gravityScale": { + "type": "number" + }, + "initialVelocityYBoost": { + "type": "number" + }, + "materialFactory": { + "$comment": "() => NodeMaterial" + }, + "numCols": { + "type": "number" + }, + "numRows": { + "type": "number" + }, + "strength": { + "type": "number" + }, + "strengthVariation": { + "type": "number" + }, + "zVariationStrength": { + "type": "number" + } + }, + "required": [ + "numRows", + "numCols", + "durationMs", + "strength", + "strengthVariation", + "gravity", + "gravityScale", + "fadeOut", + "angularVelocityMin", + "angularVelocityMax", + "initialVelocityYBoost", + "zVariationStrength", + "materialFactory" + ], + "type": "object" + }, + "Vector3": { + "additionalProperties": false, + "description": "3D vector.\n\nsee {@link https://github.com/mrdoob/three.js/blob/master/src/math/Vector3.js }", + "properties": { + "isVector3": { + "const": true, + "type": "boolean" + }, + "x": { + "default": 0, + "type": "number" + }, + "y": { + "default": 0, + "type": "number" + }, + "z": { + "default": 0, + "type": "number" + } + }, + "required": [ + "x", + "y", + "z", + "isVector3" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/FrameBufferOptions.json b/packages/core/docs/api/schemas/FrameBufferOptions.json new file mode 100644 index 00000000..0a970864 --- /dev/null +++ b/packages/core/docs/api/schemas/FrameBufferOptions.json @@ -0,0 +1,631 @@ +{ + "$ref": "#/definitions/FrameBufferOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "AlignString": { + "enum": [ + "auto", + "flex-start", + "center", + "flex-end", + "stretch", + "baseline", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "FlexDirectionString": { + "enum": [ + "column", + "column-reverse", + "row", + "row-reverse" + ], + "type": "string" + }, + "FrameBufferOptions": { + "additionalProperties": false, + "properties": { + "alignItems": { + "$ref": "#/definitions/AlignString" + }, + "bottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "buffered": { + "type": "boolean" + }, + "enableLayout": { + "type": "boolean" + }, + "flexBasis": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + } + ] + }, + "flexDirection": { + "$ref": "#/definitions/FlexDirectionString" + }, + "flexGrow": { + "type": "number" + }, + "flexShrink": { + "type": "number" + }, + "height": { + "type": "number" + }, + "justifyContent": { + "$ref": "#/definitions/JustifyString" + }, + "left": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "live": { + "type": "boolean" + }, + "margin": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginBottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginLeft": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginRight": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginTop": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "maxHeight": { + "type": "number" + }, + "maxWidth": { + "type": "number" + }, + "minHeight": { + "type": "number" + }, + "minWidth": { + "type": "number" + }, + "onKeyDown": { + "$comment": "(key: ParsedKey) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "key": { + "$ref": "#/definitions/ParsedKey" + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDown": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrag": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDragEnd": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrop": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseMove": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOut": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOver": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseScroll": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseUp": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "padding": { + "type": [ + "number", + "string" + ] + }, + "paddingBottom": { + "type": [ + "number", + "string" + ] + }, + "paddingLeft": { + "type": [ + "number", + "string" + ] + }, + "paddingRight": { + "type": [ + "number", + "string" + ] + }, + "paddingTop": { + "type": [ + "number", + "string" + ] + }, + "position": { + "$ref": "#/definitions/PositionTypeString" + }, + "respectAlpha": { + "type": "boolean" + }, + "right": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "top": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "visible": { + "type": "boolean" + }, + "width": { + "type": "number" + }, + "zIndex": { + "type": "number" + } + }, + "required": [ + "width", + "height" + ], + "type": "object" + }, + "JustifyString": { + "enum": [ + "flex-start", + "center", + "flex-end", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "MouseEvent": { + "additionalProperties": false, + "properties": { + "button": { + "type": "number" + }, + "modifiers": { + "additionalProperties": false, + "properties": { + "alt": { + "type": "boolean" + }, + "ctrl": { + "type": "boolean" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "shift", + "alt", + "ctrl" + ], + "type": "object" + }, + "scroll": { + "$ref": "#/definitions/ScrollInfo" + }, + "source": { + "$ref": "#/definitions/Renderable" + }, + "target": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "type": { + "$ref": "#/definitions/MouseEventType" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "type", + "button", + "x", + "y", + "modifiers", + "target" + ], + "type": "object" + }, + "MouseEventType": { + "enum": [ + "down", + "up", + "move", + "drag", + "drag-end", + "drop", + "over", + "out", + "scroll" + ], + "type": "string" + }, + "ParsedKey": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "ctrl": { + "type": "boolean" + }, + "meta": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "number": { + "type": "boolean" + }, + "option": { + "type": "boolean" + }, + "raw": { + "type": "string" + }, + "sequence": { + "type": "string" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "name", + "ctrl", + "meta", + "shift", + "option", + "sequence", + "number", + "raw" + ], + "type": "object" + }, + "PositionTypeString": { + "enum": [ + "static", + "relative", + "absolute" + ], + "type": "string" + }, + "Renderable": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "num": { + "type": "number" + }, + "parent": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "selectable": { + "type": "boolean" + } + }, + "required": [ + "id", + "num", + "selectable", + "parent" + ], + "type": "object" + }, + "ScrollInfo": { + "additionalProperties": false, + "properties": { + "delta": { + "type": "number" + }, + "direction": { + "enum": [ + "up", + "down", + "left", + "right" + ], + "type": "string" + } + }, + "required": [ + "direction", + "delta" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/InputRenderableOptions.json b/packages/core/docs/api/schemas/InputRenderableOptions.json new file mode 100644 index 00000000..476ea392 --- /dev/null +++ b/packages/core/docs/api/schemas/InputRenderableOptions.json @@ -0,0 +1,731 @@ +{ + "$ref": "#/definitions/InputRenderableOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "AlignString": { + "enum": [ + "auto", + "flex-start", + "center", + "flex-end", + "stretch", + "baseline", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "ColorInput": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "FlexDirectionString": { + "enum": [ + "column", + "column-reverse", + "row", + "row-reverse" + ], + "type": "string" + }, + "InputRenderableOptions": { + "additionalProperties": false, + "properties": { + "alignItems": { + "$ref": "#/definitions/AlignString" + }, + "backgroundColor": { + "$ref": "#/definitions/ColorInput" + }, + "bottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "buffered": { + "type": "boolean" + }, + "cursorColor": { + "$ref": "#/definitions/ColorInput" + }, + "enableLayout": { + "type": "boolean" + }, + "flexBasis": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + } + ] + }, + "flexDirection": { + "$ref": "#/definitions/FlexDirectionString" + }, + "flexGrow": { + "type": "number" + }, + "flexShrink": { + "type": "number" + }, + "focusedBackgroundColor": { + "$ref": "#/definitions/ColorInput" + }, + "focusedTextColor": { + "$ref": "#/definitions/ColorInput" + }, + "height": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "justifyContent": { + "$ref": "#/definitions/JustifyString" + }, + "left": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "live": { + "type": "boolean" + }, + "margin": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginBottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginLeft": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginRight": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginTop": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "maxHeight": { + "type": "number" + }, + "maxLength": { + "type": "number" + }, + "maxWidth": { + "type": "number" + }, + "minHeight": { + "type": "number" + }, + "minWidth": { + "type": "number" + }, + "onKeyDown": { + "$comment": "(key: ParsedKey) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "key": { + "$ref": "#/definitions/ParsedKey" + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDown": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrag": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDragEnd": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrop": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseMove": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOut": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOver": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseScroll": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseUp": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "padding": { + "type": [ + "number", + "string" + ] + }, + "paddingBottom": { + "type": [ + "number", + "string" + ] + }, + "paddingLeft": { + "type": [ + "number", + "string" + ] + }, + "paddingRight": { + "type": [ + "number", + "string" + ] + }, + "paddingTop": { + "type": [ + "number", + "string" + ] + }, + "placeholder": { + "type": "string" + }, + "placeholderColor": { + "$ref": "#/definitions/ColorInput" + }, + "position": { + "$ref": "#/definitions/PositionTypeString" + }, + "right": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "textColor": { + "$ref": "#/definitions/ColorInput" + }, + "top": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "value": { + "type": "string" + }, + "visible": { + "type": "boolean" + }, + "width": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "zIndex": { + "type": "number" + } + }, + "type": "object" + }, + "JustifyString": { + "enum": [ + "flex-start", + "center", + "flex-end", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "MouseEvent": { + "additionalProperties": false, + "properties": { + "button": { + "type": "number" + }, + "modifiers": { + "additionalProperties": false, + "properties": { + "alt": { + "type": "boolean" + }, + "ctrl": { + "type": "boolean" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "shift", + "alt", + "ctrl" + ], + "type": "object" + }, + "scroll": { + "$ref": "#/definitions/ScrollInfo" + }, + "source": { + "$ref": "#/definitions/Renderable" + }, + "target": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "type": { + "$ref": "#/definitions/MouseEventType" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "type", + "button", + "x", + "y", + "modifiers", + "target" + ], + "type": "object" + }, + "MouseEventType": { + "enum": [ + "down", + "up", + "move", + "drag", + "drag-end", + "drop", + "over", + "out", + "scroll" + ], + "type": "string" + }, + "ParsedKey": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "ctrl": { + "type": "boolean" + }, + "meta": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "number": { + "type": "boolean" + }, + "option": { + "type": "boolean" + }, + "raw": { + "type": "string" + }, + "sequence": { + "type": "string" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "name", + "ctrl", + "meta", + "shift", + "option", + "sequence", + "number", + "raw" + ], + "type": "object" + }, + "PositionTypeString": { + "enum": [ + "static", + "relative", + "absolute" + ], + "type": "string" + }, + "RGBA": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + } + }, + "required": [ + "buffer" + ], + "type": "object" + }, + "Renderable": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "num": { + "type": "number" + }, + "parent": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "selectable": { + "type": "boolean" + } + }, + "required": [ + "id", + "num", + "selectable", + "parent" + ], + "type": "object" + }, + "ScrollInfo": { + "additionalProperties": false, + "properties": { + "delta": { + "type": "number" + }, + "direction": { + "enum": [ + "up", + "down", + "left", + "right" + ], + "type": "string" + } + }, + "required": [ + "direction", + "delta" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/LayoutOptions.json b/packages/core/docs/api/schemas/LayoutOptions.json new file mode 100644 index 00000000..4aa08feb --- /dev/null +++ b/packages/core/docs/api/schemas/LayoutOptions.json @@ -0,0 +1,254 @@ +{ + "$ref": "#/definitions/LayoutOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "AlignString": { + "enum": [ + "auto", + "flex-start", + "center", + "flex-end", + "stretch", + "baseline", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "FlexDirectionString": { + "enum": [ + "column", + "column-reverse", + "row", + "row-reverse" + ], + "type": "string" + }, + "JustifyString": { + "enum": [ + "flex-start", + "center", + "flex-end", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "LayoutOptions": { + "additionalProperties": false, + "properties": { + "alignItems": { + "$ref": "#/definitions/AlignString" + }, + "bottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "enableLayout": { + "type": "boolean" + }, + "flexBasis": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + } + ] + }, + "flexDirection": { + "$ref": "#/definitions/FlexDirectionString" + }, + "flexGrow": { + "type": "number" + }, + "flexShrink": { + "type": "number" + }, + "justifyContent": { + "$ref": "#/definitions/JustifyString" + }, + "left": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "margin": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginBottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginLeft": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginRight": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginTop": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "maxHeight": { + "type": "number" + }, + "maxWidth": { + "type": "number" + }, + "minHeight": { + "type": "number" + }, + "minWidth": { + "type": "number" + }, + "padding": { + "type": [ + "number", + "string" + ] + }, + "paddingBottom": { + "type": [ + "number", + "string" + ] + }, + "paddingLeft": { + "type": [ + "number", + "string" + ] + }, + "paddingRight": { + "type": [ + "number", + "string" + ] + }, + "paddingTop": { + "type": [ + "number", + "string" + ] + }, + "position": { + "$ref": "#/definitions/PositionTypeString" + }, + "right": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "top": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + }, + "PositionTypeString": { + "enum": [ + "static", + "relative", + "absolute" + ], + "type": "string" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/Renderable.class.json b/packages/core/docs/api/schemas/Renderable.class.json new file mode 100644 index 00000000..a5f263ac --- /dev/null +++ b/packages/core/docs/api/schemas/Renderable.class.json @@ -0,0 +1,37 @@ +{ + "$ref": "#/definitions/Renderable", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "Renderable": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "num": { + "type": "number" + }, + "parent": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "selectable": { + "type": "boolean" + } + }, + "required": [ + "id", + "num", + "selectable", + "parent" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/RenderableOptions.json b/packages/core/docs/api/schemas/RenderableOptions.json new file mode 100644 index 00000000..358670ce --- /dev/null +++ b/packages/core/docs/api/schemas/RenderableOptions.json @@ -0,0 +1,646 @@ +{ + "$ref": "#/definitions/RenderableOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "AlignString": { + "enum": [ + "auto", + "flex-start", + "center", + "flex-end", + "stretch", + "baseline", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "FlexDirectionString": { + "enum": [ + "column", + "column-reverse", + "row", + "row-reverse" + ], + "type": "string" + }, + "JustifyString": { + "enum": [ + "flex-start", + "center", + "flex-end", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "MouseEvent": { + "additionalProperties": false, + "properties": { + "button": { + "type": "number" + }, + "modifiers": { + "additionalProperties": false, + "properties": { + "alt": { + "type": "boolean" + }, + "ctrl": { + "type": "boolean" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "shift", + "alt", + "ctrl" + ], + "type": "object" + }, + "scroll": { + "$ref": "#/definitions/ScrollInfo" + }, + "source": { + "$ref": "#/definitions/Renderable" + }, + "target": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "type": { + "$ref": "#/definitions/MouseEventType" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "type", + "button", + "x", + "y", + "modifiers", + "target" + ], + "type": "object" + }, + "MouseEventType": { + "enum": [ + "down", + "up", + "move", + "drag", + "drag-end", + "drop", + "over", + "out", + "scroll" + ], + "type": "string" + }, + "ParsedKey": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "ctrl": { + "type": "boolean" + }, + "meta": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "number": { + "type": "boolean" + }, + "option": { + "type": "boolean" + }, + "raw": { + "type": "string" + }, + "sequence": { + "type": "string" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "name", + "ctrl", + "meta", + "shift", + "option", + "sequence", + "number", + "raw" + ], + "type": "object" + }, + "PositionTypeString": { + "enum": [ + "static", + "relative", + "absolute" + ], + "type": "string" + }, + "Renderable": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "num": { + "type": "number" + }, + "parent": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "selectable": { + "type": "boolean" + } + }, + "required": [ + "id", + "num", + "selectable", + "parent" + ], + "type": "object" + }, + "RenderableOptions": { + "additionalProperties": false, + "properties": { + "alignItems": { + "$ref": "#/definitions/AlignString" + }, + "bottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "buffered": { + "type": "boolean" + }, + "enableLayout": { + "type": "boolean" + }, + "flexBasis": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + } + ] + }, + "flexDirection": { + "$ref": "#/definitions/FlexDirectionString" + }, + "flexGrow": { + "type": "number" + }, + "flexShrink": { + "type": "number" + }, + "height": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "justifyContent": { + "$ref": "#/definitions/JustifyString" + }, + "left": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "live": { + "type": "boolean" + }, + "margin": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginBottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginLeft": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginRight": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginTop": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "maxHeight": { + "type": "number" + }, + "maxWidth": { + "type": "number" + }, + "minHeight": { + "type": "number" + }, + "minWidth": { + "type": "number" + }, + "onKeyDown": { + "$comment": "(key: ParsedKey) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "key": { + "$ref": "#/definitions/ParsedKey" + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDown": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrag": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDragEnd": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrop": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseMove": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOut": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOver": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseScroll": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseUp": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "padding": { + "type": [ + "number", + "string" + ] + }, + "paddingBottom": { + "type": [ + "number", + "string" + ] + }, + "paddingLeft": { + "type": [ + "number", + "string" + ] + }, + "paddingRight": { + "type": [ + "number", + "string" + ] + }, + "paddingTop": { + "type": [ + "number", + "string" + ] + }, + "position": { + "$ref": "#/definitions/PositionTypeString" + }, + "right": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "top": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "visible": { + "type": "boolean" + }, + "width": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "zIndex": { + "type": "number" + } + }, + "type": "object" + }, + "ScrollInfo": { + "additionalProperties": false, + "properties": { + "delta": { + "type": "number" + }, + "direction": { + "enum": [ + "up", + "down", + "left", + "right" + ], + "type": "string" + } + }, + "required": [ + "direction", + "delta" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/SelectRenderableOptions.json b/packages/core/docs/api/schemas/SelectRenderableOptions.json new file mode 100644 index 00000000..81f3a2ab --- /dev/null +++ b/packages/core/docs/api/schemas/SelectRenderableOptions.json @@ -0,0 +1,775 @@ +{ + "$ref": "#/definitions/SelectRenderableOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "AlignString": { + "enum": [ + "auto", + "flex-start", + "center", + "flex-end", + "stretch", + "baseline", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "ColorInput": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "FlexDirectionString": { + "enum": [ + "column", + "column-reverse", + "row", + "row-reverse" + ], + "type": "string" + }, + "JustifyString": { + "enum": [ + "flex-start", + "center", + "flex-end", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "MouseEvent": { + "additionalProperties": false, + "properties": { + "button": { + "type": "number" + }, + "modifiers": { + "additionalProperties": false, + "properties": { + "alt": { + "type": "boolean" + }, + "ctrl": { + "type": "boolean" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "shift", + "alt", + "ctrl" + ], + "type": "object" + }, + "scroll": { + "$ref": "#/definitions/ScrollInfo" + }, + "source": { + "$ref": "#/definitions/Renderable" + }, + "target": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "type": { + "$ref": "#/definitions/MouseEventType" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "type", + "button", + "x", + "y", + "modifiers", + "target" + ], + "type": "object" + }, + "MouseEventType": { + "enum": [ + "down", + "up", + "move", + "drag", + "drag-end", + "drop", + "over", + "out", + "scroll" + ], + "type": "string" + }, + "ParsedKey": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "ctrl": { + "type": "boolean" + }, + "meta": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "number": { + "type": "boolean" + }, + "option": { + "type": "boolean" + }, + "raw": { + "type": "string" + }, + "sequence": { + "type": "string" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "name", + "ctrl", + "meta", + "shift", + "option", + "sequence", + "number", + "raw" + ], + "type": "object" + }, + "PositionTypeString": { + "enum": [ + "static", + "relative", + "absolute" + ], + "type": "string" + }, + "RGBA": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + } + }, + "required": [ + "buffer" + ], + "type": "object" + }, + "Renderable": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "num": { + "type": "number" + }, + "parent": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "selectable": { + "type": "boolean" + } + }, + "required": [ + "id", + "num", + "selectable", + "parent" + ], + "type": "object" + }, + "ScrollInfo": { + "additionalProperties": false, + "properties": { + "delta": { + "type": "number" + }, + "direction": { + "enum": [ + "up", + "down", + "left", + "right" + ], + "type": "string" + } + }, + "required": [ + "direction", + "delta" + ], + "type": "object" + }, + "SelectOption": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "value": {} + }, + "required": [ + "name", + "description" + ], + "type": "object" + }, + "SelectRenderableOptions": { + "additionalProperties": false, + "properties": { + "alignItems": { + "$ref": "#/definitions/AlignString" + }, + "backgroundColor": { + "$ref": "#/definitions/ColorInput" + }, + "bottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "buffered": { + "type": "boolean" + }, + "descriptionColor": { + "$ref": "#/definitions/ColorInput" + }, + "enableLayout": { + "type": "boolean" + }, + "fastScrollStep": { + "type": "number" + }, + "flexBasis": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + } + ] + }, + "flexDirection": { + "$ref": "#/definitions/FlexDirectionString" + }, + "flexGrow": { + "type": "number" + }, + "flexShrink": { + "type": "number" + }, + "focusedBackgroundColor": { + "$ref": "#/definitions/ColorInput" + }, + "focusedTextColor": { + "$ref": "#/definitions/ColorInput" + }, + "font": { + "enum": [ + "tiny", + "block", + "shade", + "slick" + ], + "type": "string" + }, + "height": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "itemSpacing": { + "type": "number" + }, + "justifyContent": { + "$ref": "#/definitions/JustifyString" + }, + "left": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "live": { + "type": "boolean" + }, + "margin": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginBottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginLeft": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginRight": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginTop": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "maxHeight": { + "type": "number" + }, + "maxWidth": { + "type": "number" + }, + "minHeight": { + "type": "number" + }, + "minWidth": { + "type": "number" + }, + "onKeyDown": { + "$comment": "(key: ParsedKey) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "key": { + "$ref": "#/definitions/ParsedKey" + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDown": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrag": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDragEnd": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrop": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseMove": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOut": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOver": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseScroll": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseUp": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "options": { + "items": { + "$ref": "#/definitions/SelectOption" + }, + "type": "array" + }, + "padding": { + "type": [ + "number", + "string" + ] + }, + "paddingBottom": { + "type": [ + "number", + "string" + ] + }, + "paddingLeft": { + "type": [ + "number", + "string" + ] + }, + "paddingRight": { + "type": [ + "number", + "string" + ] + }, + "paddingTop": { + "type": [ + "number", + "string" + ] + }, + "position": { + "$ref": "#/definitions/PositionTypeString" + }, + "right": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "selectedBackgroundColor": { + "$ref": "#/definitions/ColorInput" + }, + "selectedDescriptionColor": { + "$ref": "#/definitions/ColorInput" + }, + "selectedTextColor": { + "$ref": "#/definitions/ColorInput" + }, + "showDescription": { + "type": "boolean" + }, + "showScrollIndicator": { + "type": "boolean" + }, + "textColor": { + "$ref": "#/definitions/ColorInput" + }, + "top": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "visible": { + "type": "boolean" + }, + "width": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "wrapSelection": { + "type": "boolean" + }, + "zIndex": { + "type": "number" + } + }, + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/TabSelectRenderableOptions.json b/packages/core/docs/api/schemas/TabSelectRenderableOptions.json new file mode 100644 index 00000000..5406d464 --- /dev/null +++ b/packages/core/docs/api/schemas/TabSelectRenderableOptions.json @@ -0,0 +1,752 @@ +{ + "$ref": "#/definitions/TabSelectRenderableOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "AlignString": { + "enum": [ + "auto", + "flex-start", + "center", + "flex-end", + "stretch", + "baseline", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "ColorInput": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "FlexDirectionString": { + "enum": [ + "column", + "column-reverse", + "row", + "row-reverse" + ], + "type": "string" + }, + "JustifyString": { + "enum": [ + "flex-start", + "center", + "flex-end", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "MouseEvent": { + "additionalProperties": false, + "properties": { + "button": { + "type": "number" + }, + "modifiers": { + "additionalProperties": false, + "properties": { + "alt": { + "type": "boolean" + }, + "ctrl": { + "type": "boolean" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "shift", + "alt", + "ctrl" + ], + "type": "object" + }, + "scroll": { + "$ref": "#/definitions/ScrollInfo" + }, + "source": { + "$ref": "#/definitions/Renderable" + }, + "target": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "type": { + "$ref": "#/definitions/MouseEventType" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "type", + "button", + "x", + "y", + "modifiers", + "target" + ], + "type": "object" + }, + "MouseEventType": { + "enum": [ + "down", + "up", + "move", + "drag", + "drag-end", + "drop", + "over", + "out", + "scroll" + ], + "type": "string" + }, + "ParsedKey": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "ctrl": { + "type": "boolean" + }, + "meta": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "number": { + "type": "boolean" + }, + "option": { + "type": "boolean" + }, + "raw": { + "type": "string" + }, + "sequence": { + "type": "string" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "name", + "ctrl", + "meta", + "shift", + "option", + "sequence", + "number", + "raw" + ], + "type": "object" + }, + "PositionTypeString": { + "enum": [ + "static", + "relative", + "absolute" + ], + "type": "string" + }, + "RGBA": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + } + }, + "required": [ + "buffer" + ], + "type": "object" + }, + "Renderable": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "num": { + "type": "number" + }, + "parent": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "selectable": { + "type": "boolean" + } + }, + "required": [ + "id", + "num", + "selectable", + "parent" + ], + "type": "object" + }, + "ScrollInfo": { + "additionalProperties": false, + "properties": { + "delta": { + "type": "number" + }, + "direction": { + "enum": [ + "up", + "down", + "left", + "right" + ], + "type": "string" + } + }, + "required": [ + "direction", + "delta" + ], + "type": "object" + }, + "TabSelectOption": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "value": {} + }, + "required": [ + "name", + "description" + ], + "type": "object" + }, + "TabSelectRenderableOptions": { + "additionalProperties": false, + "properties": { + "alignItems": { + "$ref": "#/definitions/AlignString" + }, + "backgroundColor": { + "$ref": "#/definitions/ColorInput" + }, + "bottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "buffered": { + "type": "boolean" + }, + "enableLayout": { + "type": "boolean" + }, + "flexBasis": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + } + ] + }, + "flexDirection": { + "$ref": "#/definitions/FlexDirectionString" + }, + "flexGrow": { + "type": "number" + }, + "flexShrink": { + "type": "number" + }, + "focusedBackgroundColor": { + "$ref": "#/definitions/ColorInput" + }, + "focusedTextColor": { + "$ref": "#/definitions/ColorInput" + }, + "height": { + "type": "number" + }, + "justifyContent": { + "$ref": "#/definitions/JustifyString" + }, + "left": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "live": { + "type": "boolean" + }, + "margin": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginBottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginLeft": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginRight": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginTop": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "maxHeight": { + "type": "number" + }, + "maxWidth": { + "type": "number" + }, + "minHeight": { + "type": "number" + }, + "minWidth": { + "type": "number" + }, + "onKeyDown": { + "$comment": "(key: ParsedKey) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "key": { + "$ref": "#/definitions/ParsedKey" + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDown": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrag": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDragEnd": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrop": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseMove": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOut": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOver": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseScroll": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseUp": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "options": { + "items": { + "$ref": "#/definitions/TabSelectOption" + }, + "type": "array" + }, + "padding": { + "type": [ + "number", + "string" + ] + }, + "paddingBottom": { + "type": [ + "number", + "string" + ] + }, + "paddingLeft": { + "type": [ + "number", + "string" + ] + }, + "paddingRight": { + "type": [ + "number", + "string" + ] + }, + "paddingTop": { + "type": [ + "number", + "string" + ] + }, + "position": { + "$ref": "#/definitions/PositionTypeString" + }, + "right": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "selectedBackgroundColor": { + "$ref": "#/definitions/ColorInput" + }, + "selectedDescriptionColor": { + "$ref": "#/definitions/ColorInput" + }, + "selectedTextColor": { + "$ref": "#/definitions/ColorInput" + }, + "showDescription": { + "type": "boolean" + }, + "showScrollArrows": { + "type": "boolean" + }, + "showUnderline": { + "type": "boolean" + }, + "tabWidth": { + "type": "number" + }, + "textColor": { + "$ref": "#/definitions/ColorInput" + }, + "top": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "visible": { + "type": "boolean" + }, + "width": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "wrapSelection": { + "type": "boolean" + }, + "zIndex": { + "type": "number" + } + }, + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/TextOptions.json b/packages/core/docs/api/schemas/TextOptions.json new file mode 100644 index 00000000..4843b716 --- /dev/null +++ b/packages/core/docs/api/schemas/TextOptions.json @@ -0,0 +1,831 @@ +{ + "$ref": "#/definitions/TextOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "AlignString": { + "enum": [ + "auto", + "flex-start", + "center", + "flex-end", + "stretch", + "baseline", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "FlexDirectionString": { + "enum": [ + "column", + "column-reverse", + "row", + "row-reverse" + ], + "type": "string" + }, + "JustifyString": { + "enum": [ + "flex-start", + "center", + "flex-end", + "space-between", + "space-around", + "space-evenly" + ], + "type": "string" + }, + "MouseEvent": { + "additionalProperties": false, + "properties": { + "button": { + "type": "number" + }, + "modifiers": { + "additionalProperties": false, + "properties": { + "alt": { + "type": "boolean" + }, + "ctrl": { + "type": "boolean" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "shift", + "alt", + "ctrl" + ], + "type": "object" + }, + "scroll": { + "$ref": "#/definitions/ScrollInfo" + }, + "source": { + "$ref": "#/definitions/Renderable" + }, + "target": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "type": { + "$ref": "#/definitions/MouseEventType" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "type", + "button", + "x", + "y", + "modifiers", + "target" + ], + "type": "object" + }, + "MouseEventType": { + "enum": [ + "down", + "up", + "move", + "drag", + "drag-end", + "drop", + "over", + "out", + "scroll" + ], + "type": "string" + }, + "ParsedKey": { + "additionalProperties": false, + "properties": { + "code": { + "type": "string" + }, + "ctrl": { + "type": "boolean" + }, + "meta": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "number": { + "type": "boolean" + }, + "option": { + "type": "boolean" + }, + "raw": { + "type": "string" + }, + "sequence": { + "type": "string" + }, + "shift": { + "type": "boolean" + } + }, + "required": [ + "name", + "ctrl", + "meta", + "shift", + "option", + "sequence", + "number", + "raw" + ], + "type": "object" + }, + "PositionTypeString": { + "enum": [ + "static", + "relative", + "absolute" + ], + "type": "string" + }, + "RGBA": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + } + }, + "required": [ + "buffer" + ], + "type": "object" + }, + "Renderable": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "num": { + "type": "number" + }, + "parent": { + "anyOf": [ + { + "$ref": "#/definitions/Renderable" + }, + { + "type": "null" + } + ] + }, + "selectable": { + "type": "boolean" + } + }, + "required": [ + "id", + "num", + "selectable", + "parent" + ], + "type": "object" + }, + "ScrollInfo": { + "additionalProperties": false, + "properties": { + "delta": { + "type": "number" + }, + "direction": { + "enum": [ + "up", + "down", + "left", + "right" + ], + "type": "string" + } + }, + "required": [ + "direction", + "delta" + ], + "type": "object" + }, + "StyledText": { + "additionalProperties": false, + "properties": { + "chunks": { + "items": { + "$ref": "#/definitions/TextChunk" + }, + "type": "array" + } + }, + "required": [ + "chunks" + ], + "type": "object" + }, + "TextChunk": { + "additionalProperties": false, + "properties": { + "__isChunk": { + "const": true, + "type": "boolean" + }, + "attributes": { + "type": "number" + }, + "bg": { + "$ref": "#/definitions/RGBA" + }, + "fg": { + "$ref": "#/definitions/RGBA" + }, + "plainText": { + "type": "string" + }, + "text": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + } + }, + "required": [ + "__isChunk", + "text", + "plainText" + ], + "type": "object" + }, + "TextOptions": { + "additionalProperties": false, + "properties": { + "alignItems": { + "$ref": "#/definitions/AlignString" + }, + "attributes": { + "type": "number" + }, + "bg": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "bottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "buffered": { + "type": "boolean" + }, + "content": { + "anyOf": [ + { + "$ref": "#/definitions/StyledText" + }, + { + "type": "string" + } + ] + }, + "enableLayout": { + "type": "boolean" + }, + "fg": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "flexBasis": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + } + ] + }, + "flexDirection": { + "$ref": "#/definitions/FlexDirectionString" + }, + "flexGrow": { + "type": "number" + }, + "flexShrink": { + "type": "number" + }, + "height": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "justifyContent": { + "$ref": "#/definitions/JustifyString" + }, + "left": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "live": { + "type": "boolean" + }, + "margin": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginBottom": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginLeft": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginRight": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "marginTop": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "maxHeight": { + "type": "number" + }, + "maxWidth": { + "type": "number" + }, + "minHeight": { + "type": "number" + }, + "minWidth": { + "type": "number" + }, + "onKeyDown": { + "$comment": "(key: ParsedKey) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "key": { + "$ref": "#/definitions/ParsedKey" + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDown": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrag": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDragEnd": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseDrop": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseMove": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOut": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseOver": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseScroll": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "onMouseUp": { + "$comment": "(event: MouseEvent) => void", + "properties": { + "namedArgs": { + "additionalProperties": false, + "properties": { + "event": { + "$ref": "#/definitions/MouseEvent" + } + }, + "required": [ + "event" + ], + "type": "object" + } + }, + "type": "object" + }, + "padding": { + "type": [ + "number", + "string" + ] + }, + "paddingBottom": { + "type": [ + "number", + "string" + ] + }, + "paddingLeft": { + "type": [ + "number", + "string" + ] + }, + "paddingRight": { + "type": [ + "number", + "string" + ] + }, + "paddingTop": { + "type": [ + "number", + "string" + ] + }, + "position": { + "$ref": "#/definitions/PositionTypeString" + }, + "right": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "selectable": { + "type": "boolean" + }, + "selectionBg": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "selectionFg": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/RGBA" + } + ] + }, + "top": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "visible": { + "type": "boolean" + }, + "width": { + "anyOf": [ + { + "type": "number" + }, + { + "const": "auto", + "type": "string" + }, + { + "type": "string" + } + ] + }, + "zIndex": { + "type": "number" + } + }, + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/ThreeCliRendererOptions.json b/packages/core/docs/api/schemas/ThreeCliRendererOptions.json new file mode 100644 index 00000000..2459a410 --- /dev/null +++ b/packages/core/docs/api/schemas/ThreeCliRendererOptions.json @@ -0,0 +1,96 @@ +{ + "$ref": "#/definitions/ThreeCliRendererOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "RGBA": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": { + "type": "number" + }, + "properties": { + "BYTES_PER_ELEMENT": { + "type": "number" + }, + "buffer": { + "additionalProperties": false, + "properties": { + "byteLength": { + "type": "number" + } + }, + "required": [ + "byteLength" + ], + "type": "object" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + }, + "length": { + "type": "number" + } + }, + "required": [ + "BYTES_PER_ELEMENT", + "buffer", + "byteLength", + "byteOffset", + "length" + ], + "type": "object" + } + }, + "required": [ + "buffer" + ], + "type": "object" + }, + "SuperSampleType": { + "enum": [ + "none", + "gpu", + "cpu" + ], + "type": "string" + }, + "ThreeCliRendererOptions": { + "additionalProperties": false, + "properties": { + "alpha": { + "type": "boolean" + }, + "autoResize": { + "type": "boolean" + }, + "backgroundColor": { + "$ref": "#/definitions/RGBA" + }, + "focalLength": { + "type": "number" + }, + "height": { + "type": "number" + }, + "libPath": { + "type": "string" + }, + "superSample": { + "$ref": "#/definitions/SuperSampleType" + }, + "width": { + "type": "number" + } + }, + "required": [ + "width", + "height" + ], + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/api/schemas/TimelineOptions.json b/packages/core/docs/api/schemas/TimelineOptions.json new file mode 100644 index 00000000..0e77be9d --- /dev/null +++ b/packages/core/docs/api/schemas/TimelineOptions.json @@ -0,0 +1,27 @@ +{ + "$ref": "#/definitions/TimelineOptions", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "TimelineOptions": { + "additionalProperties": false, + "properties": { + "autoplay": { + "type": "boolean" + }, + "duration": { + "type": "number" + }, + "loop": { + "type": "boolean" + }, + "onComplete": { + "$comment": "() => void" + }, + "onPause": { + "$comment": "() => void" + } + }, + "type": "object" + } + } +} \ No newline at end of file diff --git a/packages/core/docs/modules/3d.md b/packages/core/docs/modules/3d.md new file mode 100644 index 00000000..d1332205 --- /dev/null +++ b/packages/core/docs/modules/3d.md @@ -0,0 +1,499 @@ +# 3D Module + +The 3D module provides WebGPU and Three.js integration for advanced terminal-based 3D rendering, including sprites, animations, physics, and shader effects. + +## Overview + +OpenTUI's 3D capabilities enable rich visual effects in the terminal through WebGPU rendering and Three.js integration. The module includes sprite management, particle systems, physics simulations, and custom shaders. + +## Module Entry Points + +The 3D functionality is available through a separate import: + +```typescript +// Main 3D exports +import { + ThreeCliRenderer, + WGPURenderer, + Canvas, + SpriteUtils +} from '@opentui/core/3d' + +// Animation effects +import { + SpriteAnimator, + ExplodingSpriteEffect, + PhysicsExplodingSpriteEffect, + SpriteParticleGenerator +} from '@opentui/core/3d/animation' + +// Physics adapters +import { + RapierPhysicsAdapter, + PlanckPhysicsAdapter +} from '@opentui/core/3d/physics' +``` + +## Core Components + +### Canvas + +Terminal-based canvas for 3D rendering: + +```typescript +import { Canvas } from '@opentui/core/3d' + +const canvas = new Canvas(width, height, { + backend: 'webgpu', // or 'threejs' + antialias: true, + alpha: true +}) + +// Render to terminal buffer +canvas.render(buffer) +``` + +### WGPURenderer + +WebGPU-based renderer for high-performance graphics: + +```typescript +import { WGPURenderer } from '@opentui/core/3d' + +const renderer = new WGPURenderer({ + width: 80, + height: 24, + devicePixelRatio: 2 +}) + +// Initialize WebGPU +await renderer.initialize() + +// Render frame +renderer.render(scene, camera) + +// Convert to terminal output +const buffer = renderer.toTerminalBuffer() +``` + +### Three.js Integration + +Terminal rendering with Three.js: + +```typescript +import { ThreeCliRenderer } from '@opentui/core/3d' +import * as THREE from 'three' + +const renderer = new ThreeCliRenderer({ + width: 80, + height: 24, + colors: 256, + dithering: true +}) + +// Create Three.js scene +const scene = new THREE.Scene() +const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 1000) + +// Add objects +const geometry = new THREE.BoxGeometry() +const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }) +const cube = new THREE.Mesh(geometry, material) +scene.add(cube) + +// Render to terminal +renderer.render(scene, camera) +``` + +## Sprite System + +### Sprite Management + +```typescript +import { SpriteResourceManager } from '@opentui/core/3d' + +const manager = new SpriteResourceManager() + +// Load sprite sheet +await manager.loadSpriteSheet('sprites.png', { + frameWidth: 32, + frameHeight: 32, + animations: { + idle: { frames: [0, 1, 2, 3], duration: 100 }, + walk: { frames: [4, 5, 6, 7], duration: 80 } + } +}) + +// Get sprite instance +const sprite = manager.createSprite('player', 'idle') +``` + +### Sprite Animation + +```typescript +import { SpriteAnimator } from '@opentui/core/3d/animation' + +const animator = new SpriteAnimator(sprite) + +// Play animation +animator.play('walk', { + loop: true, + speed: 1.5, + onComplete: () => console.log('Animation finished') +}) + +// Update animation +animator.update(deltaTime) +``` + +### Sprite Utils + +```typescript +import { SpriteUtils } from '@opentui/core/3d' + +// Convert image to ASCII art +const ascii = SpriteUtils.imageToAscii(imageData, { + width: 40, + height: 20, + characters: ' .:-=+*#%@' +}) + +// Generate sprite from text +const textSprite = SpriteUtils.textToSprite('HELLO', { + font: 'monospace', + size: 24, + color: '#00ff00' +}) +``` + +## Animation Effects + +### Exploding Sprite Effect + +Create explosion animations: + +```typescript +import { ExplodingSpriteEffect } from '@opentui/core/3d/animation' + +const explosion = new ExplodingSpriteEffect({ + particleCount: 100, + spread: 45, + velocity: { min: 2, max: 10 }, + lifetime: 1000, + gravity: 0.5, + colors: ['#ff0000', '#ff8800', '#ffff00'] +}) + +// Trigger explosion at position +explosion.explode(x, y) + +// Update particles +explosion.update(deltaTime) + +// Render to buffer +explosion.render(buffer) +``` + +### Physics-Based Explosions + +Realistic physics explosions: + +```typescript +import { PhysicsExplodingSpriteEffect } from '@opentui/core/3d/animation' +import { RapierPhysicsAdapter } from '@opentui/core/3d/physics' + +const physics = new RapierPhysicsAdapter() +await physics.initialize() + +const explosion = new PhysicsExplodingSpriteEffect({ + physics, + particleCount: 50, + explosionForce: 100, + damping: 0.98, + restitution: 0.8 +}) + +explosion.explode(x, y, sprite) +``` + +### Particle Generator + +Continuous particle effects: + +```typescript +import { SpriteParticleGenerator } from '@opentui/core/3d/animation' + +const generator = new SpriteParticleGenerator({ + emissionRate: 10, // particles per second + lifetime: { min: 1000, max: 2000 }, + velocity: { + angle: { min: -45, max: 45 }, + speed: { min: 1, max: 5 } + }, + size: { start: 1, end: 0.1 }, + opacity: { start: 1, end: 0 }, + colors: { + start: '#ffffff', + end: '#000000' + } +}) + +// Start emitting +generator.start() + +// Update and render +generator.update(deltaTime) +generator.render(buffer) +``` + +## Physics Integration + +### Physics Interface + +Common interface for physics engines: + +```typescript +interface PhysicsAdapter { + initialize(): Promise + createWorld(gravity?: { x: number, y: number }): PhysicsWorld + createBody(world: PhysicsWorld, options: BodyOptions): PhysicsBody + step(world: PhysicsWorld, deltaTime: number): void + dispose(): void +} +``` + +### Rapier Physics + +2D/3D physics with Rapier: + +```typescript +import { RapierPhysicsAdapter } from '@opentui/core/3d/physics' + +const physics = new RapierPhysicsAdapter() +await physics.initialize() + +const world = physics.createWorld({ x: 0, y: 9.8 }) + +// Create rigid body +const body = physics.createBody(world, { + type: 'dynamic', + position: { x: 0, y: 10 }, + shape: 'box', + size: { width: 2, height: 2 }, + mass: 1, + restitution: 0.5 +}) + +// Simulate +physics.step(world, 0.016) // 60 FPS +``` + +### Planck Physics + +2D physics with Planck.js: + +```typescript +import { PlanckPhysicsAdapter } from '@opentui/core/3d/physics' + +const physics = new PlanckPhysicsAdapter() +const world = physics.createWorld({ x: 0, y: -10 }) + +// Create ground +const ground = physics.createBody(world, { + type: 'static', + position: { x: 0, y: 0 }, + shape: 'box', + size: { width: 100, height: 1 } +}) + +// Create dynamic box +const box = physics.createBody(world, { + type: 'dynamic', + position: { x: 0, y: 20 }, + shape: 'box', + size: { width: 2, height: 2 }, + density: 1, + friction: 0.3 +}) +``` + +## Shader Support + +### Custom Shaders + +WebGPU shader integration: + +```typescript +const shader = ` + @vertex + fn vs_main(@location(0) position: vec2) -> @builtin(position) vec4 { + return vec4(position, 0.0, 1.0); + } + + @fragment + fn fs_main() -> @location(0) vec4 { + return vec4(1.0, 0.0, 0.0, 1.0); + } +` + +renderer.addShader('custom', shader) +renderer.useShader('custom') +``` + +### Post-Processing Effects + +Apply shader-based effects: + +```typescript +// Bloom effect +renderer.addPostProcess('bloom', { + threshold: 0.8, + intensity: 1.5, + radius: 4 +}) + +// Chromatic aberration +renderer.addPostProcess('chromaticAberration', { + offset: 0.01 +}) +``` + +## Texture Management + +### Texture Utils + +```typescript +import { TextureUtils } from '@opentui/core/3d' + +// Load texture +const texture = await TextureUtils.loadTexture('texture.png') + +// Convert to terminal colors +const terminalTexture = TextureUtils.toTerminalColors(texture, { + palette: 'ansi256', + dithering: 'floyd-steinberg' +}) + +// Apply to sprite +sprite.setTexture(terminalTexture) +``` + +## Performance Optimization + +### Level of Detail (LOD) + +```typescript +// Automatic LOD based on distance +const lodSprite = new LODSprite([ + { distance: 0, sprite: highDetailSprite }, + { distance: 50, sprite: mediumDetailSprite }, + { distance: 100, sprite: lowDetailSprite } +]) + +// Update based on camera distance +lodSprite.update(camera) +``` + +### Instancing + +Efficient rendering of many objects: + +```typescript +const instances = new InstancedSprites(baseSprite, 1000) + +// Update instance transforms +for (let i = 0; i < 1000; i++) { + instances.setTransform(i, { + position: { x: Math.random() * 100, y: Math.random() * 100 }, + rotation: Math.random() * Math.PI * 2, + scale: Math.random() * 2 + }) +} + +instances.render(buffer) +``` + +## Integration Example + +Complete 3D scene in terminal: + +```typescript +import { + WGPURenderer, + SpriteAnimator, + RapierPhysicsAdapter, + PhysicsExplodingSpriteEffect +} from '@opentui/core/3d' + +// Setup +const renderer = new WGPURenderer({ width: 120, height: 40 }) +await renderer.initialize() + +const physics = new RapierPhysicsAdapter() +await physics.initialize() + +const world = physics.createWorld({ x: 0, y: -9.8 }) + +// Create scene +const sprites = [] +for (let i = 0; i < 10; i++) { + const sprite = createSprite() + const body = physics.createBody(world, { + type: 'dynamic', + position: { x: i * 5, y: 20 } + }) + sprites.push({ sprite, body }) +} + +// Animation loop +function animate(deltaTime: number) { + // Update physics + physics.step(world, deltaTime) + + // Update sprites from physics + sprites.forEach(({ sprite, body }) => { + const pos = body.getPosition() + sprite.position.set(pos.x, pos.y) + sprite.rotation = body.getRotation() + }) + + // Render + renderer.render(scene, camera) + const buffer = renderer.toTerminalBuffer() + terminal.write(buffer) + + requestAnimationFrame(animate) +} + +animate(0) +``` + +## API Reference + +### Main Exports + +- `Canvas` - Terminal canvas for 3D +- `WGPURenderer` - WebGPU renderer +- `ThreeCliRenderer` - Three.js terminal renderer +- `SpriteResourceManager` - Sprite asset management +- `SpriteUtils` - Sprite utilities +- `TextureUtils` - Texture utilities + +### Animation Exports + +- `SpriteAnimator` - Sprite animation controller +- `ExplodingSpriteEffect` - Explosion effect +- `PhysicsExplodingSpriteEffect` - Physics-based explosion +- `SpriteParticleGenerator` - Particle system + +### Physics Exports + +- `RapierPhysicsAdapter` - Rapier physics integration +- `PlanckPhysicsAdapter` - Planck.js integration +- `PhysicsAdapter` - Physics interface + +## Related Modules + +- [Rendering](./rendering.md) - Core rendering system +- [Animation](./animation.md) - Timeline animations +- [Buffer](./buffer.md) - Terminal buffer operations \ No newline at end of file diff --git a/packages/core/docs/modules/animation.md b/packages/core/docs/modules/animation.md new file mode 100644 index 00000000..8cd026b6 --- /dev/null +++ b/packages/core/docs/modules/animation.md @@ -0,0 +1,664 @@ +# Animation + +> **Quick Navigation:** [Getting Started](./getting-started.md) | [Components](./components.md) | [Layout](./layout.md) | [Events](./events.md) | [Rendering](./rendering.md) + +OpenTUI provides a powerful animation system for creating smooth transitions and effects. + +## Timeline Animations + +```typescript +import { Timeline, Easing } from '@opentui/core'; + +// Create a timeline +const timeline = new Timeline({ + duration: 2000, + loop: true, + autoplay: true +}); + +// Add animations +timeline.add({ + target: myBox, + properties: { + x: { from: 0, to: 100 }, + y: { from: 0, to: 50 }, + opacity: { from: 0, to: 1 } + }, + duration: 1000, + easing: Easing.easeInOutQuad, + delay: 0 +}); + +// Chain animations +timeline + .add({ + target: box1, + properties: { x: { to: 100 } }, + duration: 500 + }) + .add({ + target: box2, + properties: { y: { to: 50 } }, + duration: 500, + offset: '-=250' // Start 250ms before previous ends + }); + +// Control playback +timeline.play(); +timeline.pause(); +timeline.stop(); +timeline.seek(500); // Jump to 500ms +``` + +## Property Animations + +```typescript +class AnimatedBox extends BoxRenderable { + private animator = new PropertyAnimator(this); + + async slideIn() { + await this.animator.animate({ + x: { from: -this.width, to: 0 }, + opacity: { from: 0, to: 1 } + }, { + duration: 300, + easing: 'easeOutQuad' + }); + } + + async slideOut() { + await this.animator.animate({ + x: { to: this.parent.width }, + opacity: { to: 0 } + }, { + duration: 300, + easing: 'easeInQuad' + }); + } + + pulse() { + this.animator.animate({ + scale: { from: 1, to: 1.1, to: 1 } + }, { + duration: 200, + repeat: 3 + }); + } +} +``` + +## Easing Functions + +Built-in easing functions: +- Linear: `linear` +- Quad: `easeInQuad`, `easeOutQuad`, `easeInOutQuad` +- Cubic: `easeInCubic`, `easeOutCubic`, `easeInOutCubic` +- Expo: `easeInExpo`, `easeOutExpo`, `easeInOutExpo` +- Bounce: `easeInBounce`, `easeOutBounce`, `easeInOutBounce` +- Elastic: `easeInElastic`, `easeOutElastic`, `easeInOutElastic` +- Back: `easeInBack`, `easeOutBack`, `easeInOutBack` + +```typescript +// Custom easing function +function customEase(t: number): number { + // t is 0 to 1 + return t * t * (3 - 2 * t); // Smooth step +} + +timeline.add({ + target: component, + properties: { x: { to: 100 } }, + easing: customEase +}); +``` + +## Frame-based Animation + +```typescript +class ParticleEffect extends Renderable { + private particles: Particle[] = []; + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + // Update particles + this.particles.forEach(particle => { + particle.x += particle.vx * deltaTime; + particle.y += particle.vy * deltaTime; + particle.vy += 0.1 * deltaTime; // Gravity + particle.life -= deltaTime; + + if (particle.life > 0) { + const opacity = particle.life / particle.maxLife; + buffer.setCell( + Math.round(particle.x), + Math.round(particle.y), + '•', + RGBA.fromValues(1, 1, 1, opacity) + ); + } + }); + + // Remove dead particles + this.particles = this.particles.filter(p => p.life > 0); + + // Keep animating if particles exist + if (this.particles.length > 0) { + this.needsUpdate(); + } + } + + emit(x: number, y: number, count: number) { + for (let i = 0; i < count; i++) { + this.particles.push({ + x, y, + vx: (Math.random() - 0.5) * 10, + vy: Math.random() * -10, + life: 1000, + maxLife: 1000 + }); + } + this.needsUpdate(); + } +} +``` + +## Transition Effects + +```typescript +class TransitionManager { + async fadeTransition(from: Renderable, to: Renderable, duration = 500) { + to.style.opacity = 0; + to.visible = true; + + const timeline = new Timeline({ duration }); + + timeline.add({ + target: from, + properties: { opacity: { to: 0 } }, + duration: duration / 2 + }); + + timeline.add({ + target: to, + properties: { opacity: { to: 1 } }, + duration: duration / 2, + offset: `-=${duration/4}` // Overlap + }); + + await timeline.play(); + from.visible = false; + } + + async slideTransition(from: Renderable, to: Renderable, direction = 'left') { + const parent = from.parent; + const width = parent.computedWidth; + + // Position 'to' off-screen + if (direction === 'left') { + to.x = width; + } else { + to.x = -width; + } + to.visible = true; + + const timeline = new Timeline({ duration: 300 }); + + timeline.add({ + targets: [from, to], + properties: { + x: { + from: (target) => target.x, + to: (target) => { + if (target === from) { + return direction === 'left' ? -width : width; + } else { + return 0; + } + } + } + }, + easing: 'easeInOutQuad' + }); + + await timeline.play(); + from.visible = false; + } +} +``` + +## Sprite Animations + +```typescript +class SpriteAnimation extends Renderable { + private frames: string[] = []; + private currentFrame = 0; + private frameDuration = 100; + private elapsed = 0; + + constructor(id: string, frames: string[]) { + super(id, {}); + this.frames = frames; + } + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + // Update animation + this.elapsed += deltaTime; + if (this.elapsed >= this.frameDuration) { + this.currentFrame = (this.currentFrame + 1) % this.frames.length; + this.elapsed = 0; + } + + // Draw current frame + const frame = this.frames[this.currentFrame]; + const lines = frame.split('\n'); + lines.forEach((line, y) => { + buffer.drawText(line, this.x, this.y + y); + }); + + this.needsUpdate(); // Continue animating + } +} + +// ASCII spinner animation +const spinner = new SpriteAnimation('spinner', [ + 'ā ‹', 'ā ™', 'ā ¹', 'ā ø', 'ā ¼', 'ā “', 'ā ¦', 'ā §', 'ā ‡', 'ā ' +]); +``` + +## Performance Best Practices + +### Optimize Animation Updates + +```typescript +class OptimizedAnimation extends Renderable { + private isDirty = false; + private animationFrame = 0; + private targetFPS = 30; + private frameInterval = 1000 / 30; // 33ms per frame + private lastFrame = 0; + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + // Throttle animation to target FPS + this.lastFrame += deltaTime; + if (this.lastFrame < this.frameInterval) { + this.needsUpdate(); + return; + } + + // Only update if changed + if (this.isDirty) { + this.updateAnimation(); + this.isDirty = false; + } + + // Continue if animating + if (this.isAnimating) { + this.needsUpdate(); + } + + this.lastFrame = 0; + } +} +``` + +### Batch Animations + +```typescript +class AnimationBatcher { + private animations: Map = new Map(); + private timeline: Timeline; + + batchAnimate(targets: Renderable[], config: AnimationConfig) { + // Batch multiple targets in single timeline + this.timeline = new Timeline({ duration: config.duration }); + + targets.forEach((target, index) => { + this.timeline.add({ + target, + properties: config.properties, + duration: config.duration, + easing: config.easing, + // Stagger animations + delay: config.stagger ? index * config.stagger : 0 + }); + }); + + return this.timeline.play(); + } +} + +// Usage +const batcher = new AnimationBatcher(); +const boxes = [box1, box2, box3, box4]; + +await batcher.batchAnimate(boxes, { + properties: { + y: { to: 10 }, + opacity: { from: 0, to: 1 } + }, + duration: 500, + stagger: 50, // 50ms delay between each + easing: 'easeOutQuad' +}); +``` + +## Complex Animation Examples + +### Loading Bar Animation + +```typescript +class LoadingBar extends BoxRenderable { + private progress = 0; + private targetProgress = 0; + private animating = false; + + constructor(id: string, options: BoxOptions) { + super(id, { + ...options, + height: 3, + border: true, + borderStyle: 'single' + }); + } + + setProgress(value: number) { + this.targetProgress = Math.max(0, Math.min(100, value)); + if (!this.animating) { + this.animateProgress(); + } + } + + private async animateProgress() { + this.animating = true; + + while (Math.abs(this.progress - this.targetProgress) > 0.1) { + // Smooth interpolation + this.progress += (this.targetProgress - this.progress) * 0.1; + this.needsUpdate(); + await new Promise(resolve => setTimeout(resolve, 16)); + } + + this.progress = this.targetProgress; + this.animating = false; + this.needsUpdate(); + } + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + super.renderSelf(buffer, deltaTime); + + const innerWidth = this.computedWidth - 2; + const filled = Math.floor(innerWidth * (this.progress / 100)); + + // Draw progress bar + for (let x = 0; x < filled; x++) { + buffer.setCell( + this.x + 1 + x, + this.y + 1, + 'ā–ˆ', + RGBA.fromHex('#00ff00') + ); + } + + // Draw percentage + const text = `${Math.round(this.progress)}%`; + buffer.drawText( + text, + this.x + Math.floor(innerWidth / 2) - Math.floor(text.length / 2), + this.y + 1, + RGBA.fromHex('#ffffff') + ); + } +} +``` + +### Notification Toast Animation + +```typescript +class Toast extends BoxRenderable { + private timeline: Timeline; + + constructor(message: string, type: 'success' | 'error' | 'info' = 'info') { + const colors = { + success: '#00ff00', + error: '#ff0000', + info: '#00aaff' + }; + + super('toast', { + width: message.length + 4, + height: 3, + border: true, + borderStyle: 'rounded', + borderColor: colors[type], + backgroundColor: '#1e1e1e', + padding: { left: 1, right: 1 }, + position: 'absolute', + right: 2, + top: -5, // Start off-screen + zIndex: 1000 + }); + + const text = new TextRenderable('message', { + text: message, + color: colors[type] + }); + this.add(text, 0); + } + + async show(duration = 3000) { + this.timeline = new Timeline({ duration: duration + 600 }); + + // Slide in + this.timeline.add({ + target: this, + properties: { + top: { from: -5, to: 2 } + }, + duration: 300, + easing: 'easeOutBack' + }); + + // Wait + this.timeline.add({ + target: this, + properties: {}, // No-op + duration: duration + }); + + // Slide out + this.timeline.add({ + target: this, + properties: { + top: { to: -5 }, + opacity: { to: 0 } + }, + duration: 300, + easing: 'easeInBack' + }); + + await this.timeline.play(); + this.destroy(); + } +} + +// Usage +const toast = new Toast('File saved successfully!', 'success'); +renderer.root.add(toast, 999); +await toast.show(); +``` + +### Wave Animation Effect + +```typescript +class WaveText extends Renderable { + private text: string; + private amplitude = 2; + private frequency = 0.5; + private phase = 0; + + constructor(id: string, text: string) { + super(id, { width: text.length, height: 5 }); + this.text = text; + } + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + // Update wave phase + this.phase += deltaTime * 0.003; + + // Draw each character with wave offset + for (let i = 0; i < this.text.length; i++) { + const yOffset = Math.sin(this.phase + i * this.frequency) * this.amplitude; + const y = Math.round(this.y + 2 + yOffset); + + // Color based on height + const hue = (i * 30 + this.phase * 100) % 360; + const color = RGBA.fromHSL(hue, 100, 50); + + buffer.setCell( + this.x + i, + y, + this.text[i], + color + ); + } + + this.needsUpdate(); // Continue animating + } +} +``` + +## Animation Sequencing + +```typescript +class AnimationSequence { + private steps: (() => Promise)[] = []; + + add(step: () => Promise): this { + this.steps.push(step); + return this; + } + + async play() { + for (const step of this.steps) { + await step(); + } + } + + async playParallel() { + await Promise.all(this.steps.map(step => step())); + } +} + +// Complex animation sequence +const sequence = new AnimationSequence(); + +sequence + .add(async () => { + // Fade in title + await titleBox.animate({ opacity: { from: 0, to: 1 } }, 500); + }) + .add(async () => { + // Slide in menu items + const items = [item1, item2, item3]; + for (let i = 0; i < items.length; i++) { + await items[i].animate({ + x: { from: -20, to: 0 }, + opacity: { from: 0, to: 1 } + }, 200); + } + }) + .add(async () => { + // Show content with bounce + await content.animate({ + scale: { from: 0, to: 1.1, to: 1 }, + opacity: { from: 0, to: 1 } + }, { + duration: 400, + easing: 'easeOutBounce' + }); + }); + +await sequence.play(); +``` + +## Troubleshooting + +### Common Issues + +1. **Choppy animations**: Reduce animation complexity or decrease target FPS +2. **Memory leaks**: Always stop/destroy timelines when components unmount +3. **CPU usage**: Use `requestAnimationFrame` pattern or throttle updates +4. **Flickering**: Enable double buffering with `buffered: true` + +### Debug Animation Performance + +```typescript +class AnimationDebugger { + private frameCount = 0; + private lastFPSUpdate = Date.now(); + private currentFPS = 0; + + measureFrame(callback: () => void) { + const start = performance.now(); + callback(); + const duration = performance.now() - start; + + this.frameCount++; + const now = Date.now(); + if (now - this.lastFPSUpdate > 1000) { + this.currentFPS = this.frameCount; + this.frameCount = 0; + this.lastFPSUpdate = now; + + console.log(`FPS: ${this.currentFPS}, Frame time: ${duration.toFixed(2)}ms`); + } + } +} +``` + +## Related Topics + +### Components & Animation +- [Components: Custom](./components.md#custom-components) - Building animated components +- [Components: ASCII Font](./components.md#ascii-font-component) - Animated text effects +- [Getting Started](./getting-started.md) - Animation basics + +### User Interaction +- [Events: Mouse](./events.md#mouse-events) - Trigger animations on interaction +- [Events: Keyboard](./events.md#keyboard-events) - Keyboard-triggered animations +- [Events: Forms](./events.md#form-handling) - Form validation animations + +### Layout Animation +- [Layout: Flexbox](./layout.md#flexbox-properties) - Animating layout properties +- [Layout: Responsive](./layout.md#responsive-techniques) - Smooth responsive transitions +- [Layout: Scrollable](./layout.md#scrollable-content) - Animated scrolling + +### Performance +- [Rendering: Optimization](./rendering.md#performance-monitoring) - Animation performance +- [Rendering: Frame Time](./rendering.md#frame-time-analysis) - Measuring animation FPS +- [Rendering: Techniques](./rendering.md#advanced-rendering-techniques) - Visual effects + +## Animation Patterns + +### Common Animations +- **Loading:** Progress bars, spinners (see examples above) +- **Notifications:** [Toast animations](#notification-toast-animation) +- **Transitions:** Page changes, modal appearances +- **Feedback:** Button presses, hover effects + +### Combining with Events +Create interactive animations: +- [Events: Mouse](./events.md#mouse-events) - Hover and click animations +- [Events: Focus](./events.md#focus-management) - Focus state animations +- [Components: Input](./components.md#input-component) - Input validation animations + +### Performance Optimization +- Use [Rendering: Optimization](./rendering.md#render-optimization-strategies) techniques +- Implement frame throttling (see examples above) +- Cache complex animations with [Rendering: Caching](./rendering.md#caching-complex-renders) + +## Next Steps + +- **Add Interaction:** Trigger animations with [Events](./events.md) +- **Build Components:** Create animated [Components](./components.md) +- **Optimize:** Improve performance with [Rendering](./rendering.md) techniques +- **Layout:** Animate [Layout](./layout.md) changes smoothly diff --git a/packages/core/docs/modules/buffer.md b/packages/core/docs/modules/buffer.md new file mode 100644 index 00000000..ee1baf21 --- /dev/null +++ b/packages/core/docs/modules/buffer.md @@ -0,0 +1,335 @@ +# Buffer Module + +The buffer module provides the high-performance `OptimizedBuffer` class, which serves as the core data structure for terminal rendering operations with native Zig acceleration. + +## Overview + +`OptimizedBuffer` manages terminal display data using typed arrays for optimal performance. It integrates with native Zig code via FFI for accelerated operations while providing JavaScript fallbacks. + +## Core Architecture + +### Buffer Structure + +The buffer uses separate typed arrays for different data types: + +```typescript +{ + char: Uint32Array, // Unicode character codes + fg: Float32Array, // Foreground RGBA (0.0-1.0) + bg: Float32Array, // Background RGBA (0.0-1.0) + attributes: Uint8Array // Text attributes (bold, italic, etc.) +} +``` + +### Creating Buffers + +```typescript +import { OptimizedBuffer } from '@opentui/core' + +// Create a buffer +const buffer = OptimizedBuffer.create(80, 24, { + respectAlpha: true // Enable alpha blending +}) + +// Access dimensions +const width = buffer.getWidth() // 80 +const height = buffer.getHeight() // 24 +``` + +## Cell Operations + +### Basic Cell Manipulation + +```typescript +import { RGBA } from '@opentui/core' + +const fg = RGBA.fromValues(1.0, 1.0, 1.0, 1.0) // White +const bg = RGBA.fromValues(0.0, 0.0, 1.0, 1.0) // Blue + +// Set a cell +buffer.setCell(10, 5, 'A', fg, bg, 0) + +// Get cell data +const cell = buffer.get(10, 5) +// Returns: { char: 65, fg: RGBA, bg: RGBA, attributes: 0 } +``` + +### Alpha Blending + +Advanced alpha blending with perceptual adjustments: + +```typescript +const semitransparent = RGBA.fromValues(1.0, 0.0, 0.0, 0.5) + +// Automatically blends with existing content +buffer.setCellWithAlphaBlending( + 10, 5, + 'B', + fg, + semitransparent, + 0 +) +``` + +Alpha blending features: +- Perceptual alpha curve for natural transparency +- Character preservation when overlaying spaces +- Automatic foreground/background blending + +## Text Drawing + +### Basic Text + +```typescript +const text = "Hello, World!" +const x = 10, y = 5 +const fg = RGBA.fromValues(1.0, 1.0, 1.0, 1.0) +const bg = RGBA.fromValues(0.0, 0.0, 0.0, 1.0) + +buffer.drawText(text, x, y, fg, bg, 0) +``` + +### Text with Selection + +Support for text selection highlighting: + +```typescript +buffer.drawText( + "Select this text", + 10, 5, + fg, bg, 0, + { + start: 7, + end: 11, + bgColor: RGBA.fromValues(0.0, 0.0, 1.0, 1.0), + fgColor: RGBA.fromValues(1.0, 1.0, 1.0, 1.0) + } +) +``` + +## Box Drawing + +### Basic Box + +```typescript +buffer.drawBox( + 5, 2, // x, y + 20, 10, // width, height + fg, bg, + true, // border + true, // fill + 'single' // border style +) +``` + +### Advanced Box Options + +```typescript +// Partial borders +buffer.drawBox( + 5, 2, 20, 10, + fg, bg, + ['top', 'bottom'], // Only top and bottom borders + true, + 'double' +) + +// With title +buffer.drawBoxWithTitle( + 5, 2, 20, 10, + fg, bg, + true, true, + 'rounded', + 'My Box', // title + 'center' // alignment: 'left', 'center', 'right' +) +``` + +### Border Styles + +Available border styles: +- `'single'` - `ā”Œā”€ā”ā”‚ā””ā”˜` +- `'double'` - `ā•”ā•ā•—ā•‘ā•šā•` +- `'rounded'` - `╭─╮│╰╯` +- `'heavy'` - `ā”ā”ā”“ā”ƒā”—ā”›` + +## Buffer Operations + +### Clearing + +```typescript +// Clear entire buffer +buffer.clear( + RGBA.fromValues(0.0, 0.0, 0.0, 1.0), // background + ' ' // clear character +) + +// Clear region +buffer.clearRect(10, 5, 20, 10, bg) +``` + +### Blitting + +Copy regions between buffers: + +```typescript +const source = OptimizedBuffer.create(20, 10) +const dest = OptimizedBuffer.create(80, 24) + +// Basic blit +dest.blit(source, 10, 5) + +// Blit with region +dest.blitRegion( + source, + 0, 0, 10, 5, // source region + 20, 10 // destination position +) + +// Blit with alpha blending +dest.blitWithAlpha(source, 10, 5) +``` + +### Merging + +Merge buffers with transparency: + +```typescript +// Merge overlay onto base +base.merge(overlay, 10, 5) + +// Partial merge +base.mergeRegion( + overlay, + 5, 5, 15, 10, // overlay region + 20, 10 // destination +) +``` + +## Performance Features + +### Native FFI Acceleration + +Most operations have optimized Zig implementations: + +```typescript +// Toggle between FFI and JavaScript implementations +buffer.useFFI = false // Use JavaScript fallback +buffer.clearLocal(bg, ' ') // Explicit local implementation + +buffer.useFFI = true // Use native Zig (default) +buffer.clearFFI(bg) // Explicit FFI implementation +``` + +### Direct Buffer Access + +For custom processing: + +```typescript +const buffers = buffer.buffers + +// Direct manipulation +for (let i = 0; i < buffers.char.length; i++) { + if (buffers.char[i] === 32) { // space + buffers.fg[i * 4] = 0.5 // dim foreground + } +} +``` + +### Memory Management + +Buffers are reference-counted in native code: + +```typescript +// Buffers are automatically managed +const buffer = OptimizedBuffer.create(80, 24) +// Native memory allocated + +// When buffer goes out of scope, +// garbage collection handles cleanup +``` + +## Utility Functions + +### Color Blending + +Internal color blending with perceptual adjustments: + +```typescript +// Perceptual alpha curve: +// - Values > 0.8: Subtle curve for near-opaque +// - Values ≤ 0.8: Power curve for smooth blending +``` + +### Drawing Options Packing + +Border configuration is packed into bitfields for efficiency: + +```typescript +// Internally packed as: +// bits 0-3: border sides (top/right/bottom/left) +// bit 4: fill flag +// bits 5-6: title alignment (0=left, 1=center, 2=right) +``` + +## Integration + +### With Renderables + +```typescript +class CustomRenderable extends Renderable { + render(buffer: OptimizedBuffer) { + buffer.drawText( + this.content, + this.x, this.y, + this.fg, this.bg + ) + } +} +``` + +### With TextBuffer + +```typescript +// Convert TextBuffer to OptimizedBuffer +const textBuffer = new TextBuffer(80, 24) +const optimized = textBuffer.toOptimizedBuffer() +``` + +## API Reference + +### Constructor & Factory + +- `OptimizedBuffer.create(width: number, height: number, options?: { respectAlpha?: boolean })` + +### Properties + +- `buffers` - Direct access to typed arrays +- `respectAlpha` - Alpha blending mode +- `id` - Unique buffer identifier + +### Methods + +- `getWidth(): number` +- `getHeight(): number` +- `setRespectAlpha(respectAlpha: boolean): void` +- `clear(bg?: RGBA, clearChar?: string): void` +- `clearRect(x: number, y: number, width: number, height: number, bg: RGBA): void` +- `setCell(x: number, y: number, char: string, fg: RGBA, bg: RGBA, attributes?: number): void` +- `setCellWithAlphaBlending(...): void` +- `get(x: number, y: number): CellData | null` +- `drawText(...): void` +- `drawBox(...): void` +- `drawBoxWithTitle(...): void` +- `blit(source: OptimizedBuffer, x: number, y: number): void` +- `blitRegion(...): void` +- `blitWithAlpha(...): void` +- `merge(source: OptimizedBuffer, x: number, y: number): void` +- `mergeRegion(...): void` + +## Related Modules + +- [Text Buffer](./text-buffer.md) - Higher-level text operations +- [Rendering](./rendering.md) - Integration with renderer +- [Zig](./zig.md) - Native acceleration layer +- [Filters](./filters.md) - Post-processing effects \ No newline at end of file diff --git a/packages/core/docs/modules/components.md b/packages/core/docs/modules/components.md new file mode 100644 index 00000000..29667c46 --- /dev/null +++ b/packages/core/docs/modules/components.md @@ -0,0 +1,252 @@ +# Components + +> **Quick Navigation:** [Getting Started](./getting-started.md) | [Layout](./layout.md) | [Events](./events.md) | [Animation](./animation.md) | [Rendering](./rendering.md) + +OpenTUI provides several built-in components for building terminal UIs. + +## Box Component + +The most fundamental container component, similar to `div` in HTML. + +```typescript +import { BoxRenderable } from '@opentui/core'; + +const box = new BoxRenderable('my-box', { + // Sizing + width: 50, + height: 20, + + // Border + border: true, + borderStyle: 'double', // 'single' | 'double' | 'rounded' | 'heavy' + borderColor: '#00ff00', + + // Background + backgroundColor: '#1e1e1e', + + // Layout + padding: 2, + margin: 1, + + // Flexbox + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'space-between' +}); + +// Custom border characters +const customBox = new BoxRenderable('custom', { + border: true, + customBorderChars: { + topLeft: 'ā•­', + topRight: 'ā•®', + bottomLeft: 'ā•°', + bottomRight: '╯', + horizontal: '─', + vertical: '│' + } +}); +``` + +## Text Component + +Displays text with optional styling and word wrapping. + +```typescript +import { TextRenderable, RGBA } from '@opentui/core'; + +const text = new TextRenderable('my-text', { + text: 'Hello World', + color: RGBA.fromHex('#ffffff'), + backgroundColor: RGBA.fromHex('#0000ff'), + + // Text alignment + align: 'center', // 'left' | 'center' | 'right' + + // Word wrap + wrap: true, + + // Selection + selectable: true, + selectionBg: '#ffff00', + selectionFg: '#000000' +}); + +// Styled text with markup +const styledText = new TextRenderable('styled', { + text: '{red}Error:{/} {bold}File not found{/}', + parseMarkup: true +}); +``` + +## Input Component + +Single-line text input field. + +```typescript +import { InputRenderable } from '@opentui/core'; + +const input = new InputRenderable('username', { + placeholder: 'Enter username...', + value: '', + + // Styling + focusedBorderColor: '#00ff00', + cursorStyle: 'block', // 'block' | 'line' | 'underline' + + // Validation + maxLength: 20, + pattern: /^[a-zA-Z0-9]+$/, + + // Events + onChange: (value) => { + console.log('Input changed:', value); + }, + onSubmit: (value) => { + console.log('Submitted:', value); + } +}); + +// Password input +const password = new InputRenderable('password', { + type: 'password', + mask: '*' +}); +``` + +## Select Component + +Dropdown selection list. + +```typescript +import { SelectRenderable } from '@opentui/core'; + +const select = new SelectRenderable('color-select', { + options: [ + { name: 'Red', value: '#ff0000' }, + { name: 'Green', value: '#00ff00' }, + { name: 'Blue', value: '#0000ff' } + ], + + selected: 0, + visibleOptions: 5, // Max visible at once + + // Styling + selectedBg: '#333333', + selectedFg: '#ffffff', + + // Events + onChange: (option, index) => { + console.log('Selected:', option.name); + } +}); +``` + +## ASCII Font Component + +Display text using ASCII art fonts. + +```typescript +import { ASCIIFontRenderable, fonts } from '@opentui/core'; + +const title = new ASCIIFontRenderable('title', { + text: 'OpenTUI', + font: fonts.block, // Built-in fonts: tiny, block, shade, slick + + // Colors (supports gradients) + fg: [ + RGBA.fromHex('#ff0000'), + RGBA.fromHex('#00ff00'), + RGBA.fromHex('#0000ff') + ] +}); + +// Custom font +import customFont from './my-font.json'; + +const custom = new ASCIIFontRenderable('custom', { + text: 'Custom', + font: customFont as FontDefinition +}); +``` + +## Creating Custom Components + +Extend the Renderable class to create custom components: + +```typescript +import { Renderable, OptimizedBuffer, RGBA } from '@opentui/core'; + +class ProgressBar extends Renderable { + private progress: number = 0; + + setProgress(value: number) { + this.progress = Math.max(0, Math.min(1, value)); + this.needsUpdate(); + } + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + const width = this.computedWidth; + const filled = Math.floor(width * this.progress); + + // Draw filled portion + for (let x = 0; x < filled; x++) { + buffer.setCell( + this.x + x, + this.y, + 'ā–ˆ', + RGBA.fromHex('#00ff00'), + RGBA.fromHex('#000000') + ); + } + + // Draw empty portion + for (let x = filled; x < width; x++) { + buffer.setCell( + this.x + x, + this.y, + 'ā–‘', + RGBA.fromHex('#333333'), + RGBA.fromHex('#000000') + ); + } + } +} +``` + +## Related Topics + +### Layout & Positioning +- [Layout System](./layout.md) - Learn about flexbox properties used by components +- [Getting Started](./getting-started.md#core-concepts) - Understanding component hierarchy + +### Interactivity +- [Event Handling](./events.md) - Add keyboard and mouse interaction to components +- [Event Handling: Forms](./events.md#form-handling) - Building interactive forms with inputs + +### Visual Effects +- [Animation](./animation.md) - Animate component properties +- [Animation: Transitions](./animation.md#transition-effects) - Page and component transitions +- [Rendering: Gradients](./rendering.md#gradient-rendering) - Advanced visual effects + +### Performance +- [Rendering: Optimization](./rendering.md#performance-tips) - Component rendering best practices +- [Rendering: Virtual Scrolling](./rendering.md#virtual-scrolling) - Efficient list rendering + +## Component Patterns + +### Container Components +Components like `BoxRenderable` are containers that use [flexbox layout](./layout.md#flexbox-properties) to arrange children. See the [Layout Guide](./layout.md) for positioning strategies. + +### Interactive Components +`InputRenderable` and other interactive components rely on the [event system](./events.md). Learn about [focus management](./events.md#focus-management) and [keyboard handling](./events.md#keyboard-events). + +### Custom Components +Build your own components by extending `Renderable`. See [Rendering](./rendering.md#custom-cell-rendering) for custom rendering techniques and [Animation](./animation.md#property-animations) for adding motion. + +## Next Steps + +- **Layout:** Learn [flexbox layout](./layout.md) to arrange components +- **Events:** Add [interactivity](./events.md) with keyboard and mouse handling +- **Animation:** Create [smooth transitions](./animation.md) between states +- **Optimization:** Improve performance with [rendering techniques](./rendering.md) diff --git a/packages/core/docs/modules/console.md b/packages/core/docs/modules/console.md new file mode 100644 index 00000000..1d2d8a58 --- /dev/null +++ b/packages/core/docs/modules/console.md @@ -0,0 +1,374 @@ +# Console Module + +The console module provides a terminal-based console window for debugging and logging, with output capture, filtering, and visual inspection capabilities. + +## Overview + +The console module intercepts standard console output and displays it in a customizable terminal panel. It includes caller information tracking, log level filtering, and automatic scrolling. + +## Core Components + +### Console Capture + +Automatic capture of console output: + +```typescript +import { capture } from '@opentui/core/console' + +// Console output is automatically captured +console.log('This is captured') +console.error('Errors too') + +// Access captured output +const stdout = capture.getStdout() +const stderr = capture.getStderr() + +// Clear capture buffers +capture.clear() +``` + +### Terminal Console + +Visual console window in the terminal: + +```typescript +import { TerminalConsole, ConsolePosition } from '@opentui/core' + +const terminalConsole = new TerminalConsole(renderer, { + position: ConsolePosition.BOTTOM, + sizePercent: 30, + zIndex: Infinity, + backgroundColor: '#1a1a1a', + startInDebugMode: false +}) + +// Show/hide console +terminalConsole.show() +terminalConsole.hide() +terminalConsole.toggle() +``` + +## Configuration + +### Console Options + +```typescript +interface ConsoleOptions { + position?: ConsolePosition // TOP, BOTTOM, LEFT, RIGHT + sizePercent?: number // Size as percentage of screen (default: 30) + zIndex?: number // Layer order (default: Infinity) + + // Colors for log levels + colorInfo?: ColorInput // Cyan default + colorWarn?: ColorInput // Yellow default + colorError?: ColorInput // Red default + colorDebug?: ColorInput // Gray default + colorDefault?: ColorInput // White default + + backgroundColor?: ColorInput // Panel background + titleBarColor?: ColorInput // Title bar color + titleBarTextColor?: ColorInput // Title text color + cursorColor?: ColorInput // Cursor/selection color + + title?: string // Console title (default: "Console") + startInDebugMode?: boolean // Enable debug info on start + maxStoredLogs?: number // Max logs to keep (default: 2000) + maxDisplayLines?: number // Max lines to display (default: 3000) +} +``` + +### Default Configuration + +```typescript +const DEFAULT_CONSOLE_OPTIONS = { + position: ConsolePosition.BOTTOM, + sizePercent: 30, + zIndex: Infinity, + colorInfo: "#00FFFF", // Cyan + colorWarn: "#FFFF00", // Yellow + colorError: "#FF0000", // Red + colorDebug: "#808080", // Gray + colorDefault: "#FFFFFF", // White + backgroundColor: RGBA.fromValues(0.1, 0.1, 0.1, 0.7), + title: "Console", + titleBarColor: RGBA.fromValues(0.05, 0.05, 0.05, 0.7), + titleBarTextColor: "#FFFFFF", + cursorColor: "#00A0FF", + maxStoredLogs: 2000, + maxDisplayLines: 3000 +} +``` + +## Console Cache + +### Log Entry Management + +The console cache stores all console output: + +```typescript +// Internal cache management +class TerminalConsoleCache extends EventEmitter { + private _cachedLogs: [Date, LogLevel, any[], CallerInfo | null][] + private readonly MAX_CACHE_SIZE = 1000 + + // Enable/disable caching + setCachingEnabled(enabled: boolean): void + + // Clear all cached logs + clearConsole(): void + + // Enable caller info collection (debug mode) + setCollectCallerInfo(enabled: boolean): void +} +``` + +### Caller Information + +Debug mode captures detailed caller information: + +```typescript +interface CallerInfo { + functionName: string // Function that called console + fullPath: string // Full file path + fileName: string // Just the filename + lineNumber: number // Line number in file + columnNumber: number // Column number +} + +// Enable debug mode to collect caller info +terminalConsole.setDebugMode(true) +``` + +## Display Management + +### Scrolling + +Console supports smooth scrolling: + +```typescript +// Scroll controls +terminalConsole.scrollUp(lines?: number) // Default: 1 line +terminalConsole.scrollDown(lines?: number) +terminalConsole.scrollToTop() +terminalConsole.scrollToBottom() +terminalConsole.pageUp() // Scroll by visible height +terminalConsole.pageDown() + +// Auto-scroll to bottom on new logs +terminalConsole.setAutoScroll(true) +``` + +### Filtering + +Filter logs by level: + +```typescript +// Show only specific log levels +terminalConsole.setLogLevelFilter([ + LogLevel.ERROR, + LogLevel.WARN +]) + +// Or use convenience methods +terminalConsole.showOnlyErrors() +terminalConsole.showAll() +``` + +### Search + +Search through console output: + +```typescript +// Search for text +terminalConsole.search('error') +terminalConsole.searchNext() +terminalConsole.searchPrevious() +terminalConsole.clearSearch() +``` + +## Keyboard Shortcuts + +Built-in keyboard navigation: + +``` +Escape - Close console +Tab - Toggle focus +D - Toggle debug mode +C - Clear console +↑/↓ - Scroll up/down +Page Up/Dn - Page scroll +Home/End - Jump to top/bottom +/ - Start search +n/N - Next/previous search result +``` + +## Rendering + +### Frame Buffer + +Console uses optimized rendering: + +```typescript +// Console maintains its own frame buffer +private frameBuffer: OptimizedBuffer | null +private _needsFrameBufferUpdate: boolean + +// Mark for re-render +private markNeedsUpdate(): void { + this._needsFrameBufferUpdate = true + this.renderer.needsUpdate() +} +``` + +### Display Lines + +Log entries are formatted for display: + +```typescript +interface DisplayLine { + text: string // Formatted text + level: LogLevel // Log level for coloring + indent: boolean // Whether to indent (for multi-line) +} +``` + +## Output Capture + +### Captured Streams + +Intercept stdout/stderr: + +```typescript +// Automatic stream capture +const mockStdout = new CapturedWritableStream("stdout", capture) +const mockStderr = new CapturedWritableStream("stderr", capture) + +// Global console replacement +global.console = new console.Console({ + stdout: mockStdout, + stderr: mockStderr, + colorMode: true, + inspectOptions: { + compact: false, + breakLength: 80, + depth: 2 + } +}) +``` + +### Environment Variables + +Control console behavior: + +```bash +# Skip console capture +SKIP_CONSOLE_CACHE=true + +# Auto-show console on start +SHOW_CONSOLE=true +``` + +## Integration + +### With Renderer + +```typescript +class MyApp { + private renderer: CliRenderer + private console: TerminalConsole + + constructor() { + this.renderer = new CliRenderer() + this.console = new TerminalConsole(this.renderer, { + position: ConsolePosition.BOTTOM, + sizePercent: 25 + }) + + // Console renders automatically when visible + this.console.show() + } + + handleError(error: Error) { + console.error('Application error:', error) + this.console.show() // Show console on error + } +} +``` + +### With Logging + +```typescript +// Custom log formatting +terminalConsole.on('entry', (entry) => { + const [date, level, args, caller] = entry + + // Save to file + fs.appendFileSync('app.log', + `${date.toISOString()} [${level}] ${args.join(' ')}\n` + ) +}) +``` + +## Advanced Features + +### Debug Mode + +Enhanced debugging information: + +```typescript +// Toggle debug mode +terminalConsole.toggleDebugMode() + +// When enabled, shows: +// - Function names +// - File paths +// - Line/column numbers +// - Stack traces for errors +``` + +### Export Logs + +Export console content: + +```typescript +// Get all logs +const logs = terminalConsole.exportLogs() + +// Get filtered logs +const errors = terminalConsole.exportLogs({ + levels: [LogLevel.ERROR], + limit: 100 +}) + +// Save to file +terminalConsole.saveLogsToFile('debug.log') +``` + +## API Reference + +### Classes + +- `TerminalConsole` - Main console window class +- `TerminalConsoleCache` - Console output cache +- `Capture` - Output capture manager +- `CapturedWritableStream` - Stream interceptor + +### Enums + +- `LogLevel` - LOG, INFO, WARN, ERROR, DEBUG +- `ConsolePosition` - TOP, BOTTOM, LEFT, RIGHT + +### Functions + +- `getCallerInfo(): CallerInfo | null` - Extract caller information + +### Exports + +- `capture` - Global capture instance +- `terminalConsoleCache` - Global cache instance + +## Related Modules + +- [Rendering](./rendering.md) - Console rendering integration +- [Buffer](./buffer.md) - Frame buffer management +- [Lib](./lib.md) - Color parsing and utilities \ No newline at end of file diff --git a/packages/core/docs/modules/events.md b/packages/core/docs/modules/events.md new file mode 100644 index 00000000..db9cbed6 --- /dev/null +++ b/packages/core/docs/modules/events.md @@ -0,0 +1,332 @@ +# Event Handling + +OpenTUI provides comprehensive keyboard and mouse event handling. + +## Keyboard Events + +```typescript +import { Renderable, ParsedKey } from '@opentui/core'; + +class MyComponent extends Renderable { + constructor(id: string) { + super(id, { + onKeyDown: (key: ParsedKey) => { + // Handle key press + if (key.name === 'escape') { + this.handleEscape(); + return true; // Prevent bubbling + } + + // Arrow keys + if (key.name === 'up') this.moveUp(); + if (key.name === 'down') this.moveDown(); + if (key.name === 'left') this.moveLeft(); + if (key.name === 'right') this.moveRight(); + + // Modifiers + if (key.ctrl && key.name === 'c') { + this.copy(); + } + + // Regular characters + if (key.name.length === 1) { + this.handleCharacter(key.name); + } + + return false; // Allow bubbling + } + }); + } +} +``` + +### ParsedKey Structure + +```typescript +interface ParsedKey { + name: string; // Key name ('a', 'enter', 'escape', etc.) + ctrl: boolean; // Ctrl key held + meta: boolean; // Meta/Cmd key held + shift: boolean; // Shift key held + option: boolean; // Alt/Option key held + sequence: string; // Raw escape sequence + raw: string; // Raw input + code?: string; // Key code if available +} +``` + +### Common Key Names +- Letters: 'a' through 'z' +- Numbers: '0' through '9' +- Special: 'enter', 'escape', 'backspace', 'delete', 'tab', 'space' +- Navigation: 'up', 'down', 'left', 'right', 'home', 'end', 'pageup', 'pagedown' +- Function: 'f1' through 'f12' + +## Mouse Events + +```typescript +class ClickableComponent extends Renderable { + private isHovered = false; + private isDragging = false; + private dragStart = { x: 0, y: 0 }; + + constructor(id: string) { + super(id, { + onMouseDown: (event: MouseEvent) => { + if (event.button === 0) { // Left click + this.isDragging = true; + this.dragStart = { x: event.x, y: event.y }; + event.preventDefault(); + } else if (event.button === 2) { // Right click + this.showContextMenu(event.x, event.y); + } + }, + + onMouseUp: (event: MouseEvent) => { + if (this.isDragging) { + this.isDragging = false; + this.handleDrop(event.x, event.y); + } + }, + + onMouseDrag: (event: MouseEvent) => { + if (this.isDragging) { + const dx = event.x - this.dragStart.x; + const dy = event.y - this.dragStart.y; + this.handleDrag(dx, dy); + } + }, + + onMouseOver: (event: MouseEvent) => { + this.isHovered = true; + this.updateHoverState(); + }, + + onMouseOut: (event: MouseEvent) => { + this.isHovered = false; + this.updateHoverState(); + }, + + onMouseScroll: (event: MouseEvent) => { + if (event.scroll.direction === 'up') { + this.scrollUp(event.scroll.delta); + } else { + this.scrollDown(event.scroll.delta); + } + } + }); + } +} +``` + +### MouseEvent Structure + +```typescript +interface MouseEvent { + type: MouseEventType; // Event type + button: number; // 0=left, 1=middle, 2=right + x: number; // X coordinate in terminal + y: number; // Y coordinate in terminal + modifiers: { + shift: boolean; + alt: boolean; + ctrl: boolean; + }; + scroll?: { + direction: 'up' | 'down' | 'left' | 'right'; + delta: number; + }; + target: Renderable | null; // Target component + source: Renderable; // Source component + + preventDefault(): void; // Stop default behavior +} +``` + +## Focus Management + +```typescript +class FocusableList extends Renderable { + private focusedIndex = 0; + private items: Renderable[] = []; + + constructor(id: string) { + super(id, { + onKeyDown: (key) => { + if (key.name === 'tab') { + if (key.shift) { + this.focusPrevious(); + } else { + this.focusNext(); + } + return true; // Prevent default tab behavior + } + } + }); + } + + focusNext() { + this.items[this.focusedIndex]?.blur(); + this.focusedIndex = (this.focusedIndex + 1) % this.items.length; + this.items[this.focusedIndex]?.focus(); + } + + focusPrevious() { + this.items[this.focusedIndex]?.blur(); + this.focusedIndex = (this.focusedIndex - 1 + this.items.length) % this.items.length; + this.items[this.focusedIndex]?.focus(); + } +} +``` + +## Event Delegation + +```typescript +class EventDelegate extends Renderable { + private handlers = new Map(); + + constructor(id: string) { + super(id, { + onMouseDown: (event) => { + // Delegate to child components based on data attributes + const target = event.target; + if (target && target.data?.action) { + const handler = this.handlers.get(target.data.action); + if (handler) { + handler(event); + } + } + } + }); + } + + registerHandler(action: string, handler: Function) { + this.handlers.set(action, handler); + } + + createButton(text: string, action: string) { + const button = new BoxRenderable(`btn-${action}`, { + padding: 1, + border: true, + data: { action } // Custom data for delegation + }); + button.add(new TextRenderable('label', { text })); + return button; + } +} +``` + +## Global Shortcuts + +```typescript +class Application extends Renderable { + private shortcuts = new Map(); + + constructor() { + super('app', { + onKeyDown: (key) => { + const shortcut = this.getShortcutKey(key); + const handler = this.shortcuts.get(shortcut); + + if (handler) { + handler(); + return true; // Handled + } + + return false; // Pass through + } + }); + + // Register shortcuts + this.registerShortcut('ctrl+s', () => this.save()); + this.registerShortcut('ctrl+o', () => this.open()); + this.registerShortcut('ctrl+q', () => this.quit()); + } + + private getShortcutKey(key: ParsedKey): string { + const parts = []; + if (key.ctrl) parts.push('ctrl'); + if (key.shift) parts.push('shift'); + if (key.alt) parts.push('alt'); + parts.push(key.name); + return parts.join('+'); + } + + registerShortcut(keys: string, handler: Function) { + this.shortcuts.set(keys, handler); + } +} +``` + +## Related Topics + +### Interactive Components +- [Components: Input](./components.md#input-component) - Text input with keyboard handling +- [Components: Custom](./components.md#custom-components) - Building interactive components +- [Getting Started](./getting-started.md#core-concepts) - Event system overview + +### Visual Feedback +- [Animation: Properties](./animation.md#property-animations) - Animate on user interaction +- [Animation: Transitions](./animation.md#transition-effects) - Smooth state changes +- [Rendering: Effects](./rendering.md#advanced-rendering-techniques) - Visual feedback effects + +### Layout Integration +- [Layout: Responsive](./layout.md#layout-patterns) - Handling resize events +- [Layout: Scrollable](./layout.md#scrollable-content) - Scroll event handling +- [Components: Box](./components.md#box-component) - Container event bubbling + +## Event Patterns + +### Form Handling +Build interactive forms using: +- [Components: Input](./components.md#input-component) - Text input fields +- [Layout: Forms](./layout.md#layout-patterns) - Form layout patterns +- [Animation: Validation](./animation.md#complex-animation-examples) - Animated validation feedback + +### Drag and Drop +Implement drag operations with: +- Mouse event tracking (see examples above) +- [Animation: Movement](./animation.md#property-animations) - Smooth dragging +- [Rendering: Layers](./rendering.md#advanced-rendering-techniques) - Z-index management + +### Keyboard Navigation +Create accessible interfaces: +- Tab order management +- Focus indicators with [Rendering: Effects](./rendering.md#shadow-effects) +- Keyboard shortcuts (see examples above) + +## Best Practices + +1. **Event Delegation:** Use bubbling for parent containers to handle child events +2. **Debouncing:** Throttle rapid events like scroll or mouse move +3. **Focus Management:** Maintain logical tab order for accessibility +4. **Visual Feedback:** Always provide feedback for user actions +5. **Prevent Default:** Stop propagation when handling events + +## Troubleshooting + +### Common Issues +- **Events not firing:** Check focus state and event bubbling +- **Multiple handlers:** Use `stopPropagation()` to prevent bubbling +- **Performance:** Debounce rapid events like mouse move +- **Focus issues:** Ensure components are focusable + +### Debug Events +```typescript +class EventDebugger extends Renderable { + constructor(id: string) { + super(id, { + onMouseDown: (e) => console.log('MouseDown:', e), + onKeyDown: (k) => console.log('KeyDown:', k), + // Log all events + }); + } +} +``` + +## Next Steps + +- **Build Forms:** Create interactive forms with [Components](./components.md) +- **Add Motion:** Respond to events with [Animations](./animation.md) +- **Optimize:** Handle events efficiently with [Rendering](./rendering.md) techniques +- **Layout:** Create responsive layouts that handle [resize events](./layout.md) diff --git a/packages/core/docs/modules/filters.md b/packages/core/docs/modules/filters.md new file mode 100644 index 00000000..8a38c426 --- /dev/null +++ b/packages/core/docs/modules/filters.md @@ -0,0 +1,293 @@ +# Post-Processing Filters Module + +The filters module provides real-time post-processing effects for terminal rendering, operating directly on OptimizedBuffer data structures for performance. + +## Overview + +Post-processing filters manipulate the rendered buffer's foreground/background colors and characters to create visual effects. All filters work with normalized color values (0.0-1.0) in Float32Array buffers. + +## Static Filter Functions + +### Scanlines + +Apply retro CRT-style scanline effect: + +```typescript +import { applyScanlines } from '@opentui/core/post/filters' + +// Darken every 2nd row to 80% brightness +applyScanlines(buffer, 0.8, 2) + +// Stronger effect with wider gaps +applyScanlines(buffer, 0.5, 3) +``` + +### Grayscale + +Convert colors to grayscale using luminance calculation: + +```typescript +import { applyGrayscale } from '@opentui/core/post/filters' + +// Convert entire buffer to grayscale +applyGrayscale(buffer) +// Uses formula: 0.299*R + 0.587*G + 0.114*B +``` + +### Sepia + +Apply vintage sepia tone effect: + +```typescript +import { applySepia } from '@opentui/core/post/filters' + +// Apply sepia tone transformation +applySepia(buffer) +// Uses standard sepia matrix transformation +``` + +### Invert + +Invert all colors: + +```typescript +import { applyInvert } from '@opentui/core/post/filters' + +// Invert fg and bg colors +applyInvert(buffer) +// Each channel becomes 1.0 - original +``` + +### Noise + +Add random noise for texture: + +```typescript +import { applyNoise } from '@opentui/core/post/filters' + +// Add subtle noise +applyNoise(buffer, 0.1) + +// Heavy static effect +applyNoise(buffer, 0.3) +``` + +### Chromatic Aberration + +Simulate lens distortion with color channel separation: + +```typescript +import { applyChromaticAberration } from '@opentui/core/post/filters' + +// Subtle aberration +applyChromaticAberration(buffer, 1) + +// Strong RGB separation +applyChromaticAberration(buffer, 3) +``` + +### ASCII Art + +Convert buffer to ASCII art based on brightness: + +```typescript +import { applyAsciiArt } from '@opentui/core/post/filters' + +// Default ramp: " .:-=+*#%@" +applyAsciiArt(buffer) + +// Custom character ramp +applyAsciiArt(buffer, " ā–‘ā–’ā–“ā–ˆ") +``` + +## Effect Classes + +### DistortionEffect + +Animated glitch/distortion effect with configurable parameters: + +```typescript +import { DistortionEffect } from '@opentui/core/post/filters' + +const distortion = new DistortionEffect({ + glitchChancePerSecond: 0.5, + maxGlitchLines: 3, + minGlitchDuration: 0.05, + maxGlitchDuration: 0.2, + maxShiftAmount: 10, + shiftFlipRatio: 0.6, + colorGlitchChance: 0.2 +}) + +// Apply with delta time for animation +distortion.apply(buffer, deltaTime) +``` + +Glitch types: +- **shift**: Horizontal pixel shifting with wrap-around +- **flip**: Horizontal line mirroring +- **color**: Random color corruption + +### VignetteEffect + +Darken corners for cinematic framing: + +```typescript +import { VignetteEffect } from '@opentui/core/post/filters' + +const vignette = new VignetteEffect(0.5) + +// Apply vignette +vignette.apply(buffer) + +// Adjust strength dynamically +vignette.strength = 0.8 +``` + +Features: +- Precomputed distance attenuation for performance +- Automatic recalculation on buffer resize +- Non-negative strength clamping + +### BrightnessEffect + +Adjust overall brightness: + +```typescript +import { BrightnessEffect } from '@opentui/core/post/filters' + +const brightness = new BrightnessEffect(1.0) + +// Darken to 50% +brightness.brightness = 0.5 +brightness.apply(buffer) + +// Brighten by 20% +brightness.brightness = 1.2 +brightness.apply(buffer) +``` + +### BlurEffect + +Optimized separable box blur with character modification: + +```typescript +import { BlurEffect } from '@opentui/core/post/filters' + +const blur = new BlurEffect(2) + +// Apply blur +blur.apply(buffer) + +// Adjust radius +blur.radius = 3 +``` + +Features: +- Sliding window optimization for O(n) complexity +- Separate horizontal/vertical passes +- Character ramp based on alpha: `[" ", "ā–‘", "ā–’", "ā–“", " "]` + +### BloomEffect + +Light bloom based on brightness threshold: + +```typescript +import { BloomEffect } from '@opentui/core/post/filters' + +const bloom = new BloomEffect( + 0.8, // threshold (0-1) + 0.2, // strength + 2 // radius in pixels +) + +// Apply bloom to bright areas +bloom.apply(buffer) + +// Adjust parameters +bloom.threshold = 0.7 +bloom.strength = 0.3 +bloom.radius = 3 +``` + +Features: +- Luminance-based bright pixel detection +- Linear distance falloff +- Additive blending with clamping + +## Performance Considerations + +### Direct Buffer Manipulation + +All filters operate directly on OptimizedBuffer's typed arrays: +- `buffer.buffers.fg` - Float32Array for foreground colors +- `buffer.buffers.bg` - Float32Array for background colors +- `buffer.buffers.char` - Uint32Array for characters +- `buffer.buffers.attributes` - Uint8Array for text attributes + +### Optimization Techniques + +1. **Precomputation**: VignetteEffect caches distance calculations +2. **Separable Filters**: BlurEffect uses two 1D passes instead of 2D +3. **Sliding Window**: Blur uses moving average for O(n) complexity +4. **In-place Operations**: Most filters modify buffers directly +5. **Early Exit**: Effects skip processing when parameters indicate no change + +## Integration Example + +```typescript +import { CliRenderer } from '@opentui/core' +import { + applyGrayscale, + VignetteEffect, + DistortionEffect +} from '@opentui/core/post/filters' + +const renderer = new CliRenderer() +const vignette = new VignetteEffect(0.5) +const distortion = new DistortionEffect() + +let lastTime = Date.now() + +function render() { + const now = Date.now() + const deltaTime = (now - lastTime) / 1000 + lastTime = now + + const buffer = renderer.getBuffer() + + // Apply effects in sequence + applyGrayscale(buffer) + vignette.apply(buffer) + distortion.apply(buffer, deltaTime) + + renderer.render() + requestAnimationFrame(render) +} +``` + +## API Reference + +### Functions + +- `applyScanlines(buffer: OptimizedBuffer, strength?: number, step?: number): void` +- `applyGrayscale(buffer: OptimizedBuffer): void` +- `applySepia(buffer: OptimizedBuffer): void` +- `applyInvert(buffer: OptimizedBuffer): void` +- `applyNoise(buffer: OptimizedBuffer, strength?: number): void` +- `applyChromaticAberration(buffer: OptimizedBuffer, strength?: number): void` +- `applyAsciiArt(buffer: OptimizedBuffer, ramp?: string): void` + +### Classes + +- `DistortionEffect` - Animated glitch effects +- `VignetteEffect` - Corner darkening +- `BrightnessEffect` - Brightness adjustment +- `BlurEffect` - Box blur with character modification +- `BloomEffect` - Light bloom for bright areas + +## Related Modules + +- [Buffer](./buffer.md) - OptimizedBuffer structure +- [Rendering](./rendering.md) - Core rendering pipeline +- [Animation](./animation.md) - Timeline for animating effects \ No newline at end of file diff --git a/packages/core/docs/modules/guide.md b/packages/core/docs/modules/guide.md new file mode 100644 index 00000000..1120e695 --- /dev/null +++ b/packages/core/docs/modules/guide.md @@ -0,0 +1,91 @@ +# Getting Started with OpenTUI + +> **Quick Navigation:** [Components](./components.md) | [Layout](./layout.md) | [Events](./events.md) | [Animation](./animation.md) | [Rendering](./rendering.md) + +OpenTUI is a terminal UI framework for building rich, interactive command-line applications with a React-like component model. + +## Installation + +```bash +npm install @opentui/core +# or +bun add @opentui/core +``` + +## Basic Example + +```typescript +import { CliRenderer, BoxRenderable, TextRenderable } from '@opentui/core'; + +// Create the renderer +const renderer = new CliRenderer( + lib, // Native library handle + rendererPtr, // Renderer pointer + process.stdin, + process.stdout, + 80, // Width + 24, // Height + {} // Config +); + +// Create a box with text inside +const box = new BoxRenderable('main-box', { + width: '100%', + height: '100%', + border: true, + borderStyle: 'rounded', + padding: 2 +}); + +const text = new TextRenderable('hello', { + text: 'Hello, OpenTUI!' +}); + +// Build component tree +box.add(text); +renderer.root.add(box); + +// Start rendering +renderer.start(); +``` + +## Core Concepts + +### Renderables +Everything you see on screen is a Renderable - the base class for all UI components. +→ Learn more: [Components Guide](./components.md) + +### Layout System +OpenTUI uses Yoga (Facebook's flexbox implementation) for layout: +- Supports flexbox properties +- Percentage-based sizing +- Absolute and relative positioning +→ Learn more: [Layout System](./layout.md) + +### Event System +- Keyboard events flow through focused components +- Mouse events use bubbling similar to the web +- Components can prevent default behavior +→ Learn more: [Event Handling](./events.md) + +### Render Loop +1. Input processing +2. Layout calculation +3. Component rendering to buffer +4. Buffer diff and terminal update +→ Learn more: [Rendering System](./rendering.md) + +## Next Steps + +- **Build UI:** Start with the [Components Guide](./components.md) to learn about available components +- **Handle Input:** Read the [Events Guide](./events.md) for keyboard and mouse handling +- **Add Motion:** Check out [Animations](./animation.md) for transitions and effects +- **Optimize:** Learn about performance in the [Rendering Guide](./rendering.md) + +## Related Topics + +- [Components](./components.md) - Built-in UI components and how to use them +- [Layout System](./layout.md) - Flexbox layout and positioning +- [Event Handling](./events.md) - Keyboard and mouse interaction +- [Animation](./animation.md) - Creating smooth animations +- [Rendering](./rendering.md) - Understanding the render pipeline diff --git a/packages/core/docs/modules/index.md b/packages/core/docs/modules/index.md new file mode 100644 index 00000000..c25ec09d --- /dev/null +++ b/packages/core/docs/modules/index.md @@ -0,0 +1,134 @@ +# OpenTUI Module Documentation + +Complete documentation for all OpenTUI core modules, organized by functionality. + +## Core Modules + +### [Rendering](./rendering.md) +Core rendering system with double buffering, dirty region tracking, and frame management. + +### [Buffer](./buffer.md) +High-performance `OptimizedBuffer` class with native Zig acceleration for terminal display operations. + +### [Text Buffer](./text-buffer.md) +Efficient text manipulation and buffer management for terminal rendering with styling support. + +### [Components](./components.md) +Built-in UI components including Box, Text, Input, Select, TabSelect, ASCIIFont, and FrameBuffer. + +## Utility Modules + +### [Lib](./lib.md) +Essential utilities including RGBA colors, styled text, borders, ASCII fonts, input handling, and selection management. + +### [Utils](./utils.md) +Helper functions including `createTextAttributes` for simplified text styling. + +### [Types](./types.md) +TypeScript type definitions, enums, and interfaces for type safety across the framework. + +## Visual Effects + +### [Animation](./animation.md) +Timeline-based animation system with easing functions, keyframes, and property interpolation. + +### [Post-Processing Filters](./filters.md) +Real-time visual effects including blur, glow, distortion, vignette, and color transformations. + +### [3D](./3d.md) +WebGPU and Three.js integration for 3D graphics, sprites, particles, and physics in the terminal. + +## System Integration + +### [Events](./events.md) +Event system for keyboard, mouse, resize, and custom events with bubbling and capturing. + +### [Console](./console.md) +Terminal-based debugging console with output capture, filtering, and visual inspection. + +### [Layout](./layout.md) +Flexbox-inspired layout system using Yoga for automatic component positioning. + +## Native Performance + +### [Zig](./zig.md) +High-performance native acceleration through FFI bindings for rendering and buffer operations. + +## Module Categories + +### Rendering Pipeline +1. **Buffer** - Low-level buffer operations +2. **Text Buffer** - Text-specific buffer management +3. **Rendering** - Core rendering loop +4. **Components** - UI component rendering +5. **Post-Processing Filters** - Visual effects + +### Component System +1. **Components** - Built-in UI components +2. **Layout** - Component positioning +3. **Events** - User interaction +4. **Animation** - Component animation + +### Development Tools +1. **Console** - Debug output and logging +2. **Types** - Type definitions +3. **Utils** - Helper functions + +### Advanced Features +1. **3D** - 3D graphics support +2. **Zig** - Native acceleration +3. **Lib** - Core utilities + +## Quick Start Examples + +### Basic Rendering +```typescript +import { CliRenderer, BoxRenderable, TextRenderable } from '@opentui/core' + +const renderer = new CliRenderer() +const box = new BoxRenderable('container', { + width: 40, + height: 10, + border: true +}) + +const text = new TextRenderable('label', { + content: 'Hello, OpenTUI!' +}) + +box.appendChild(text) +renderer.appendChild(box) +renderer.render() +``` + +### With Animation +```typescript +import { Timeline } from '@opentui/core' + +const timeline = new Timeline() +timeline.add({ + target: box, + property: 'x', + from: 0, + to: 40, + duration: 1000, + easing: 'easeInOut' +}) +timeline.play() +``` + +### With Effects +```typescript +import { VignetteEffect, applyGrayscale } from '@opentui/core/post/filters' + +const vignette = new VignetteEffect(0.5) +const buffer = renderer.getBuffer() + +applyGrayscale(buffer) +vignette.apply(buffer) +renderer.render() +``` + +## API Reference + +For detailed API documentation of types and methods, see the [reference](../reference/index.md) directory. diff --git a/packages/core/docs/modules/layout.md b/packages/core/docs/modules/layout.md new file mode 100644 index 00000000..f4c38dfe --- /dev/null +++ b/packages/core/docs/modules/layout.md @@ -0,0 +1,243 @@ +# Layout System + +OpenTUI uses Facebook's Yoga layout engine, providing flexbox layout for terminal UIs. + +## Basic Layout + +```typescript +const container = new BoxRenderable('container', { + width: '100%', + height: '100%', + flexDirection: 'column' +}); + +const header = new BoxRenderable('header', { + height: 3, + width: '100%', + backgroundColor: '#333333' +}); + +const content = new BoxRenderable('content', { + flexGrow: 1, // Take remaining space + width: '100%' +}); + +const footer = new BoxRenderable('footer', { + height: 3, + width: '100%', + backgroundColor: '#333333' +}); + +container.add(header); +container.add(content); +container.add(footer); +``` + +## Flexbox Properties + +### Container Properties + +```typescript +const flex = new BoxRenderable('flex', { + // Direction + flexDirection: 'row', // 'row' | 'column' | 'row-reverse' | 'column-reverse' + + // Alignment + alignItems: 'center', // Cross-axis alignment + justifyContent: 'center', // Main-axis alignment + + // Wrapping + flexWrap: 'wrap', // 'nowrap' | 'wrap' | 'wrap-reverse' + + // Gap between items + gap: 2 +}); +``` + +### Item Properties + +```typescript +const item = new BoxRenderable('item', { + // Flex properties + flexGrow: 1, // Grow factor + flexShrink: 1, // Shrink factor + flexBasis: 100, // Base size before flex + + // Self alignment + alignSelf: 'stretch' // Override parent's alignItems +}); +``` + +## Grid Layout + +Create grid layouts using nested flexbox: + +```typescript +function createGrid(rows: number, cols: number) { + const grid = new BoxRenderable('grid', { + flexDirection: 'column', + width: '100%', + height: '100%' + }); + + for (let r = 0; r < rows; r++) { + const row = new BoxRenderable(`row-${r}`, { + flexDirection: 'row', + height: `${100 / rows}%`, + width: '100%' + }); + + for (let c = 0; c < cols; c++) { + const cell = new BoxRenderable(`cell-${r}-${c}`, { + width: `${100 / cols}%`, + height: '100%', + border: true + }); + row.add(cell); + } + + grid.add(row); + } + + return grid; +} +``` + +## Absolute Positioning + +```typescript +const overlay = new BoxRenderable('overlay', { + position: 'absolute', + top: 10, + left: 10, + width: 40, + height: 10, + backgroundColor: 'rgba(0, 0, 0, 0.8)', + zIndex: 100 +}); +``` + +## Responsive Layout + +```typescript +class ResponsiveContainer extends BoxRenderable { + constructor(id: string) { + super(id, {}); + this.updateLayout(); + } + + updateLayout() { + const width = this.parent?.computedWidth || 80; + + if (width < 40) { + // Mobile layout + this.setOptions({ + flexDirection: 'column', + padding: 1 + }); + } else if (width < 80) { + // Tablet layout + this.setOptions({ + flexDirection: 'row', + flexWrap: 'wrap', + padding: 2 + }); + } else { + // Desktop layout + this.setOptions({ + flexDirection: 'row', + flexWrap: 'nowrap', + padding: 3 + }); + } + } +} +``` + +## Scrollable Content + +```typescript +class ScrollableBox extends BoxRenderable { + private scrollOffset = 0; + + constructor(id: string, options: BoxOptions) { + super(id, { + ...options, + overflow: 'hidden' + }); + + this.onMouseScroll = (event) => { + if (event.scroll.direction === 'up') { + this.scrollOffset = Math.max(0, this.scrollOffset - 1); + } else { + this.scrollOffset = Math.min( + this.getContentHeight() - this.computedHeight, + this.scrollOffset + 1 + ); + } + this.needsUpdate(); + }; + } + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + // Render with scroll offset + const originalY = this.y; + this.y -= this.scrollOffset; + super.renderSelf(buffer, deltaTime); + this.y = originalY; + } +} +``` + +## Related Topics + +### Component Layout +- [Components: Box](./components.md#box-component) - Container component with flexbox support +- [Components: Text](./components.md#text-component) - Text alignment and wrapping +- [Getting Started](./getting-started.md#core-concepts) - Layout fundamentals + +### Dynamic Layouts +- [Events: Window](./events.md#window-events) - Handling terminal resize +- [Animation: Properties](./animation.md#property-animations) - Animating layout changes +- [Animation: Transitions](./animation.md#transition-effects) - Smooth layout transitions + +### Performance +- [Rendering: Optimization](./rendering.md#performance-tips) - Layout performance tips +- [Rendering: Virtual Scrolling](./rendering.md#virtual-scrolling) - Efficient scrollable layouts +- [Rendering: Culling](./rendering.md#render-optimization-strategies) - Skip rendering off-screen elements + +## Layout Patterns + +### Common Patterns +For implementation examples of common layouts: +- **Forms:** See [Events: Form Handling](./events.md#form-handling) and [Components: Input](./components.md#input-component) +- **Grids:** Check [Components: Patterns](./components.md#component-patterns) +- **Modals/Dialogs:** Review [Animation: Toast](./animation.md#notification-toast-animation) +- **Sidebars:** See flexbox examples above + +### Responsive Techniques +- Use percentage widths: `width: '50%'` +- Flexbox grow/shrink: `flexGrow: 1` +- Media queries via terminal size detection +- See [Events](./events.md) for resize handling + +### Layout Animation +Combine layout with smooth animations: +- [Animation: Timeline](./animation.md#timeline-animations) - Orchestrate multiple layout changes +- [Animation: Sequencing](./animation.md#animation-sequencing) - Chain layout animations +- [Components](./components.md) - Animated component examples + +## Best Practices + +1. **Use Flexbox:** Leverage flexbox for responsive layouts instead of absolute positioning +2. **Percentage Sizing:** Use percentages for responsive designs +3. **Container Components:** Wrap related items in [Box components](./components.md#box-component) +4. **Virtual Scrolling:** For long lists, implement [virtual scrolling](./rendering.md#virtual-scrolling) +5. **Layout Caching:** Cache complex layouts to improve [rendering performance](./rendering.md#caching-complex-renders) + +## Next Steps + +- **Build UIs:** Create interfaces with the [component library](./components.md) +- **Add Interaction:** Make layouts interactive with [event handling](./events.md) +- **Animate Changes:** Add motion with the [animation system](./animation.md) +- **Optimize Performance:** Learn [rendering techniques](./rendering.md) diff --git a/packages/core/docs/modules/lib.md b/packages/core/docs/modules/lib.md new file mode 100644 index 00000000..76063e95 --- /dev/null +++ b/packages/core/docs/modules/lib.md @@ -0,0 +1,258 @@ +# Lib Utilities Module + +The lib module provides essential utility functions and classes that power OpenTUI's core functionality, including styling, borders, fonts, and input handling. + +## Overview + +This module contains foundational utilities used throughout OpenTUI for text styling, border rendering, ASCII fonts, color management, and keyboard/mouse input parsing. + +## Core Components + +### RGBA Color Management + +```typescript +import { RGBA } from '@opentui/core/lib' + +const red = new RGBA(255, 0, 0, 255) +const semitransparent = new RGBA(0, 0, 255, 128) + +// Color blending +const blended = RGBA.blend(red, semitransparent) + +// Color interpolation +const gradient = RGBA.interpolate(red, blue, 0.5) +``` + +### Styled Text + +Rich text formatting with ANSI escape sequences: + +```typescript +import { StyledText, parseStyledText } from '@opentui/core/lib' + +const styled = new StyledText('Hello World') + .fg(255, 0, 0) + .bg(0, 0, 255) + .bold() + .underline() + +const ansi = styled.toANSI() + +// Parse existing styled text +const parsed = parseStyledText('\x1b[31mRed Text\x1b[0m') +``` + +### Border Rendering + +Flexible border system with multiple styles: + +```typescript +import { Border, BorderStyle } from '@opentui/core/lib' + +const border = new Border({ + style: BorderStyle.Double, + fg: new RGBA(255, 255, 255, 255), + padding: 2 +}) + +// Render border to buffer +border.render(buffer, x, y, width, height) + +// Available styles +BorderStyle.Single // ā”Œā”€ā” +BorderStyle.Double // ╔═╗ +BorderStyle.Rounded // ╭─╮ +BorderStyle.Heavy // ā”ā”ā”“ +``` + +### ASCII Fonts + +Decorative text rendering with ASCII art fonts: + +```typescript +import { ASCIIFont } from '@opentui/core/lib' + +const font = new ASCIIFont({ + font: 'block', + fg: new RGBA(255, 255, 0, 255) +}) + +const rendered = font.render('HELLO') +// ā–ˆā–ˆā•— ā–ˆā–ˆā•—ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•—ā–ˆā–ˆā•— ā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•— +// ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ā–ˆā–ˆā•”ā•ā•ā•ā•ā•ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ ā–ˆā–ˆā•”ā•ā•ā•ā–ˆā–ˆā•— +// ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•‘ā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ +// ā–ˆā–ˆā•”ā•ā•ā–ˆā–ˆā•‘ā–ˆā–ˆā•”ā•ā•ā• ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ +// ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•—ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•—ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•—ā•šā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•”ā• +// ā•šā•ā• ā•šā•ā•ā•šā•ā•ā•ā•ā•ā•ā•ā•šā•ā•ā•ā•ā•ā•ā•ā•šā•ā•ā•ā•ā•ā•ā• ā•šā•ā•ā•ā•ā•ā• +``` + +## Input Handling + +### KeyHandler + +Sophisticated keyboard input management: + +```typescript +import { KeyHandler } from '@opentui/core/lib' + +const handler = new KeyHandler() + +handler.on('ctrl+c', () => process.exit(0)) +handler.on('arrow-up', () => moveCursor(-1)) +handler.on('enter', () => submitForm()) + +// Complex key combinations +handler.on('ctrl+shift+p', () => openCommandPalette()) + +// Key sequences +handler.sequence(['g', 'g'], () => goToTop()) +handler.sequence(['d', 'd'], () => deleteLine()) +``` + +### Mouse Parsing + +Parse terminal mouse events: + +```typescript +import { parseMouse } from '@opentui/core/lib' + +process.stdin.on('data', (data) => { + const mouse = parseMouse(data) + if (mouse) { + console.log(`Click at ${mouse.x}, ${mouse.y}`) + if (mouse.button === 'left') handleLeftClick(mouse) + if (mouse.type === 'wheel') handleScroll(mouse.delta) + } +}) +``` + +## Text Processing + +### HAST Styled Text + +Integration with syntax highlighting using HAST: + +```typescript +import { hastToStyledText } from '@opentui/core/lib' + +const hastTree = { + type: 'element', + tagName: 'span', + properties: { className: ['keyword'] }, + children: [{ type: 'text', value: 'function' }] +} + +const styled = hastToStyledText(hastTree, { + theme: 'monokai', + background: false +}) +``` + +### Selection Management + +Text selection and clipboard operations: + +```typescript +import { Selection } from '@opentui/core/lib' + +const selection = new Selection() +selection.start(10, 5) +selection.extend(25, 8) + +const selected = selection.getSelectedText(buffer) +const coords = selection.getCoordinates() + +// Visual feedback +selection.highlight(buffer, { bg: [100, 100, 100, 255] }) +``` + +## Layout Utilities + +### Yoga Layout Options + +Flexbox layout configuration: + +```typescript +import { yogaOptions } from '@opentui/core/lib' + +const layout = yogaOptions({ + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + padding: 10, + gap: 5 +}) +``` + +### TrackedNode + +DOM-like node tracking for component trees: + +```typescript +import { TrackedNode } from '@opentui/core/lib' + +const root = new TrackedNode('root') +const child = new TrackedNode('child') +root.appendChild(child) + +// Tree traversal +root.traverse((node) => { + console.log(node.id) +}) + +// Find nodes +const found = root.find((node) => node.id === 'child') +``` + +## Utilities + +### Output Capture + +Capture and redirect terminal output: + +```typescript +import { captureOutput } from '@opentui/core/lib' + +const restore = captureOutput((output) => { + // Process captured output + logger.log(output) +}) + +console.log('This will be captured') +restore() // Restore normal output +``` + +### Parse Keypress + +Low-level keypress parsing: + +```typescript +import { parseKeypress } from '@opentui/core/lib' + +const key = parseKeypress(Buffer.from([27, 91, 65])) +// { name: 'up', ctrl: false, shift: false, meta: false } +``` + +## API Reference + +### Exports + +- `RGBA` - Color representation and manipulation +- `StyledText` - Text with ANSI styling +- `Border` - Border rendering utilities +- `BorderStyle` - Border style constants +- `ASCIIFont` - ASCII art text rendering +- `KeyHandler` - Keyboard event management +- `parseMouse` - Mouse event parsing +- `parseKeypress` - Keypress parsing +- `Selection` - Text selection management +- `TrackedNode` - Node tree management +- `hastToStyledText` - HAST to styled text conversion +- `yogaOptions` - Layout configuration helpers +- `captureOutput` - Output redirection + +## Related Modules + +- [Components](./components.md) - Uses lib utilities for rendering +- [Text Buffer](./text-buffer.md) - Text manipulation and styling +- [Events](./events.md) - Input event handling \ No newline at end of file diff --git a/packages/core/docs/modules/rendering.md b/packages/core/docs/modules/rendering.md new file mode 100644 index 00000000..4ce59ff1 --- /dev/null +++ b/packages/core/docs/modules/rendering.md @@ -0,0 +1,713 @@ +# Rendering System + +> **Quick Navigation:** [Getting Started](./getting-started.md) | [Components](./components.md) | [Layout](./layout.md) | [Events](./events.md) | [Animation](./animation.md) + +Understanding how OpenTUI renders to the terminal for optimal performance. + +## Render Pipeline + +``` +Input Events → Layout → Component Render → Buffer Diff → Terminal Update +``` + +## The OptimizedBuffer + +OpenTUI uses a double-buffered rendering system with dirty region tracking. + +```typescript +import { OptimizedBuffer, RGBA } from '@opentui/core'; + +class CustomRenderer extends Renderable { + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + // Clear a region + buffer.clear(this.x, this.y, this.width, this.height); + + // Draw text + buffer.drawText( + 'Hello World', + this.x, + this.y, + RGBA.fromHex('#ffffff'), // Foreground + RGBA.fromHex('#000000') // Background + ); + + // Draw individual cells + for (let x = 0; x < this.width; x++) { + buffer.setCell( + this.x + x, + this.y + 1, + '═', + RGBA.white(), + RGBA.black() + ); + } + + // Draw a box + buffer.drawBox( + this.x, + this.y, + this.width, + this.height, + { + style: 'double', + color: RGBA.fromHex('#00ff00') + } + ); + } +} +``` + +## Color Management + +```typescript +import { RGBA } from '@opentui/core'; + +// Create colors +const red = RGBA.fromHex('#ff0000'); +const green = RGBA.fromValues(0, 1, 0, 1); // r, g, b, a (0-1) +const blue = new RGBA(0, 0, 255, 255); // r, g, b, a (0-255) + +// Color with transparency +const semiTransparent = RGBA.fromValues(1, 1, 1, 0.5); + +// Blend colors +const purple = RGBA.blend(red, blue, 0.5); + +// Common colors +const white = RGBA.white(); +const black = RGBA.black(); +const transparent = RGBA.transparent(); +``` + +## Dirty Region Optimization + +```typescript +class OptimizedComponent extends Renderable { + private isDirty = true; + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + if (!this.isDirty) { + return; // Skip rendering if not dirty + } + + // Mark the region we're about to render as dirty + buffer.markDirty(this.x, this.y, this.width, this.height); + + // Render content + this.renderContent(buffer); + + this.isDirty = false; + } + + // Call when content changes + invalidate() { + this.isDirty = true; + this.needsUpdate(); // Request re-render + } +} +``` + +## Layered Rendering + +```typescript +class LayeredUI extends Renderable { + private layers: Map = new Map(); + + addToLayer(component: Renderable, layer: number) { + if (!this.layers.has(layer)) { + this.layers.set(layer, []); + } + this.layers.get(layer)!.push(component); + component.zIndex = layer; + } + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + // Render layers in order + const sortedLayers = Array.from(this.layers.keys()).sort(); + + for (const layer of sortedLayers) { + const components = this.layers.get(layer)!; + for (const component of components) { + component.render(buffer, deltaTime); + } + } + } +} +``` + +## Performance Tips + +### 1. Use Buffered Rendering + +```typescript +// Good - renders to internal buffer first +const buffered = new BoxRenderable('buffered', { + buffered: true, // Enable internal buffering + width: 100, + height: 50 +}); + +// Updates only re-render this component, not parents +buffered.needsUpdate(); +``` + +### 2. Batch Updates + +```typescript +class BatchUpdater extends Renderable { + private pendingUpdates: Function[] = []; + + queueUpdate(fn: Function) { + this.pendingUpdates.push(fn); + } + + flushUpdates() { + // Batch all updates together + this.pendingUpdates.forEach(fn => fn()); + this.pendingUpdates = []; + this.needsUpdate(); // Single re-render + } +} +``` + +### 3. Virtual Scrolling + +```typescript +class VirtualList extends Renderable { + private items: string[] = []; + private scrollOffset = 0; + private itemHeight = 1; + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + const visibleItems = Math.floor(this.height / this.itemHeight); + const startIndex = this.scrollOffset; + const endIndex = Math.min(startIndex + visibleItems, this.items.length); + + // Only render visible items + for (let i = startIndex; i < endIndex; i++) { + const y = this.y + (i - startIndex) * this.itemHeight; + buffer.drawText(this.items[i], this.x, y); + } + } +} +``` + +### 4. Caching Complex Renders + +```typescript +class CachedComponent extends Renderable { + private cache?: OptimizedBuffer; + private cacheValid = false; + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + if (!this.cacheValid) { + // Render to cache + this.cache = OptimizedBuffer.create(this.width, this.height); + this.renderToCache(this.cache); + this.cacheValid = true; + } + + // Copy from cache + buffer.copyFrom(this.cache, this.x, this.y); + } + + invalidateCache() { + this.cacheValid = false; + this.needsUpdate(); + } +} +``` + +## Debug Overlay + +```typescript +// Enable debug overlay +renderer.toggleDebugOverlay(); + +// Configure overlay +renderer.configureDebugOverlay({ + enabled: true, + corner: DebugOverlayCorner.TOP_RIGHT, + showFPS: true, + showDirtyRegions: true, + showLayoutBounds: true +}); +``` + +## Advanced Rendering Techniques + +### Custom Cell Rendering + +```typescript +class MatrixRain extends Renderable { + private columns: number[] = []; + private chars = 'ļ¾Šļ¾ļ¾‹ļ½°ļ½³ļ½¼ļ¾…ļ¾“ļ¾†ļ½»ļ¾œļ¾‚ļ½µļ¾˜ļ½±ļ¾Žļ¾ƒļ¾ļ½¹ļ¾’ļ½“ļ½¶ļ½·ļ¾‘ļ¾•ļ¾—ļ½¾ļ¾ˆļ½½ļ¾€ļ¾‡ļ¾0123456789'; + + constructor(id: string, options: RenderableOptions) { + super(id, options); + this.columns = new Array(this.width).fill(0); + } + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + // Fade existing cells + for (let y = 0; y < this.height; y++) { + for (let x = 0; x < this.width; x++) { + const cell = buffer.getCell(this.x + x, this.y + y); + if (cell) { + // Fade to black + const color = cell.fg; + const faded = RGBA.fromValues( + 0, + color.g * 0.9, + 0, + color.a * 0.95 + ); + buffer.setCell( + this.x + x, + this.y + y, + cell.char, + faded + ); + } + } + } + + // Update columns + for (let x = 0; x < this.columns.length; x++) { + if (Math.random() > 0.98) { + this.columns[x] = 0; // Reset column + } + + const y = this.columns[x]; + if (y < this.height) { + const char = this.chars[Math.floor(Math.random() * this.chars.length)]; + const brightness = y === 0 ? 1 : 0.7; + + buffer.setCell( + this.x + x, + this.y + y, + char, + RGBA.fromValues(0, brightness, 0, 1) + ); + + this.columns[x]++; + } + } + + this.needsUpdate(); + } +} +``` + +### Gradient Rendering + +```typescript +class GradientBox extends BoxRenderable { + private gradient: { + startColor: RGBA; + endColor: RGBA; + direction: 'horizontal' | 'vertical' | 'diagonal'; + }; + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + super.renderSelf(buffer, deltaTime); + + const { startColor, endColor, direction } = this.gradient; + + for (let y = 0; y < this.height; y++) { + for (let x = 0; x < this.width; x++) { + let progress: number; + + switch (direction) { + case 'horizontal': + progress = x / this.width; + break; + case 'vertical': + progress = y / this.height; + break; + case 'diagonal': + progress = (x + y) / (this.width + this.height); + break; + } + + const color = RGBA.blend(startColor, endColor, progress); + buffer.setCell( + this.x + x, + this.y + y, + ' ', + color, + color // Use as background + ); + } + } + } +} +``` + +### Shadow Effects + +```typescript +class ShadowBox extends BoxRenderable { + private shadowOffset = { x: 2, y: 1 }; + private shadowColor = RGBA.fromValues(0, 0, 0, 0.5); + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + // Draw shadow first + for (let y = 0; y < this.height; y++) { + for (let x = 0; x < this.width; x++) { + const shadowX = this.x + x + this.shadowOffset.x; + const shadowY = this.y + y + this.shadowOffset.y; + + // Blend shadow with existing content + const existing = buffer.getCell(shadowX, shadowY); + if (existing) { + const blended = RGBA.blend(existing.bg, this.shadowColor, 0.5); + buffer.setCell(shadowX, shadowY, existing.char, existing.fg, blended); + } + } + } + + // Draw box on top + super.renderSelf(buffer, deltaTime); + } +} +``` + +### Texture Patterns + +```typescript +class TexturedBackground extends Renderable { + private patterns = { + dots: ['Ā·', '•', 'ā—'], + lines: ['─', '═', '━'], + crosses: ['┼', '╬', 'ā•‹'], + blocks: ['ā–‘', 'ā–’', 'ā–“'] + }; + + renderPattern( + buffer: OptimizedBuffer, + pattern: keyof typeof this.patterns, + density: number = 0.3 + ) { + const chars = this.patterns[pattern]; + + for (let y = 0; y < this.height; y++) { + for (let x = 0; x < this.width; x++) { + if (Math.random() < density) { + const char = chars[Math.floor(Math.random() * chars.length)]; + const brightness = 0.2 + Math.random() * 0.3; + + buffer.setCell( + this.x + x, + this.y + y, + char, + RGBA.fromValues(brightness, brightness, brightness, 1) + ); + } + } + } + } +} +``` + +## Performance Monitoring + +### Frame Time Analysis + +```typescript +class RenderProfiler { + private samples: number[] = []; + private maxSamples = 100; + + startFrame(): () => void { + const start = performance.now(); + + return () => { + const duration = performance.now() - start; + this.samples.push(duration); + + if (this.samples.length > this.maxSamples) { + this.samples.shift(); + } + }; + } + + getStats() { + if (this.samples.length === 0) return null; + + const sorted = [...this.samples].sort((a, b) => a - b); + const sum = sorted.reduce((a, b) => a + b, 0); + + return { + avg: sum / sorted.length, + min: sorted[0], + max: sorted[sorted.length - 1], + p50: sorted[Math.floor(sorted.length * 0.5)], + p95: sorted[Math.floor(sorted.length * 0.95)], + p99: sorted[Math.floor(sorted.length * 0.99)] + }; + } +} + +// Usage +const profiler = new RenderProfiler(); + +class ProfiledComponent extends Renderable { + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + const endProfile = profiler.startFrame(); + + // Render logic here + this.renderContent(buffer); + + endProfile(); + + // Log stats periodically + if (Math.random() < 0.01) { + console.log('Render stats:', profiler.getStats()); + } + } +} +``` + +### Memory Usage Tracking + +```typescript +class MemoryMonitor { + private buffers = new WeakMap(); + + trackBuffer(buffer: OptimizedBuffer) { + const size = buffer.width * buffer.height * 4 * 2; // cells Ɨ RGBA Ɨ 2 (fg+bg) + this.buffers.set(buffer, size); + } + + getEstimatedMemory(): string { + // Note: WeakMap doesn't allow iteration + // This would need a different approach in production + const usage = process.memoryUsage(); + return `Heap: ${(usage.heapUsed / 1024 / 1024).toFixed(2)}MB`; + } +} +``` + +## Render Optimization Strategies + +### 1. Scissor Regions + +```typescript +class ScissoredRenderer extends Renderable { + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + // Set scissor region to limit rendering + buffer.setScissor(this.x, this.y, this.width, this.height); + + // All rendering operations are now clipped to this region + this.renderChildren(buffer, deltaTime); + + // Clear scissor + buffer.clearScissor(); + } +} +``` + +### 2. Level of Detail (LOD) + +```typescript +class LODComponent extends Renderable { + private distanceFromFocus: number = 0; + + protected renderSelf(buffer: OptimizedBuffer, deltaTime: number): void { + if (this.distanceFromFocus > 100) { + // Far away - render simplified version + this.renderLowDetail(buffer); + } else if (this.distanceFromFocus > 50) { + // Medium distance - render medium detail + this.renderMediumDetail(buffer); + } else { + // Close - render full detail + this.renderHighDetail(buffer); + } + } + + private renderLowDetail(buffer: OptimizedBuffer) { + // Just a colored block + buffer.fillRect(this.x, this.y, this.width, this.height, 'ā–ˆ'); + } + + private renderMediumDetail(buffer: OptimizedBuffer) { + // Basic box with title + buffer.drawBox(this.x, this.y, this.width, this.height); + buffer.drawText(this.title, this.x + 1, this.y); + } + + private renderHighDetail(buffer: OptimizedBuffer) { + // Full rendering with all details + super.renderSelf(buffer, deltaTime); + } +} +``` + +### 3. Render Culling + +```typescript +class CullingRenderer extends CliRenderer { + private viewport = { x: 0, y: 0, width: 80, height: 24 }; + + protected renderTree(buffer: OptimizedBuffer, deltaTime: number) { + this.cullAndRender(this.root, buffer, deltaTime); + } + + private cullAndRender( + node: Renderable, + buffer: OptimizedBuffer, + deltaTime: number + ) { + // Check if node is visible in viewport + if (!this.isInViewport(node)) { + return; // Skip rendering + } + + // Render node + node.render(buffer, deltaTime); + + // Recursively render visible children + for (const child of node.getChildren()) { + this.cullAndRender(child, buffer, deltaTime); + } + } + + private isInViewport(node: Renderable): boolean { + return !( + node.x + node.width < this.viewport.x || + node.y + node.height < this.viewport.y || + node.x > this.viewport.x + this.viewport.width || + node.y > this.viewport.y + this.viewport.height + ); + } +} +``` + +## Troubleshooting Rendering Issues + +### Common Problems and Solutions + +1. **Flickering** + - Enable double buffering: `buffered: true` + - Reduce update frequency + - Check for unnecessary re-renders + +2. **Tearing** + - Synchronize updates with vsync if available + - Use atomic buffer swaps + - Avoid partial updates during render + +3. **Performance** + - Profile with debug overlay + - Implement dirty region tracking + - Use virtual scrolling for lists + - Cache complex renders + +4. **Color Issues** + - Check terminal color support + - Use fallback colors for limited terminals + - Test with different terminal emulators + +### Debugging Tools + +```typescript +class RenderDebugger { + static highlightDirtyRegions(buffer: OptimizedBuffer) { + const regions = buffer.getDirtyRegions(); + for (const region of regions) { + // Draw red border around dirty regions + buffer.drawBox( + region.x, + region.y, + region.width, + region.height, + { + style: 'single', + color: RGBA.fromHex('#ff0000') + } + ); + } + } + + static showRenderOrder(root: Renderable, buffer: OptimizedBuffer) { + let order = 0; + + function traverse(node: Renderable) { + // Draw render order number + buffer.drawText( + order.toString(), + node.x, + node.y, + RGBA.fromHex('#ffff00') + ); + order++; + + for (const child of node.getChildren()) { + traverse(child); + } + } + + traverse(root); + } +} +``` + +## Related Topics + +### Components & Rendering +- [Components: Custom](./components.md#custom-components) - Custom component rendering +- [Components: Box](./components.md#box-component) - Container rendering +- [Getting Started](./getting-started.md#core-concepts) - Render loop basics + +### Animation Integration +- [Animation: Performance](./animation.md#performance-best-practices) - Optimizing animated renders +- [Animation: Frame-based](./animation.md#frame-based-animation) - Frame-by-frame rendering +- [Animation: Effects](./animation.md#complex-animation-examples) - Visual effects rendering + +### Layout & Rendering +- [Layout: Optimization](./layout.md#best-practices) - Layout performance +- [Layout: Scrollable](./layout.md#scrollable-content) - Virtual scrolling +- [Layout: Responsive](./layout.md#responsive-techniques) - Responsive rendering + +### Event-driven Rendering +- [Events: Mouse](./events.md#mouse-events) - Render on interaction +- [Events: Window](./events.md#window-events) - Handle resize rendering +- [Events: Forms](./events.md#form-handling) - Input field rendering + +## Rendering Patterns + +### Common Techniques +- **Double Buffering:** Prevent flicker with buffered rendering +- **Dirty Regions:** Only update changed areas +- **Virtual Scrolling:** Render only visible items +- **Caching:** Store complex renders for reuse + +### Visual Effects +Implement advanced effects: +- [Gradients](#gradient-rendering) - Color gradients +- [Shadows](#shadow-effects) - Drop shadows +- [Textures](#texture-patterns) - Background patterns +- [Matrix Rain](#custom-cell-rendering) - Custom effects + +### Performance Strategies +- [LOD](#level-of-detail-lod) - Adjust detail by distance +- [Culling](#render-culling) - Skip off-screen elements +- [Batching](#performance-tips) - Batch render operations +- [Profiling](#performance-monitoring) - Measure and optimize + +## Best Practices + +1. **Use Buffering:** Enable `buffered: true` for frequently updating components +2. **Track Dirty Regions:** Only redraw changed areas +3. **Implement Virtual Scrolling:** For long lists +4. **Cache Complex Renders:** Store and reuse expensive renders +5. **Profile Performance:** Measure frame times and optimize bottlenecks + +## Next Steps + +- **Build UIs:** Create efficient [Components](./components.md) +- **Add Motion:** Optimize [Animations](./animation.md) for performance +- **Handle Input:** Render feedback for [Events](./events.md) +- **Layout:** Create performant [Layouts](./layout.md) diff --git a/packages/core/docs/modules/text-buffer.md b/packages/core/docs/modules/text-buffer.md new file mode 100644 index 00000000..2f3e4fd1 --- /dev/null +++ b/packages/core/docs/modules/text-buffer.md @@ -0,0 +1,158 @@ +# Text Buffer Module + +The text-buffer module provides efficient text manipulation and buffer management for terminal rendering operations. + +## Overview + +The TextBuffer class manages character-based content with styling, providing optimized operations for terminal UI rendering including diffing, merging, and viewport management. + +## Core Components + +### TextBuffer + +Main class for managing text content with ANSI styling and efficient updates. + +```typescript +import { TextBuffer } from '@opentui/core' + +const buffer = new TextBuffer(80, 24) +buffer.write(0, 0, 'Hello, World!') +buffer.setStyle(0, 0, 13, { fg: [255, 0, 0, 255] }) +``` + +## Key Features + +### Buffer Operations + +- **Write Operations**: Direct character writing with position control +- **Style Management**: Apply ANSI colors and text decorations +- **Diff Generation**: Efficient change detection between buffer states +- **Viewport Support**: Handle scrolling and partial rendering +- **Clear Operations**: Reset regions or entire buffer + +### Text Manipulation + +```typescript +// Write styled text +buffer.writeStyled(10, 5, 'Important', { + fg: [255, 255, 0, 255], + bold: true, + underline: true +}) + +// Extract regions +const region = buffer.getRegion(0, 0, 40, 10) + +// Merge buffers +buffer.merge(otherBuffer, 20, 10) +``` + +## Performance Optimization + +### Dirty Tracking + +Tracks modified regions to minimize rendering updates: + +```typescript +buffer.write(0, 0, 'Changed') +const dirty = buffer.getDirtyRegions() +// Only re-render dirty regions +``` + +### Buffer Pooling + +Reuse buffer instances to reduce allocations: + +```typescript +const pool = new TextBufferPool(10) +const buffer = pool.acquire(80, 24) +// Use buffer... +pool.release(buffer) +``` + +## Integration + +### With Renderables + +TextBuffer integrates seamlessly with the rendering system: + +```typescript +class CustomRenderable extends Renderable { + private buffer: TextBuffer + + render(target: TextBuffer) { + target.merge(this.buffer, this.x, this.y) + } +} +``` + +### With Console Output + +Direct terminal output support: + +```typescript +const output = buffer.toANSI() +process.stdout.write(output) +``` + +## Advanced Usage + +### Double Buffering + +Implement smooth animations with double buffering: + +```typescript +let frontBuffer = new TextBuffer(80, 24) +let backBuffer = new TextBuffer(80, 24) + +function render() { + // Render to back buffer + backBuffer.clear() + renderScene(backBuffer) + + // Swap buffers + [frontBuffer, backBuffer] = [backBuffer, frontBuffer] + + // Output front buffer + console.write(frontBuffer.toANSI()) +} +``` + +### Custom Encodings + +Support for different character encodings: + +```typescript +const buffer = new TextBuffer(80, 24, { + encoding: 'utf-8', + lineEnding: '\n' +}) +``` + +## API Reference + +### Constructor + +```typescript +new TextBuffer(width: number, height: number, options?: TextBufferOptions) +``` + +### Methods + +- `write(x: number, y: number, text: string): void` +- `writeStyled(x: number, y: number, text: string, style: TextStyle): void` +- `clear(x?: number, y?: number, width?: number, height?: number): void` +- `getChar(x: number, y: number): string` +- `getStyle(x: number, y: number): TextStyle` +- `setStyle(x: number, y: number, length: number, style: TextStyle): void` +- `getRegion(x: number, y: number, width: number, height: number): TextBuffer` +- `merge(buffer: TextBuffer, x: number, y: number): void` +- `getDirtyRegions(): DirtyRegion[]` +- `toANSI(): string` +- `clone(): TextBuffer` + +## Related Modules + +- [Buffer](./buffer.md) - Lower-level buffer operations +- [Rendering](./rendering.md) - Integration with rendering system +- [Components](./components.md) - Usage in UI components \ No newline at end of file diff --git a/packages/core/docs/modules/types.md b/packages/core/docs/modules/types.md new file mode 100644 index 00000000..0cf8a99a --- /dev/null +++ b/packages/core/docs/modules/types.md @@ -0,0 +1,408 @@ +# Types Module + +The types module provides TypeScript type definitions, enums, and interfaces used throughout OpenTUI for type safety and consistency. + +## Overview + +This module exports core type definitions that ensure type safety across the OpenTUI framework, including text attributes, cursor styles, render contexts, and configuration options. + +## Text Attributes + +### Attribute Flags + +Bitwise flags for text styling: + +```typescript +import { TextAttributes } from '@opentui/core' + +const TextAttributes = { + NONE: 0, + BOLD: 1 << 0, // 1 + DIM: 1 << 1, // 2 + ITALIC: 1 << 2, // 4 + UNDERLINE: 1 << 3, // 8 + BLINK: 1 << 4, // 16 + INVERSE: 1 << 5, // 32 + HIDDEN: 1 << 6, // 64 + STRIKETHROUGH: 1 << 7 // 128 +} +``` + +### Combining Attributes + +Use bitwise operations to combine attributes: + +```typescript +// Combine multiple attributes +const style = TextAttributes.BOLD | TextAttributes.UNDERLINE + +// Check for attribute +const isBold = (style & TextAttributes.BOLD) !== 0 + +// Remove attribute +const withoutBold = style & ~TextAttributes.BOLD + +// Toggle attribute +const toggled = style ^ TextAttributes.ITALIC +``` + +## Cursor Types + +### CursorStyle + +Terminal cursor appearance: + +```typescript +type CursorStyle = "block" | "line" | "underline" + +// Usage +renderer.setCursorStyle("block") +renderer.setCursorStyle("line") // Vertical bar +renderer.setCursorStyle("underline") // Horizontal underscore +``` + +## Debug Overlay + +### DebugOverlayCorner + +Position for debug information display: + +```typescript +enum DebugOverlayCorner { + topLeft = 0, + topRight = 1, + bottomLeft = 2, + bottomRight = 3 +} + +// Usage +renderer.setDebugOverlay(true, DebugOverlayCorner.topRight) +``` + +## Render Context + +### RenderContext Interface + +Context provided during rendering: + +```typescript +interface RenderContext { + // Add hit detection region + addToHitGrid: ( + x: number, + y: number, + width: number, + height: number, + id: number + ) => void + + // Get viewport dimensions + width: () => number + height: () => number + + // Mark for re-render + needsUpdate: () => void +} + +// Usage in renderable +class MyRenderable extends Renderable { + render(buffer: Buffer, context: RenderContext) { + // Register hit area + context.addToHitGrid(this.x, this.y, this.width, this.height, this.id) + + // Check viewport + if (this.x > context.width()) return + + // Request update + if (this.animated) context.needsUpdate() + } +} +``` + +## Selection State + +### SelectionState Interface + +Text selection tracking: + +```typescript +interface SelectionState { + anchor: { x: number; y: number } // Selection start + focus: { x: number; y: number } // Selection end + isActive: boolean // Selection exists + isSelecting: boolean // Currently selecting +} + +// Usage +const selection: SelectionState = { + anchor: { x: 10, y: 5 }, + focus: { x: 25, y: 7 }, + isActive: true, + isSelecting: false +} + +// Get selection bounds +const minX = Math.min(selection.anchor.x, selection.focus.x) +const maxX = Math.max(selection.anchor.x, selection.focus.x) +const minY = Math.min(selection.anchor.y, selection.focus.y) +const maxY = Math.max(selection.anchor.y, selection.focus.y) +``` + +## Color Types + +### ColorInput + +Flexible color input type: + +```typescript +type ColorInput = string | RGBA | [number, number, number, number] + +// All valid color inputs +const color1: ColorInput = "#ff0000" +const color2: ColorInput = "rgb(255, 0, 0)" +const color3: ColorInput = RGBA.fromValues(1, 0, 0, 1) +const color4: ColorInput = [255, 0, 0, 255] +``` + +## Component Option Types + +Types are provided for all component configurations (imported from type definition files): + +- `BoxOptions` - Box component configuration +- `TextOptions` - Text component options +- `InputRenderableOptions` - Input field configuration +- `SelectRenderableOptions` - Select dropdown options +- `TabSelectRenderableOptions` - Tab selector options +- `ASCIIFontOptions` - ASCII art font settings +- `FrameBufferOptions` - Frame buffer configuration +- `AnimationOptions` - Animation settings +- `TimelineOptions` - Timeline configuration +- `ConsoleOptions` - Console window options +- `CliRendererConfig` - Renderer configuration + +## Layout Types + +### LayoutOptions + +Flexbox-style layout configuration: + +```typescript +interface LayoutOptions { + flexDirection?: 'row' | 'column' | 'row-reverse' | 'column-reverse' + justifyContent?: 'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around' + alignItems?: 'flex-start' | 'center' | 'flex-end' | 'stretch' + flexWrap?: 'nowrap' | 'wrap' | 'wrap-reverse' + flex?: number + flexGrow?: number + flexShrink?: number + flexBasis?: number | string + padding?: number | [number, number] | [number, number, number, number] + margin?: number | [number, number] | [number, number, number, number] + gap?: number + width?: number | string + height?: number | string + minWidth?: number | string + minHeight?: number | string + maxWidth?: number | string + maxHeight?: number | string +} +``` + +## Border Types + +### BorderConfig + +Border configuration options: + +```typescript +interface BorderConfig { + style?: BorderStyle + color?: ColorInput + width?: number + padding?: number | [number, number] | [number, number, number, number] + margin?: number | [number, number] | [number, number, number, number] + rounded?: boolean +} + +type BorderStyle = 'single' | 'double' | 'rounded' | 'heavy' +type BorderSides = 'top' | 'right' | 'bottom' | 'left' +``` + +## Event Types + +### Mouse Events + +```typescript +interface MouseEvent { + x: number + y: number + button: 'left' | 'right' | 'middle' | 'none' + type: 'click' | 'move' | 'wheel' | 'down' | 'up' + modifiers: { + shift: boolean + ctrl: boolean + alt: boolean + meta: boolean + } + delta?: number // For wheel events +} +``` + +### Keyboard Events + +```typescript +interface KeyEvent { + key: string + code: string + modifiers: { + shift: boolean + ctrl: boolean + alt: boolean + meta: boolean + } + isComposing: boolean +} +``` + +## Utility Types + +### Dimensions + +```typescript +interface Dimensions { + width: number + height: number +} + +interface Position { + x: number + y: number +} + +interface Bounds { + x: number + y: number + width: number + height: number +} + +interface Padding { + top: number + right: number + bottom: number + left: number +} +``` + +## Type Guards + +Utility functions for type checking: + +```typescript +// Check if value is RGBA +function isRGBA(value: any): value is RGBA { + return value instanceof RGBA +} + +// Check if value is color string +function isColorString(value: any): value is string { + return typeof value === 'string' && + (value.startsWith('#') || value.startsWith('rgb')) +} + +// Check if has selection +function hasSelection(state: SelectionState): boolean { + return state.isActive && + (state.anchor.x !== state.focus.x || + state.anchor.y !== state.focus.y) +} +``` + +## Generic Types + +### Callback Types + +```typescript +type VoidCallback = () => void +type ValueCallback = (value: T) => void +type Predicate = (value: T) => boolean +type Mapper = (value: T) => U +type Reducer = (acc: U, value: T) => U +``` + +### Component Types + +```typescript +type ComponentProps = T & { + id?: string + className?: string + style?: Partial + children?: ReactNode +} + +type RenderFunction = ( + buffer: OptimizedBuffer, + context: RenderContext +) => void +``` + +## Usage Examples + +### Type-Safe Component Creation + +```typescript +import { BoxOptions, TextAttributes, RGBA } from '@opentui/core' + +const boxConfig: BoxOptions = { + width: 40, + height: 20, + border: true, + borderStyle: 'double', + padding: 2, + fg: RGBA.fromValues(1, 1, 1, 1), + bg: RGBA.fromValues(0, 0, 0.5, 0.8) +} + +const textStyle = TextAttributes.BOLD | TextAttributes.UNDERLINE + +const box = new BoxRenderable('myBox', boxConfig) +box.attributes = textStyle +``` + +### Type-Safe Event Handling + +```typescript +function handleMouse(event: MouseEvent): void { + if (event.type === 'click' && event.button === 'left') { + console.log(`Clicked at ${event.x}, ${event.y}`) + } + + if (event.modifiers.ctrl) { + console.log('Ctrl key held') + } +} + +function handleKey(event: KeyEvent): void { + if (event.key === 'Enter' && !event.modifiers.shift) { + submitForm() + } +} +``` + +## API Reference + +### Exports + +- `TextAttributes` - Text attribute flags +- `CursorStyle` - Cursor appearance type +- `DebugOverlayCorner` - Debug overlay positions +- `RenderContext` - Rendering context interface +- `SelectionState` - Text selection state +- All option interfaces from type definition files + +## Related Modules + +- [Components](./components.md) - Uses type definitions +- [Rendering](./rendering.md) - Uses RenderContext +- [Events](./events.md) - Event type definitions +- [Lib](./lib.md) - Color and style utilities \ No newline at end of file diff --git a/packages/core/docs/modules/utils.md b/packages/core/docs/modules/utils.md new file mode 100644 index 00000000..7bb630dd --- /dev/null +++ b/packages/core/docs/modules/utils.md @@ -0,0 +1,331 @@ +# Utils Module + +The utils module provides utility functions for common operations in OpenTUI, including text attribute creation and other helper functions. + +## Overview + +This module contains helper functions that simplify common tasks when working with OpenTUI components and rendering. + +## Text Attribute Utilities + +### createTextAttributes + +Create text attributes using a friendly object interface instead of bitwise operations: + +```typescript +import { createTextAttributes } from '@opentui/core' + +// Create attributes with object syntax +const attributes = createTextAttributes({ + bold: true, + underline: true, + italic: false +}) + +// Equivalent to: +// TextAttributes.BOLD | TextAttributes.UNDERLINE +``` + +### Usage Examples + +```typescript +// No attributes (default) +const plain = createTextAttributes() +// Returns: 0 + +// Single attribute +const bold = createTextAttributes({ bold: true }) +// Returns: 1 + +// Multiple attributes +const fancy = createTextAttributes({ + bold: true, + italic: true, + underline: true +}) +// Returns: 13 (1 + 4 + 8) + +// All attributes +const all = createTextAttributes({ + bold: true, + dim: true, + italic: true, + underline: true, + blink: true, + inverse: true, + hidden: true, + strikethrough: true +}) +// Returns: 255 (all bits set) +``` + +### Attribute Options + +All options are optional and default to `false`: + +```typescript +interface TextAttributeOptions { + bold?: boolean // Make text bold + italic?: boolean // Make text italic + underline?: boolean // Underline text + dim?: boolean // Dim/faint text + blink?: boolean // Blinking text + inverse?: boolean // Swap fg/bg colors + hidden?: boolean // Hide text (but preserve space) + strikethrough?: boolean // Strike through text +} +``` + +## Integration with Components + +### With Text Components + +```typescript +import { TextRenderable, createTextAttributes } from '@opentui/core' + +const text = new TextRenderable('myText', { + content: 'Important Message', + attributes: createTextAttributes({ + bold: true, + underline: true + }) +}) +``` + +### With Box Components + +```typescript +import { BoxRenderable, createTextAttributes } from '@opentui/core' + +const box = new BoxRenderable('myBox', { + title: 'Alert', + titleAttributes: createTextAttributes({ + bold: true, + inverse: true + }) +}) +``` + +### Dynamic Attribute Updates + +```typescript +class InteractiveText extends TextRenderable { + private baseAttributes = createTextAttributes({ bold: true }) + private hoverAttributes = createTextAttributes({ + bold: true, + underline: true, + inverse: true + }) + + onMouseEnter() { + this.attributes = this.hoverAttributes + } + + onMouseLeave() { + this.attributes = this.baseAttributes + } +} +``` + +## Attribute Manipulation + +### Combining with Existing Attributes + +```typescript +// Start with some attributes +let attrs = createTextAttributes({ bold: true }) + +// Add more attributes +attrs |= createTextAttributes({ underline: true }) + +// Remove attributes +attrs &= ~TextAttributes.BOLD + +// Toggle attributes +attrs ^= TextAttributes.ITALIC + +// Check for attributes +const isBold = (attrs & TextAttributes.BOLD) !== 0 +``` + +### Attribute Presets + +Create reusable attribute presets: + +```typescript +const styles = { + heading: createTextAttributes({ + bold: true, + underline: true + }), + + error: createTextAttributes({ + bold: true, + inverse: true + }), + + muted: createTextAttributes({ + dim: true + }), + + link: createTextAttributes({ + underline: true + }), + + code: createTextAttributes({ + inverse: true + }) +} + +// Use presets +text.attributes = styles.heading +errorText.attributes = styles.error +``` + +## Performance Considerations + +### Caching Attributes + +Since `createTextAttributes` performs bitwise operations, cache frequently used combinations: + +```typescript +// Good - cache the result +class MyComponent { + private static readonly HIGHLIGHT_ATTRS = createTextAttributes({ + bold: true, + inverse: true + }) + + highlight() { + this.attributes = MyComponent.HIGHLIGHT_ATTRS + } +} + +// Avoid - creates new value each time +class MyComponent { + highlight() { + this.attributes = createTextAttributes({ + bold: true, + inverse: true + }) // Recalculated each call + } +} +``` + +## Best Practices + +### Semantic Naming + +Use descriptive names for attribute combinations: + +```typescript +const semanticStyles = { + primary: createTextAttributes({ bold: true }), + secondary: createTextAttributes({ dim: true }), + success: createTextAttributes({ bold: true }), + warning: createTextAttributes({ bold: true, underline: true }), + danger: createTextAttributes({ bold: true, inverse: true }), + info: createTextAttributes({ italic: true }), + disabled: createTextAttributes({ dim: true, strikethrough: true }) +} +``` + +### Terminal Compatibility + +Not all terminals support all attributes: + +```typescript +// Most compatible +const basic = createTextAttributes({ + bold: true, // Widely supported + underline: true // Widely supported +}) + +// Less compatible +const advanced = createTextAttributes({ + italic: true, // Not all terminals + blink: true, // Often disabled + strikethrough: true // Limited support +}) + +// Check terminal capabilities +const supportsItalic = process.env.TERM_PROGRAM !== 'Apple_Terminal' +const attrs = createTextAttributes({ + bold: true, + italic: supportsItalic +}) +``` + +## Examples + +### Status Indicators + +```typescript +function getStatusAttributes(status: string) { + switch (status) { + case 'running': + return createTextAttributes({ bold: true, blink: true }) + case 'success': + return createTextAttributes({ bold: true }) + case 'error': + return createTextAttributes({ bold: true, inverse: true }) + case 'warning': + return createTextAttributes({ bold: true, underline: true }) + case 'disabled': + return createTextAttributes({ dim: true, strikethrough: true }) + default: + return createTextAttributes() + } +} +``` + +### Progressive Enhancement + +```typescript +// Start with basic styling +let attributes = createTextAttributes({ bold: true }) + +// Add enhancements based on context +if (isImportant) { + attributes |= TextAttributes.UNDERLINE +} + +if (isError) { + attributes |= TextAttributes.INVERSE +} + +if (isDeprecated) { + attributes |= TextAttributes.STRIKETHROUGH +} +``` + +## API Reference + +### Functions + +- `createTextAttributes(options?: TextAttributeOptions): number` + - Creates text attributes from an options object + - Returns a number with appropriate bits set + - All options default to false + +### Types + +```typescript +interface TextAttributeOptions { + bold?: boolean + italic?: boolean + underline?: boolean + dim?: boolean + blink?: boolean + inverse?: boolean + hidden?: boolean + strikethrough?: boolean +} +``` + +## Related Modules + +- [Types](./types.md) - TextAttributes enum definition +- [Components](./components.md) - Components that use attributes +- [Lib](./lib.md) - Additional text styling utilities +- [Rendering](./rendering.md) - How attributes are rendered \ No newline at end of file diff --git a/packages/core/docs/modules/zig.md b/packages/core/docs/modules/zig.md new file mode 100644 index 00000000..a34b1442 --- /dev/null +++ b/packages/core/docs/modules/zig.md @@ -0,0 +1,428 @@ +# Zig Native Module + +The Zig module provides high-performance native acceleration for OpenTUI through Foreign Function Interface (FFI) bindings, enabling fast terminal rendering and buffer operations. + +## Overview + +OpenTUI uses Zig-compiled native libraries for performance-critical operations. The module automatically loads platform-specific binaries and provides TypeScript interfaces to native functions. + +## Architecture + +### Platform Support + +Native binaries are provided for: +- **Darwin (macOS)**: x64, arm64 +- **Linux**: x64, arm64 +- **Windows**: x64, arm64 + +```typescript +// Automatic platform detection +const module = await import(`@opentui/core-${process.platform}-${process.arch}/index.ts`) +const targetLibPath = module.default + +// Verify platform support +if (!existsSync(targetLibPath)) { + throw new Error(`opentui is not supported on: ${process.platform}-${process.arch}`) +} +``` + +### FFI Library Loading + +The module uses Bun's FFI to load native functions: + +```typescript +import { dlopen } from "bun:ffi" + +const lib = dlopen(libPath, { + createRenderer: { + args: ["u32", "u32"], // width, height + returns: "ptr" // renderer pointer + }, + // ... more functions +}) +``` + +## Core Functions + +### Renderer Management + +Create and manage native renderers: + +```typescript +// Create renderer +createRenderer(width: number, height: number): Pointer | null + +// Destroy renderer +destroyRenderer( + renderer: Pointer, + useAlternateScreen: boolean, + splitHeight: number +): void + +// Configure threading +setUseThread(renderer: Pointer, useThread: boolean): void + +// Set background color +setBackgroundColor(renderer: Pointer, color: RGBA): void + +// Update render offset +setRenderOffset(renderer: Pointer, offset: number): void + +// Perform render +render(renderer: Pointer, force: boolean): void +``` + +### Buffer Operations + +Native buffer creation and manipulation: + +```typescript +// Create optimized buffer +createOptimizedBuffer( + width: number, + height: number, + respectAlpha?: boolean +): OptimizedBuffer + +// Destroy buffer +destroyOptimizedBuffer(bufferPtr: Pointer): void + +// Get buffer dimensions +getBufferWidth(buffer: Pointer): number +getBufferHeight(buffer: Pointer): number + +// Clear buffer +bufferClear(buffer: Pointer, color: RGBA): void + +// Get buffer data pointers +bufferGetCharPtr(buffer: Pointer): Pointer // Character array +bufferGetFgPtr(buffer: Pointer): Pointer // Foreground colors +bufferGetBgPtr(buffer: Pointer): Pointer // Background colors +bufferGetAttributesPtr(buffer: Pointer): Pointer // Text attributes +``` + +### Text Rendering + +Accelerated text drawing: + +```typescript +// Draw text to buffer +bufferDrawText( + buffer: Pointer, + text: string, + x: number, + y: number, + color: RGBA, + bgColor?: RGBA, + attributes?: number +): void + +// Set cell with alpha blending +bufferSetCellWithAlphaBlending( + buffer: Pointer, + x: number, + y: number, + char: string, + color: RGBA, + bgColor: RGBA, + attributes?: number +): void +``` + +### Box Drawing + +Native box rendering with borders: + +```typescript +bufferDrawBox( + buffer: Pointer, + x: number, + y: number, + width: number, + height: number, + borderSides: number, // Packed bitfield + borderStyle: Pointer, // Border character array + fg: RGBA, + bg: RGBA, + title: string | null, + titleAlignment: number // 0=left, 1=center, 2=right +): void +``` + +### Frame Buffer Operations + +Efficient buffer copying and blitting: + +```typescript +// Draw frame buffer to target +drawFrameBuffer( + targetBufferPtr: Pointer, + destX: number, + destY: number, + bufferPtr: Pointer, + sourceX?: number, + sourceY?: number, + sourceWidth?: number, + sourceHeight?: number +): void + +// Fill rectangle +bufferFillRect( + buffer: Pointer, + x: number, + y: number, + width: number, + height: number, + color: RGBA +): void +``` + +## TextBuffer Support + +Native text buffer for efficient text management: + +```typescript +// Create/destroy text buffer +createTextBuffer(capacity: number): Pointer +destroyTextBuffer(buffer: Pointer): void + +// Get data pointers +textBufferGetCharPtr(buffer: Pointer): Pointer +textBufferGetFgPtr(buffer: Pointer): Pointer +textBufferGetBgPtr(buffer: Pointer): Pointer +textBufferGetAttributesPtr(buffer: Pointer): Pointer + +// Buffer operations +textBufferGetLength(buffer: Pointer): number +textBufferGetCapacity(buffer: Pointer): number +textBufferResize(buffer: Pointer, newCapacity: number): void +textBufferReset(buffer: Pointer): void + +// Set cell data +textBufferSetCell( + buffer: Pointer, + index: number, + char: number, + fg: RGBA, + bg: RGBA, + attributes: number +): void + +// Concatenate buffers +textBufferConcat(buffer1: Pointer, buffer2: Pointer): Pointer + +// Selection support +textBufferSetSelection( + buffer: Pointer, + start: number, + end: number, + selectionFg: RGBA, + selectionBg: RGBA +): void +textBufferResetSelection(buffer: Pointer): void + +// Write chunks efficiently +textBufferWriteChunk( + buffer: Pointer, + chars: Pointer, + length: number, + fg: RGBA, + bg: RGBA, + attributes: Pointer +): number + +// Line information +textBufferFinalizeLineInfo(buffer: Pointer): void +textBufferGetLineStartsPtr(buffer: Pointer): Pointer +textBufferGetLineWidthsPtr(buffer: Pointer): Pointer +textBufferGetLineCount(buffer: Pointer): number + +// Draw to buffer +bufferDrawTextBuffer( + targetBuffer: Pointer, + textBuffer: Pointer, + x: number, + y: number, + scrollX: number, + scrollY: number, + viewWidth: number, + viewHeight: number, + wrap: boolean +): void +``` + +## Terminal Control + +Native terminal manipulation: + +```typescript +// Clear terminal screen +clearTerminal(renderer: Pointer): void + +// Cursor control +setCursorPosition(x: number, y: number, visible: boolean): void +setCursorStyle(renderer: Pointer, style: CursorStyle, visible: boolean): void +setCursorColor(color: RGBA): void + +// Mouse support +enableMouse(renderer: Pointer, enable: boolean): void +disableMouse(renderer: Pointer): void +``` + +## Hit Testing + +Pixel-perfect hit detection: + +```typescript +// Add hit region +addToHitGrid( + renderer: Pointer, + x: number, + y: number, + width: number, + height: number, + id: number +): void + +// Check hit at position +checkHit(renderer: Pointer, x: number, y: number): number + +// Debug hit grid +dumpHitGrid(renderer: Pointer): void +``` + +## Performance Monitoring + +Native performance statistics: + +```typescript +// Update render stats +updateStats( + renderer: Pointer, + time: number, + fps: number, + frameCallbackTime: number +): void + +// Update memory stats +updateMemoryStats( + renderer: Pointer, + heapUsed: number, + heapTotal: number, + arrayBuffers: number +): void +``` + +## Debug Features + +Development and debugging tools: + +```typescript +// Debug overlay +setDebugOverlay( + renderer: Pointer, + enabled: boolean, + corner: DebugOverlayCorner +): void + +// Dump buffers for debugging +dumpBuffers(renderer: Pointer, timestamp: bigint): void +dumpStdoutBuffer(renderer: Pointer, timestamp: bigint): void +``` + +## RenderLib Interface + +TypeScript interface wrapping native functions: + +```typescript +export interface RenderLib { + createRenderer: (width: number, height: number) => Pointer | null + destroyRenderer: (renderer: Pointer, useAlternateScreen: boolean, splitHeight: number) => void + setUseThread: (renderer: Pointer, useThread: boolean) => void + setBackgroundColor: (renderer: Pointer, color: RGBA) => void + render: (renderer: Pointer, force: boolean) => void + getNextBuffer: (renderer: Pointer) => OptimizedBuffer + getCurrentBuffer: (renderer: Pointer) => OptimizedBuffer + createOptimizedBuffer: (width: number, height: number, respectAlpha?: boolean) => OptimizedBuffer + // ... and many more +} +``` + +## Usage Example + +```typescript +import { resolveRenderLib } from '@opentui/core/zig' +import { RGBA } from '@opentui/core' + +// Get native library +const lib = resolveRenderLib() + +// Create renderer +const renderer = lib.createRenderer(80, 24) + +// Create buffer +const buffer = lib.createOptimizedBuffer(80, 24, true) + +// Draw text +lib.bufferDrawText( + buffer.ptr, + "Hello, Native!", + 10, 5, + RGBA.fromValues(1, 1, 1, 1), + RGBA.fromValues(0, 0, 0, 1), + 0 +) + +// Render +lib.render(renderer, false) + +// Cleanup +lib.destroyOptimizedBuffer(buffer.ptr) +lib.destroyRenderer(renderer, false, 0) +``` + +## Building Native Libraries + +To rebuild the native libraries: + +```bash +# Development build (debug symbols) +bun run build:dev + +# Production build (optimized) +bun run build:prod + +# Build for all platforms +bun run build:all +``` + +Requirements: +- Zig 0.14.0-0.14.1 +- Bun runtime + +## Performance Benefits + +Native acceleration provides: +- **10-100x faster** buffer operations vs pure JavaScript +- **Minimal GC pressure** through direct memory management +- **SIMD optimizations** where available +- **Efficient text rendering** with native string handling +- **Zero-copy operations** for buffer transfers + +## API Reference + +### Exported Functions + +- `getOpenTUILib(libPath?: string)` - Load FFI library +- `resolveRenderLib()` - Get singleton RenderLib instance + +### Types + +- `RenderLib` - TypeScript interface for native functions +- `Pointer` - Native memory pointer type from Bun FFI + +## Related Modules + +- [Buffer](./buffer.md) - OptimizedBuffer that uses native acceleration +- [Text Buffer](./text-buffer.md) - TextBuffer with native support +- [Rendering](./rendering.md) - Renderer using native functions \ No newline at end of file diff --git a/packages/core/src/intellisense.d.ts b/packages/core/src/intellisense.d.ts new file mode 100644 index 00000000..6bdcebb1 --- /dev/null +++ b/packages/core/src/intellisense.d.ts @@ -0,0 +1,346 @@ +/** + * OpenTUI IntelliSense Definitions + * + * This file provides comprehensive type definitions and IntelliSense support + * for OpenTUI components and APIs. + * + * @packageDocumentation + */ + +import * as Types from './types/index.d.ts'; + +declare module '@opentui/core' { + // Re-export all types + export * from './types'; + + // Component Classes + export class Renderable { + constructor(id: string, options?: RenderableOptions); + + /** Unique identifier */ + id: string; + + /** X position */ + x: number; + + /** Y position */ + y: number; + + /** Width */ + width: number; + + /** Height */ + height: number; + + /** Visibility state */ + visible: boolean; + + /** Focus state */ + focused: boolean; + + /** Parent component */ + parent: Renderable | null; + + /** Child components */ + children: Renderable[]; + + // Methods + add(child: Renderable, index?: number): number; + remove(id: string): void; + focus(): void; + blur(): void; + needsUpdate(): void; + destroy(): void; + handleKeyPress(key: ParsedKey | string): boolean; + getSelectedText(): string; + hasSelection(): boolean; + } + + export class BoxRenderable extends Renderable { + constructor(id: string, options?: BoxOptions); + + /** Border visibility */ + border: boolean | [boolean, boolean, boolean, boolean]; + + /** Border style */ + borderStyle: BorderStyle; + + /** Box title */ + title?: string; + + /** Padding */ + padding: number | { top: number; right: number; bottom: number; left: number }; + + // Methods + setBorderStyle(style: BorderStyle): void; + setTitle(title: string): void; + setPadding(padding: number | { top: number; right: number; bottom: number; left: number }): void; + showBorder(show: boolean): void; + } + + export class TextRenderable extends Renderable { + constructor(id: string, options?: TextOptions); + + /** Text content */ + text: string; + + /** Text color */ + color: string | RGBA; + + /** Background color */ + backgroundColor?: string | RGBA; + + /** Text alignment */ + align: 'left' | 'center' | 'right'; + + /** Word wrap enabled */ + wrap: boolean; + + /** Text is selectable */ + selectable: boolean; + + // Methods + setText(text: string): void; + setColor(color: string | RGBA): void; + setAlign(align: 'left' | 'center' | 'right'): void; + } + + export class InputRenderable extends Renderable { + constructor(id: string, options?: InputRenderableOptions); + + /** Current value */ + value: string; + + /** Placeholder text */ + placeholder?: string; + + /** Maximum length */ + maxLength?: number; + + /** Password mode */ + password?: boolean; + + /** Cursor position */ + cursorPosition: number; + + // Methods + setValue(value: string): void; + clear(): void; + selectAll(): void; + setCursorPosition(position: number): void; + insertText(text: string): void; + deleteSelection(): void; + validate(): boolean; + } + + export class ASCIIFontRenderable extends Renderable { + constructor(id: string, options?: ASCIIFontOptions); + + /** Display text */ + text: string; + + /** Font name or definition */ + font: string | FontDefinition; + + /** Text color */ + color: string | RGBA; + + // Methods + setText(text: string): void; + setFont(font: string | FontDefinition): void; + static registerFont(name: string, definition: FontDefinition): void; + } + + export class CliRenderer { + constructor( + lib: any, + ptr: any, + stdin: NodeJS.ReadStream, + stdout: NodeJS.WriteStream, + width: number, + height: number, + config?: CliRendererConfig + ); + + /** Terminal width */ + width: number; + + /** Terminal height */ + height: number; + + /** Root component */ + root: RootRenderable; + + // Methods + start(): void; + stop(): void; + resize(width: number, height: number): void; + needsUpdate(): void; + toggleDebugOverlay(): void; + setBackgroundColor(color: string | RGBA): void; + } + + export class Timeline { + constructor(options?: TimelineOptions); + + /** Timeline duration */ + duration: number; + + /** Loop enabled */ + loop: boolean; + + /** Playing state */ + isPlaying: boolean; + + /** Current time */ + currentTime: number; + + // Methods + add(animation: AnimationOptions): Timeline; + play(): Promise; + pause(): void; + stop(): void; + seek(time: number): void; + remove(animation: AnimationOptions): void; + } + + export class OptimizedBuffer { + constructor(width: number, height: number); + + /** Buffer width */ + width: number; + + /** Buffer height */ + height: number; + + // Methods + drawText(text: string, x: number, y: number, fg?: RGBA, bg?: RGBA): void; + drawBox(x: number, y: number, width: number, height: number, options?: BoxDrawOptions): void; + setCell(x: number, y: number, char: string, fg?: RGBA, bg?: RGBA): void; + clear(x?: number, y?: number, width?: number, height?: number): void; + copyFrom(source: OptimizedBuffer, x: number, y: number): void; + markDirty(x: number, y: number, width: number, height: number): void; + getDirtyRegion(): { x: number; y: number; width: number; height: number } | null; + } + + // Helper Types + export interface ParsedKey { + name: string; + ctrl: boolean; + meta: boolean; + shift: boolean; + alt: boolean; + sequence?: string; + code?: string; + } + + export interface MouseEvent { + type: MouseEventType; + button: number; + x: number; + y: number; + source: Renderable; + target: Renderable | null; + modifiers: { + shift: boolean; + alt: boolean; + ctrl: boolean; + }; + scroll?: { + direction: 'up' | 'down'; + delta: number; + }; + preventDefault(): void; + } + + export interface FontDefinition { + height: number; + chars: { + [char: string]: string[]; + }; + kerning?: { + [pair: string]: number; + }; + } + + export interface RGBA { + r: number; + g: number; + b: number; + a: number; + + static fromHex(hex: string): RGBA; + static fromValues(r: number, g: number, b: number, a: number): RGBA; + static fromHSL(h: number, s: number, l: number, a?: number): RGBA; + static white(): RGBA; + static black(): RGBA; + static transparent(): RGBA; + static blend(from: RGBA, to: RGBA, alpha: number): RGBA; + } + + // Enums + export type MouseEventType = + | 'down' + | 'up' + | 'move' + | 'drag' + | 'drag-end' + | 'drop' + | 'over' + | 'out' + | 'scroll'; + + export type BorderStyle = 'single' | 'double' | 'rounded' | 'heavy'; + + export type AlignString = 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline'; + + export type JustifyString = 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly'; + + export type FlexDirectionString = 'row' | 'column' | 'row-reverse' | 'column-reverse'; + + export type PositionTypeString = 'relative' | 'absolute'; + + // Easing Functions + export const Easing: { + linear: (t: number) => number; + easeInQuad: (t: number) => number; + easeOutQuad: (t: number) => number; + easeInOutQuad: (t: number) => number; + easeInCubic: (t: number) => number; + easeOutCubic: (t: number) => number; + easeInOutCubic: (t: number) => number; + easeInExpo: (t: number) => number; + easeOutExpo: (t: number) => number; + easeInOutExpo: (t: number) => number; + easeInBounce: (t: number) => number; + easeOutBounce: (t: number) => number; + easeInOutBounce: (t: number) => number; + easeInElastic: (t: number) => number; + easeOutElastic: (t: number) => number; + easeInOutElastic: (t: number) => number; + easeInBack: (t: number) => number; + easeOutBack: (t: number) => number; + easeInOutBack: (t: number) => number; + }; + + // Debug + export enum DebugOverlayCorner { + TOP_LEFT = 'top-left', + TOP_RIGHT = 'top-right', + BOTTOM_LEFT = 'bottom-left', + BOTTOM_RIGHT = 'bottom-right' + } +} + +// Global type augmentations for better IntelliSense +declare global { + namespace NodeJS { + interface ProcessEnv { + OPENTUI_DEBUG?: string; + OPENTUI_THEME?: string; + OPENTUI_RENDERER?: string; + } + } +} + +export {}; \ No newline at end of file diff --git a/packages/core/src/types/ASCIIFontOptions.d.ts b/packages/core/src/types/ASCIIFontOptions.d.ts new file mode 100644 index 00000000..ea4e5d15 --- /dev/null +++ b/packages/core/src/types/ASCIIFontOptions.d.ts @@ -0,0 +1,136 @@ +/** + * ASCIIFontOptions configuration options + * + * @public + * @category Configuration + */ +export interface ASCIIFontOptions { + alignItems?: AlignString; + + bg?: RGBA; + + bottom?: number | string | string; + + buffered?: boolean; + + enableLayout?: boolean; + + fg?: RGBA | RGBA[]; + + flexBasis?: number | string; + + flexDirection?: FlexDirectionString; + + flexGrow?: number; + + flexShrink?: number; + + font?: 'tiny' | 'block' | 'shade' | 'slick'; + + height?: number | string | string; + + justifyContent?: JustifyString; + + left?: number | string | string; + + live?: boolean; + + margin?: number | string | string; + + marginBottom?: number | string | string; + + marginLeft?: number | string | string; + + marginRight?: number | string | string; + + marginTop?: number | string | string; + + maxHeight?: number; + + maxWidth?: number; + + minHeight?: number; + + minWidth?: number; + + /** + * (key: ParsedKey) => void + */ + onKeyDown?: { namedArgs: { key: ParsedKey } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDown?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrag?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDragEnd?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrop?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseMove?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOut?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOver?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseScroll?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseUp?: { namedArgs: { event: MouseEvent } }; + + padding?: any; + + paddingBottom?: any; + + paddingLeft?: any; + + paddingRight?: any; + + paddingTop?: any; + + position?: PositionTypeString; + + right?: number | string | string; + + selectable?: boolean; + + selectionBg?: string | RGBA; + + selectionFg?: string | RGBA; + + text?: string; + + top?: number | string | string; + + visible?: boolean; + + width?: number | string | string; + + zIndex?: number; + +} diff --git a/packages/core/src/types/AnimationOptions.d.ts b/packages/core/src/types/AnimationOptions.d.ts new file mode 100644 index 00000000..fa799be3 --- /dev/null +++ b/packages/core/src/types/AnimationOptions.d.ts @@ -0,0 +1,40 @@ +/** + * AnimationOptions configuration options + * + * @public + * @category Configuration + */ +export interface AnimationOptions { + alternate?: boolean; + + duration: number; + + ease?: EasingFunctions; + + loop?: any; + + loopDelay?: number; + + /** + * () => void + */ + onComplete?: any; + + /** + * () => void + */ + onLoop?: any; + + /** + * () => void + */ + onStart?: any; + + /** + * (animation: JSAnimation) => void + */ + onUpdate?: { namedArgs: { animation: JSAnimation } }; + + once?: boolean; + +} diff --git a/packages/core/src/types/BorderConfig.d.ts b/packages/core/src/types/BorderConfig.d.ts new file mode 100644 index 00000000..8734ada7 --- /dev/null +++ b/packages/core/src/types/BorderConfig.d.ts @@ -0,0 +1,16 @@ +/** + * BorderConfig configuration options + * + * @public + * @category Configuration + */ +export interface BorderConfig { + border: boolean | BorderSides[]; + + borderColor?: ColorInput; + + borderStyle: BorderStyle; + + customBorderChars?: BorderCharacters; + +} diff --git a/packages/core/src/types/BoxDrawOptions.d.ts b/packages/core/src/types/BoxDrawOptions.d.ts new file mode 100644 index 00000000..41f18aad --- /dev/null +++ b/packages/core/src/types/BoxDrawOptions.d.ts @@ -0,0 +1,32 @@ +/** + * BoxDrawOptions configuration options + * + * @public + * @category Configuration + */ +export interface BoxDrawOptions { + backgroundColor: ColorInput; + + border: boolean | BorderSides[]; + + borderColor: ColorInput; + + borderStyle: BorderStyle; + + customBorderChars?: BorderCharacters; + + height: number; + + shouldFill?: boolean; + + title?: string; + + titleAlignment?: 'left' | 'center' | 'right'; + + width: number; + + x: number; + + y: number; + +} diff --git a/packages/core/src/types/BoxOptions.d.ts b/packages/core/src/types/BoxOptions.d.ts new file mode 100644 index 00000000..f70301dd --- /dev/null +++ b/packages/core/src/types/BoxOptions.d.ts @@ -0,0 +1,140 @@ +/** + * BoxOptions configuration options + * + * @public + * @category Configuration + */ +export interface BoxOptions { + alignItems?: AlignString; + + backgroundColor?: string | RGBA; + + border?: boolean | BorderSides[]; + + borderColor?: string | RGBA; + + borderStyle?: BorderStyle; + + bottom?: number | string | string; + + buffered?: boolean; + + customBorderChars?: BorderCharacters; + + enableLayout?: boolean; + + flexBasis?: number | string; + + flexDirection?: FlexDirectionString; + + flexGrow?: number; + + flexShrink?: number; + + focusedBorderColor?: ColorInput; + + height?: number | string | string; + + justifyContent?: JustifyString; + + left?: number | string | string; + + live?: boolean; + + margin?: number | string | string; + + marginBottom?: number | string | string; + + marginLeft?: number | string | string; + + marginRight?: number | string | string; + + marginTop?: number | string | string; + + maxHeight?: number; + + maxWidth?: number; + + minHeight?: number; + + minWidth?: number; + + /** + * (key: ParsedKey) => void + */ + onKeyDown?: { namedArgs: { key: ParsedKey } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDown?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrag?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDragEnd?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrop?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseMove?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOut?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOver?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseScroll?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseUp?: { namedArgs: { event: MouseEvent } }; + + padding?: any; + + paddingBottom?: any; + + paddingLeft?: any; + + paddingRight?: any; + + paddingTop?: any; + + position?: PositionTypeString; + + right?: number | string | string; + + shouldFill?: boolean; + + title?: string; + + titleAlignment?: 'left' | 'center' | 'right'; + + top?: number | string | string; + + visible?: boolean; + + width?: number | string | string; + + zIndex?: number; + +} diff --git a/packages/core/src/types/CliRendererConfig.d.ts b/packages/core/src/types/CliRendererConfig.d.ts new file mode 100644 index 00000000..8495d3bf --- /dev/null +++ b/packages/core/src/types/CliRendererConfig.d.ts @@ -0,0 +1,40 @@ +/** + * CliRendererConfig configuration options + * + * @public + * @category Configuration + */ +export interface CliRendererConfig { + consoleOptions?: ConsoleOptions; + + debounceDelay?: number; + + enableMouseMovement?: boolean; + + exitOnCtrlC?: boolean; + + experimental_splitHeight?: number; + + gatherStats?: boolean; + + maxStatSamples?: number; + + memorySnapshotInterval?: number; + + postProcessFns?: { namedArgs: { buffer: OptimizedBuffer; deltaTime: number } }[]; + + stdin?: global.NodeJS.ReadStream; + + stdout?: global.NodeJS.WriteStream; + + targetFps?: number; + + useAlternateScreen?: boolean; + + useConsole?: boolean; + + useMouse?: boolean; + + useThread?: boolean; + +} diff --git a/packages/core/src/types/ConsoleOptions.d.ts b/packages/core/src/types/ConsoleOptions.d.ts new file mode 100644 index 00000000..71f056eb --- /dev/null +++ b/packages/core/src/types/ConsoleOptions.d.ts @@ -0,0 +1,40 @@ +/** + * ConsoleOptions configuration options + * + * @public + * @category Configuration + */ +export interface ConsoleOptions { + backgroundColor?: ColorInput; + + colorDebug?: ColorInput; + + colorDefault?: ColorInput; + + colorError?: ColorInput; + + colorInfo?: ColorInput; + + colorWarn?: ColorInput; + + cursorColor?: ColorInput; + + maxDisplayLines?: number; + + maxStoredLogs?: number; + + position?: ConsolePosition; + + sizePercent?: number; + + startInDebugMode?: boolean; + + title?: string; + + titleBarColor?: ColorInput; + + titleBarTextColor?: ColorInput; + + zIndex?: number; + +} diff --git a/packages/core/src/types/ExplosionEffectParameters.d.ts b/packages/core/src/types/ExplosionEffectParameters.d.ts new file mode 100644 index 00000000..c5829399 --- /dev/null +++ b/packages/core/src/types/ExplosionEffectParameters.d.ts @@ -0,0 +1,37 @@ +/** + * ExplosionEffectParameters configuration options + * + * @public + * @category Configuration + */ +export interface ExplosionEffectParameters { + angularVelocityMax: Vector3; + + angularVelocityMin: Vector3; + + durationMs: number; + + fadeOut: boolean; + + gravity: number; + + gravityScale: number; + + initialVelocityYBoost: number; + + /** + * () => NodeMaterial + */ + materialFactory: any; + + numCols: number; + + numRows: number; + + strength: number; + + strengthVariation: number; + + zVariationStrength: number; + +} diff --git a/packages/core/src/types/FrameBufferOptions.d.ts b/packages/core/src/types/FrameBufferOptions.d.ts new file mode 100644 index 00000000..5add94fd --- /dev/null +++ b/packages/core/src/types/FrameBufferOptions.d.ts @@ -0,0 +1,124 @@ +/** + * FrameBufferOptions configuration options + * + * @public + * @category Configuration + */ +export interface FrameBufferOptions { + alignItems?: AlignString; + + bottom?: number | string | string; + + buffered?: boolean; + + enableLayout?: boolean; + + flexBasis?: number | string; + + flexDirection?: FlexDirectionString; + + flexGrow?: number; + + flexShrink?: number; + + height: number; + + justifyContent?: JustifyString; + + left?: number | string | string; + + live?: boolean; + + margin?: number | string | string; + + marginBottom?: number | string | string; + + marginLeft?: number | string | string; + + marginRight?: number | string | string; + + marginTop?: number | string | string; + + maxHeight?: number; + + maxWidth?: number; + + minHeight?: number; + + minWidth?: number; + + /** + * (key: ParsedKey) => void + */ + onKeyDown?: { namedArgs: { key: ParsedKey } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDown?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrag?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDragEnd?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrop?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseMove?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOut?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOver?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseScroll?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseUp?: { namedArgs: { event: MouseEvent } }; + + padding?: any; + + paddingBottom?: any; + + paddingLeft?: any; + + paddingRight?: any; + + paddingTop?: any; + + position?: PositionTypeString; + + respectAlpha?: boolean; + + right?: number | string | string; + + top?: number | string | string; + + visible?: boolean; + + width: number; + + zIndex?: number; + +} diff --git a/packages/core/src/types/InputRenderableOptions.d.ts b/packages/core/src/types/InputRenderableOptions.d.ts new file mode 100644 index 00000000..fcc476cf --- /dev/null +++ b/packages/core/src/types/InputRenderableOptions.d.ts @@ -0,0 +1,140 @@ +/** + * InputRenderableOptions configuration options + * + * @public + * @category Configuration + */ +export interface InputRenderableOptions { + alignItems?: AlignString; + + backgroundColor?: ColorInput; + + bottom?: number | string | string; + + buffered?: boolean; + + cursorColor?: ColorInput; + + enableLayout?: boolean; + + flexBasis?: number | string; + + flexDirection?: FlexDirectionString; + + flexGrow?: number; + + flexShrink?: number; + + focusedBackgroundColor?: ColorInput; + + focusedTextColor?: ColorInput; + + height?: number | string | string; + + justifyContent?: JustifyString; + + left?: number | string | string; + + live?: boolean; + + margin?: number | string | string; + + marginBottom?: number | string | string; + + marginLeft?: number | string | string; + + marginRight?: number | string | string; + + marginTop?: number | string | string; + + maxHeight?: number; + + maxLength?: number; + + maxWidth?: number; + + minHeight?: number; + + minWidth?: number; + + /** + * (key: ParsedKey) => void + */ + onKeyDown?: { namedArgs: { key: ParsedKey } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDown?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrag?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDragEnd?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrop?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseMove?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOut?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOver?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseScroll?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseUp?: { namedArgs: { event: MouseEvent } }; + + padding?: any; + + paddingBottom?: any; + + paddingLeft?: any; + + paddingRight?: any; + + paddingTop?: any; + + placeholder?: string; + + placeholderColor?: ColorInput; + + position?: PositionTypeString; + + right?: number | string | string; + + textColor?: ColorInput; + + top?: number | string | string; + + value?: string; + + visible?: boolean; + + width?: number | string | string; + + zIndex?: number; + +} diff --git a/packages/core/src/types/LayoutOptions.d.ts b/packages/core/src/types/LayoutOptions.d.ts new file mode 100644 index 00000000..9300858d --- /dev/null +++ b/packages/core/src/types/LayoutOptions.d.ts @@ -0,0 +1,60 @@ +/** + * LayoutOptions configuration options + * + * @public + * @category Configuration + */ +export interface LayoutOptions { + alignItems?: AlignString; + + bottom?: number | string | string; + + enableLayout?: boolean; + + flexBasis?: number | string; + + flexDirection?: FlexDirectionString; + + flexGrow?: number; + + flexShrink?: number; + + justifyContent?: JustifyString; + + left?: number | string | string; + + margin?: number | string | string; + + marginBottom?: number | string | string; + + marginLeft?: number | string | string; + + marginRight?: number | string | string; + + marginTop?: number | string | string; + + maxHeight?: number; + + maxWidth?: number; + + minHeight?: number; + + minWidth?: number; + + padding?: any; + + paddingBottom?: any; + + paddingLeft?: any; + + paddingRight?: any; + + paddingTop?: any; + + position?: PositionTypeString; + + right?: number | string | string; + + top?: number | string | string; + +} diff --git a/packages/core/src/types/RenderableOptions.d.ts b/packages/core/src/types/RenderableOptions.d.ts new file mode 100644 index 00000000..2f26cdb9 --- /dev/null +++ b/packages/core/src/types/RenderableOptions.d.ts @@ -0,0 +1,122 @@ +/** + * RenderableOptions configuration options + * + * @public + * @category Configuration + */ +export interface RenderableOptions { + alignItems?: AlignString; + + bottom?: number | string | string; + + buffered?: boolean; + + enableLayout?: boolean; + + flexBasis?: number | string; + + flexDirection?: FlexDirectionString; + + flexGrow?: number; + + flexShrink?: number; + + height?: number | string | string; + + justifyContent?: JustifyString; + + left?: number | string | string; + + live?: boolean; + + margin?: number | string | string; + + marginBottom?: number | string | string; + + marginLeft?: number | string | string; + + marginRight?: number | string | string; + + marginTop?: number | string | string; + + maxHeight?: number; + + maxWidth?: number; + + minHeight?: number; + + minWidth?: number; + + /** + * (key: ParsedKey) => void + */ + onKeyDown?: { namedArgs: { key: ParsedKey } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDown?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrag?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDragEnd?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrop?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseMove?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOut?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOver?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseScroll?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseUp?: { namedArgs: { event: MouseEvent } }; + + padding?: any; + + paddingBottom?: any; + + paddingLeft?: any; + + paddingRight?: any; + + paddingTop?: any; + + position?: PositionTypeString; + + right?: number | string | string; + + top?: number | string | string; + + visible?: boolean; + + width?: number | string | string; + + zIndex?: number; + +} diff --git a/packages/core/src/types/SelectRenderableOptions.d.ts b/packages/core/src/types/SelectRenderableOptions.d.ts new file mode 100644 index 00000000..36d9c076 --- /dev/null +++ b/packages/core/src/types/SelectRenderableOptions.d.ts @@ -0,0 +1,152 @@ +/** + * SelectRenderableOptions configuration options + * + * @public + * @category Configuration + */ +export interface SelectRenderableOptions { + alignItems?: AlignString; + + backgroundColor?: ColorInput; + + bottom?: number | string | string; + + buffered?: boolean; + + descriptionColor?: ColorInput; + + enableLayout?: boolean; + + fastScrollStep?: number; + + flexBasis?: number | string; + + flexDirection?: FlexDirectionString; + + flexGrow?: number; + + flexShrink?: number; + + focusedBackgroundColor?: ColorInput; + + focusedTextColor?: ColorInput; + + font?: 'tiny' | 'block' | 'shade' | 'slick'; + + height?: number | string | string; + + itemSpacing?: number; + + justifyContent?: JustifyString; + + left?: number | string | string; + + live?: boolean; + + margin?: number | string | string; + + marginBottom?: number | string | string; + + marginLeft?: number | string | string; + + marginRight?: number | string | string; + + marginTop?: number | string | string; + + maxHeight?: number; + + maxWidth?: number; + + minHeight?: number; + + minWidth?: number; + + /** + * (key: ParsedKey) => void + */ + onKeyDown?: { namedArgs: { key: ParsedKey } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDown?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrag?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDragEnd?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrop?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseMove?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOut?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOver?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseScroll?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseUp?: { namedArgs: { event: MouseEvent } }; + + options?: SelectOption[]; + + padding?: any; + + paddingBottom?: any; + + paddingLeft?: any; + + paddingRight?: any; + + paddingTop?: any; + + position?: PositionTypeString; + + right?: number | string | string; + + selectedBackgroundColor?: ColorInput; + + selectedDescriptionColor?: ColorInput; + + selectedTextColor?: ColorInput; + + showDescription?: boolean; + + showScrollIndicator?: boolean; + + textColor?: ColorInput; + + top?: number | string | string; + + visible?: boolean; + + width?: number | string | string; + + wrapSelection?: boolean; + + zIndex?: number; + +} diff --git a/packages/core/src/types/TabSelectRenderableOptions.d.ts b/packages/core/src/types/TabSelectRenderableOptions.d.ts new file mode 100644 index 00000000..056bff83 --- /dev/null +++ b/packages/core/src/types/TabSelectRenderableOptions.d.ts @@ -0,0 +1,148 @@ +/** + * TabSelectRenderableOptions configuration options + * + * @public + * @category Configuration + */ +export interface TabSelectRenderableOptions { + alignItems?: AlignString; + + backgroundColor?: ColorInput; + + bottom?: number | string | string; + + buffered?: boolean; + + enableLayout?: boolean; + + flexBasis?: number | string; + + flexDirection?: FlexDirectionString; + + flexGrow?: number; + + flexShrink?: number; + + focusedBackgroundColor?: ColorInput; + + focusedTextColor?: ColorInput; + + height?: number; + + justifyContent?: JustifyString; + + left?: number | string | string; + + live?: boolean; + + margin?: number | string | string; + + marginBottom?: number | string | string; + + marginLeft?: number | string | string; + + marginRight?: number | string | string; + + marginTop?: number | string | string; + + maxHeight?: number; + + maxWidth?: number; + + minHeight?: number; + + minWidth?: number; + + /** + * (key: ParsedKey) => void + */ + onKeyDown?: { namedArgs: { key: ParsedKey } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDown?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrag?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDragEnd?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrop?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseMove?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOut?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOver?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseScroll?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseUp?: { namedArgs: { event: MouseEvent } }; + + options?: TabSelectOption[]; + + padding?: any; + + paddingBottom?: any; + + paddingLeft?: any; + + paddingRight?: any; + + paddingTop?: any; + + position?: PositionTypeString; + + right?: number | string | string; + + selectedBackgroundColor?: ColorInput; + + selectedDescriptionColor?: ColorInput; + + selectedTextColor?: ColorInput; + + showDescription?: boolean; + + showScrollArrows?: boolean; + + showUnderline?: boolean; + + tabWidth?: number; + + textColor?: ColorInput; + + top?: number | string | string; + + visible?: boolean; + + width?: number | string | string; + + wrapSelection?: boolean; + + zIndex?: number; + +} diff --git a/packages/core/src/types/TextOptions.d.ts b/packages/core/src/types/TextOptions.d.ts new file mode 100644 index 00000000..39580b99 --- /dev/null +++ b/packages/core/src/types/TextOptions.d.ts @@ -0,0 +1,136 @@ +/** + * TextOptions configuration options + * + * @public + * @category Configuration + */ +export interface TextOptions { + alignItems?: AlignString; + + attributes?: number; + + bg?: string | RGBA; + + bottom?: number | string | string; + + buffered?: boolean; + + content?: StyledText | string; + + enableLayout?: boolean; + + fg?: string | RGBA; + + flexBasis?: number | string; + + flexDirection?: FlexDirectionString; + + flexGrow?: number; + + flexShrink?: number; + + height?: number | string | string; + + justifyContent?: JustifyString; + + left?: number | string | string; + + live?: boolean; + + margin?: number | string | string; + + marginBottom?: number | string | string; + + marginLeft?: number | string | string; + + marginRight?: number | string | string; + + marginTop?: number | string | string; + + maxHeight?: number; + + maxWidth?: number; + + minHeight?: number; + + minWidth?: number; + + /** + * (key: ParsedKey) => void + */ + onKeyDown?: { namedArgs: { key: ParsedKey } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDown?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrag?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDragEnd?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseDrop?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseMove?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOut?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseOver?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseScroll?: { namedArgs: { event: MouseEvent } }; + + /** + * (event: MouseEvent) => void + */ + onMouseUp?: { namedArgs: { event: MouseEvent } }; + + padding?: any; + + paddingBottom?: any; + + paddingLeft?: any; + + paddingRight?: any; + + paddingTop?: any; + + position?: PositionTypeString; + + right?: number | string | string; + + selectable?: boolean; + + selectionBg?: string | RGBA; + + selectionFg?: string | RGBA; + + top?: number | string | string; + + visible?: boolean; + + width?: number | string | string; + + zIndex?: number; + +} diff --git a/packages/core/src/types/ThreeCliRendererOptions.d.ts b/packages/core/src/types/ThreeCliRendererOptions.d.ts new file mode 100644 index 00000000..69d66e8c --- /dev/null +++ b/packages/core/src/types/ThreeCliRendererOptions.d.ts @@ -0,0 +1,24 @@ +/** + * ThreeCliRendererOptions configuration options + * + * @public + * @category Configuration + */ +export interface ThreeCliRendererOptions { + alpha?: boolean; + + autoResize?: boolean; + + backgroundColor?: RGBA; + + focalLength?: number; + + height: number; + + libPath?: string; + + superSample?: SuperSampleType; + + width: number; + +} diff --git a/packages/core/src/types/TimelineOptions.d.ts b/packages/core/src/types/TimelineOptions.d.ts new file mode 100644 index 00000000..5c93d3c7 --- /dev/null +++ b/packages/core/src/types/TimelineOptions.d.ts @@ -0,0 +1,24 @@ +/** + * TimelineOptions configuration options + * + * @public + * @category Configuration + */ +export interface TimelineOptions { + autoplay?: boolean; + + duration?: number; + + loop?: boolean; + + /** + * () => void + */ + onComplete?: any; + + /** + * () => void + */ + onPause?: any; + +} diff --git a/packages/core/src/types/index.d.ts b/packages/core/src/types/index.d.ts new file mode 100644 index 00000000..0da0f9a0 --- /dev/null +++ b/packages/core/src/types/index.d.ts @@ -0,0 +1,78 @@ +/** + * OpenTUI Type Definitions + * + * This module exports all configuration interfaces and types used by OpenTUI components. + * + * @module @opentui/core/types + * @packageDocumentation + */ + +// Component Options +export type { ASCIIFontOptions } from './ASCIIFontOptions'; +export type { AnimationOptions } from './AnimationOptions'; +export type { BorderConfig } from './BorderConfig'; +export type { BoxDrawOptions } from './BoxDrawOptions'; +export type { BoxOptions } from './BoxOptions'; +export type { CliRendererConfig } from './CliRendererConfig'; +export type { ConsoleOptions } from './ConsoleOptions'; +export type { ExplosionEffectParameters } from './ExplosionEffectParameters'; +export type { FrameBufferOptions } from './FrameBufferOptions'; +export type { InputRenderableOptions } from './InputRenderableOptions'; +export type { LayoutOptions } from './LayoutOptions'; +export type { RenderableOptions } from './RenderableOptions'; +export type { SelectRenderableOptions } from './SelectRenderableOptions'; +export type { TabSelectRenderableOptions } from './TabSelectRenderableOptions'; +export type { TextOptions } from './TextOptions'; +export type { ThreeCliRendererOptions } from './ThreeCliRendererOptions'; +export type { TimelineOptions } from './TimelineOptions'; + +// Re-export commonly used types +export type { + BoxOptions, + TextOptions, + InputRenderableOptions, + ASCIIFontOptions, + AnimationOptions, + TimelineOptions, + CliRendererConfig +} from './index'; + +/** + * Common color input type + */ +export type ColorInput = string | RGBA; + +/** + * RGBA color representation + */ +export interface RGBA { + r: number; + g: number; + b: number; + a: number; +} + +/** + * Border style options + */ +export type BorderStyle = 'single' | 'double' | 'rounded' | 'heavy'; + +/** + * Flexbox alignment options + */ +export type AlignString = 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline'; + +/** + * Flexbox justification options + */ +export type JustifyString = 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly'; + +/** + * Flexbox direction options + */ +export type FlexDirectionString = 'row' | 'column' | 'row-reverse' | 'column-reverse'; + +/** + * Position type options + */ +export type PositionTypeString = 'relative' | 'absolute'; diff --git a/packages/core/src/types/package.json b/packages/core/src/types/package.json new file mode 100644 index 00000000..279a1a58 --- /dev/null +++ b/packages/core/src/types/package.json @@ -0,0 +1,5 @@ +{ + "name": "@opentui/core/types", + "types": "./index.d.ts", + "description": "TypeScript type definitions for OpenTUI" +} \ No newline at end of file diff --git a/scripts/jsdoc-to-tsdoc.js b/scripts/jsdoc-to-tsdoc.js new file mode 100755 index 00000000..f593c020 --- /dev/null +++ b/scripts/jsdoc-to-tsdoc.js @@ -0,0 +1,158 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +const jsdocDir = path.join(__dirname, '../packages/core/docs/api/jsdoc'); +const outputDir = path.join(__dirname, '../packages/core/docs/api/types'); + +// Create output directory +if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); +} + +// Function to convert JSDoc to TSDoc +function convertJSDocToTSDoc(content, filename) { + const typeName = filename.replace('.js', ''); + + // Extract JSDoc comments and properties + const jsdocRegex = /\/\*\*([\s\S]*?)\*\//g; + const propertyRegex = /@property\s+\{([^}]+)\}\s+(\[?[\w.]+\]?)\s*-?\s*(.*)/g; + + let tsDoc = `/**\n * ${typeName} interface\n`; + + // Extract description from first JSDoc block + const firstMatch = jsdocRegex.exec(content); + if (firstMatch) { + const lines = firstMatch[1].split('\n'); + const description = lines + .filter(line => !line.includes('@') && line.trim().length > 0) + .map(line => line.replace(/^\s*\*\s?/, '')) + .join(' ') + .trim(); + + if (description && !description.includes('Generated from:')) { + tsDoc += ` * ${description}\n`; + } + } + + tsDoc += ` * \n * @public\n */\n`; + tsDoc += `export interface ${typeName} {\n`; + + // Reset regex + propertyRegex.lastIndex = 0; + + // Extract properties + let match; + const properties = []; + + while ((match = propertyRegex.exec(content)) !== null) { + const [, type, name, description] = match; + const isOptional = name.startsWith('[') && name.endsWith(']'); + const propName = isOptional ? name.slice(1, -1) : name; + const cleanName = propName.split('.').pop(); // Handle nested properties + + properties.push({ + name: cleanName, + type: mapJSTypeToTS(type), + description: description.trim(), + optional: isOptional + }); + } + + // Add properties to interface + properties.forEach(prop => { + if (prop.description) { + tsDoc += ` /**\n * ${prop.description}\n */\n`; + } + tsDoc += ` ${prop.name}${prop.optional ? '?' : ''}: ${prop.type};\n\n`; + }); + + tsDoc += '}\n'; + + return tsDoc; +} + +// Map JS types to TypeScript types +function mapJSTypeToTS(jsType) { + const typeMap = { + 'String': 'string', + 'string': 'string', + 'Number': 'number', + 'number': 'number', + 'Boolean': 'boolean', + 'boolean': 'boolean', + 'Object': 'Record', + 'object': 'Record', + 'Array': 'any[]', + 'array': 'any[]', + 'Function': '(...args: any[]) => any', + 'function': '(...args: any[]) => any', + 'any': 'any', + '*': 'any' + }; + + // Handle union types + if (jsType.includes('|')) { + return jsType.split('|') + .map(t => mapJSTypeToTS(t.trim())) + .join(' | '); + } + + // Handle array types + if (jsType.includes('[]')) { + const baseType = jsType.replace('[]', ''); + return `${mapJSTypeToTS(baseType)}[]`; + } + + // Handle specific OpenTUI types + if (jsType.includes('RGBA') || jsType.includes('ColorInput')) { + return jsType; // Keep as-is + } + + return typeMap[jsType] || jsType; +} + +// Process all JSDoc files +const files = fs.readdirSync(jsdocDir).filter(f => f.endsWith('.js')); + +console.log('Converting JSDoc to TSDoc...\n'); + +files.forEach(file => { + if (file === 'all-types.js') { + // Skip the aggregated file + return; + } + + const inputPath = path.join(jsdocDir, file); + const outputFile = file.replace('.js', '.d.ts'); + const outputPath = path.join(outputDir, outputFile); + + const content = fs.readFileSync(inputPath, 'utf8'); + const tsDoc = convertJSDocToTSDoc(content, file); + + fs.writeFileSync(outputPath, tsDoc); + console.log(`āœ“ Converted ${file} → ${outputFile}`); +}); + +// Create an index file that exports all types +const indexContent = `/** + * OpenTUI Type Definitions + * + * @packageDocumentation + */ + +${files + .filter(f => f !== 'all-types.js') + .map(f => { + const typeName = f.replace('.js', ''); + return `export type { ${typeName} } from './${typeName}';`; + }) + .join('\n')} +`; + +fs.writeFileSync(path.join(outputDir, 'index.d.ts'), indexContent); +console.log('\nāœ“ Created index.d.ts'); + +console.log(`\nāœ… TSDoc conversion complete!`); +console.log(`šŸ“ Output: ${outputDir}`); \ No newline at end of file diff --git a/scripts/schemas-to-tsdoc.cjs b/scripts/schemas-to-tsdoc.cjs new file mode 100755 index 00000000..dd7920f0 --- /dev/null +++ b/scripts/schemas-to-tsdoc.cjs @@ -0,0 +1,226 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +const schemasDir = path.join(__dirname, '../packages/core/docs/api/schemas'); +const outputDir = path.join(__dirname, '../packages/core/src/types'); + +// Create output directory +if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); +} + +// Convert JSON Schema to TypeScript with TSDoc +function schemaToTypeScript(schema, typeName) { + let tsContent = ''; + + // Find the main definition + const definition = schema.definitions?.[typeName] || schema; + + if (!definition.properties) { + console.warn(`No properties found for ${typeName}`); + return ''; + } + + // Add TSDoc header + tsContent += `/**\n`; + tsContent += ` * ${typeName} configuration options\n`; + + if (definition.description || definition.$comment) { + tsContent += ` * \n`; + tsContent += ` * ${definition.description || definition.$comment}\n`; + } + + tsContent += ` * \n`; + tsContent += ` * @public\n`; + tsContent += ` * @category Configuration\n`; + tsContent += ` */\n`; + tsContent += `export interface ${typeName} {\n`; + + // Process properties + Object.entries(definition.properties).forEach(([propName, propDef]) => { + const isRequired = definition.required?.includes(propName); + + // Add property documentation + if (propDef.description || propDef.$comment) { + tsContent += ` /**\n`; + tsContent += ` * ${propDef.description || propDef.$comment}\n`; + + if (propDef.default !== undefined) { + tsContent += ` * @defaultValue ${JSON.stringify(propDef.default)}\n`; + } + + if (propDef.enum) { + tsContent += ` * @remarks Possible values: ${propDef.enum.map(v => `'${v}'`).join(', ')}\n`; + } + + tsContent += ` */\n`; + } + + // Add property definition + const propType = jsonSchemaTypeToTS(propDef); + tsContent += ` ${propName}${isRequired ? '' : '?'}: ${propType};\n\n`; + }); + + tsContent += '}\n'; + + return tsContent; +} + +// Convert JSON Schema type to TypeScript type +function jsonSchemaTypeToTS(schema) { + if (schema.$ref) { + // Extract type name from ref + const typeName = schema.$ref.split('/').pop(); + return typeName; + } + + if (schema.enum) { + return schema.enum.map(v => typeof v === 'string' ? `'${v}'` : v).join(' | '); + } + + if (schema.type === 'array') { + const itemType = schema.items ? jsonSchemaTypeToTS(schema.items) : 'any'; + return `${itemType}[]`; + } + + if (schema.type === 'object') { + if (schema.properties) { + const props = Object.entries(schema.properties) + .map(([key, value]) => `${key}: ${jsonSchemaTypeToTS(value)}`) + .join('; '); + return `{ ${props} }`; + } + return 'Record'; + } + + if (schema.anyOf) { + return schema.anyOf.map(s => jsonSchemaTypeToTS(s)).join(' | '); + } + + if (schema.oneOf) { + return schema.oneOf.map(s => jsonSchemaTypeToTS(s)).join(' | '); + } + + const typeMap = { + 'string': 'string', + 'number': 'number', + 'integer': 'number', + 'boolean': 'boolean', + 'null': 'null' + }; + + return typeMap[schema.type] || 'any'; +} + +// Process all schema files +const files = fs.readdirSync(schemasDir).filter(f => f.endsWith('.json')); + +console.log('Converting JSON Schemas to TypeScript with TSDoc...\n'); + +const imports = new Set(); +const typeExports = []; + +files.forEach(file => { + const typeName = file.replace('.json', ''); + const schemaPath = path.join(schemasDir, file); + const schema = JSON.parse(fs.readFileSync(schemaPath, 'utf8')); + + const tsContent = schemaToTypeScript(schema, typeName); + + if (tsContent) { + const outputFile = `${typeName}.d.ts`; + const outputPath = path.join(outputDir, outputFile); + + fs.writeFileSync(outputPath, tsContent); + typeExports.push(typeName); + console.log(`āœ“ Generated ${outputFile}`); + } +}); + +// Create index file +const indexContent = `/** + * OpenTUI Type Definitions + * + * This module exports all configuration interfaces and types used by OpenTUI components. + * + * @module @opentui/core/types + * @packageDocumentation + */ + +// Component Options +${typeExports.map(name => `export type { ${name} } from './${name}';`).join('\n')} + +// Re-export commonly used types +export type { + BoxOptions, + TextOptions, + InputRenderableOptions, + ASCIIFontOptions, + AnimationOptions, + TimelineOptions, + CliRendererConfig +} from './index'; + +/** + * Common color input type + */ +export type ColorInput = string | RGBA; + +/** + * RGBA color representation + */ +export interface RGBA { + r: number; + g: number; + b: number; + a: number; +} + +/** + * Border style options + */ +export type BorderStyle = 'single' | 'double' | 'rounded' | 'heavy'; + +/** + * Flexbox alignment options + */ +export type AlignString = 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline'; + +/** + * Flexbox justification options + */ +export type JustifyString = 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly'; + +/** + * Flexbox direction options + */ +export type FlexDirectionString = 'row' | 'column' | 'row-reverse' | 'column-reverse'; + +/** + * Position type options + */ +export type PositionTypeString = 'relative' | 'absolute'; +`; + +fs.writeFileSync(path.join(outputDir, 'index.d.ts'), indexContent); +console.log('\nāœ“ Created index.d.ts'); + +// Create a package.json for the types +const packageJson = { + "name": "@opentui/core/types", + "types": "./index.d.ts", + "description": "TypeScript type definitions for OpenTUI" +}; + +fs.writeFileSync( + path.join(outputDir, 'package.json'), + JSON.stringify(packageJson, null, 2) +); +console.log('āœ“ Created package.json'); + +console.log(`\nāœ… TSDoc type definitions generated!`); +console.log(`šŸ“ Output: ${outputDir}`); +console.log('\nUsage in TypeScript:'); +console.log(' import type { BoxOptions, TextOptions } from "@opentui/core/types";'); \ No newline at end of file diff --git a/tsconfig.ide.json b/tsconfig.ide.json new file mode 100644 index 00000000..e6b49d42 --- /dev/null +++ b/tsconfig.ide.json @@ -0,0 +1,67 @@ +{ + "compilerOptions": { + // IDE Support + "plugins": [ + { + "name": "typescript-plugin-css-modules" + } + ], + + // Enhanced IntelliSense + "strict": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictBindCallApply": true, + "strictPropertyInitialization": true, + "noImplicitThis": true, + "noImplicitAny": true, + + // Module Resolution + "moduleResolution": "node", + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + + // Type Checking + "skipLibCheck": false, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + + // Paths for IntelliSense + "baseUrl": ".", + "paths": { + "@opentui/core": ["./packages/core/src/index.ts"], + "@opentui/core/*": ["./packages/core/src/*"], + "@opentui/react": ["./packages/react/src/index.ts"], + "@opentui/react/*": ["./packages/react/src/*"], + "@opentui/solid": ["./packages/solid/src/index.ts"], + "@opentui/solid/*": ["./packages/solid/src/*"] + }, + + // Include type definitions + "types": [ + "node" + ], + "typeRoots": [ + "./node_modules/@types", + "./packages/core/src/types" + ] + }, + + "include": [ + "packages/*/src/**/*", + "packages/*/docs/**/*", + "scripts/**/*" + ], + + "exclude": [ + "node_modules", + "**/node_modules", + "dist", + "**/dist", + "build", + "**/build" + ] +} \ No newline at end of file