Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
219 changes: 219 additions & 0 deletions .vscode/opentui.code-snippets
Original file line number Diff line number Diff line change
@@ -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"
}
}
73 changes: 73 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -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
}
}
78 changes: 78 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -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 <file> # Run specific test file

# Release workflow
bun run prepare-release <version> # 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
Loading