### Install OpenTUI Keymap Source: https://opentui.com/docs/keymap/overview Install the OpenTUI Keymap package using Bun. ```bash bun install @opentui/keymap ``` -------------------------------- ### Welcome Screen Example Source: https://opentui.com/docs/components/ascii-font A comprehensive example demonstrating how to use Box, ASCIIFont, and Text components to create a welcome screen. Imports from @opentui/core. ```typescript import { Box, ASCIIFont, Text, createCliRenderer } from "@opentui/core" const renderer = await createCliRenderer() const welcomeScreen = Box( { width: "100%", height: "100%", flexDirection: "column", alignItems: "center", justifyContent: "center", }, ASCIIFont({ text: "OPENTUI", font: "huge", color: "#00FFFF", }), Text({ content: "Terminal UI Framework", fg: "#888888", }), Text({ content: "Press any key to continue...", fg: "#444444", }), ) renderer.root.add(welcomeScreen) ``` -------------------------------- ### Install OpenTUI Solid Bindings Source: https://opentui.com/docs/bindings/solid Install the necessary packages for Solid.js integration. ```bash bun install solid-js @opentui/solid ``` -------------------------------- ### Install QR Code Package Source: https://opentui.com/docs/components/qr-code Install the QR code package separately using Bun. ```bash bun install @opentui/qrcode ``` -------------------------------- ### Basic React TUI Application Setup Source: https://opentui.com/docs/bindings/react Demonstrates the fundamental setup for a React TUI application, including creating a renderer and rendering a simple 'Hello, world!' component. ```jsx import { createCliRenderer } from "@opentui/core" import { createRoot } from "@opentui/react" function App() { return Hello, world! } const renderer = await createCliRenderer() createRoot(renderer).render() ``` -------------------------------- ### Device Selection and Playback Start Source: https://opentui.com/docs/core-concepts/audio Illustrates how to list available playback devices, select a specific device, and then start the audio engine. If no playback device is available, an error is logged. ```typescript const audio = Audio.create({ autoStart: false }) const devices = audio.listPlaybackDevices() ?? [] const device = devices.find((item) => item.isDefault) ?? devices[0] if (device) { audio.selectPlaybackDevice(device.index) } if (!audio.start()) { console.error("No playback device available") } ``` -------------------------------- ### Start React DevTools Source: https://opentui.com/docs/bindings/react Command to start the React DevTools standalone application. ```bash npx react-devtools@7 ``` -------------------------------- ### Manual Installation of OpenTUI React Packages Source: https://opentui.com/docs/bindings/react Install the necessary OpenTUI React and core packages along with React itself. ```bash bun install @opentui/react @opentui/core react ``` -------------------------------- ### Basic React Keymap Setup Source: https://opentui.com/docs/keymap/react Demonstrates the fundamental setup of OpenTUI keymap bindings within a React application. It shows how to initialize the keymap, provide it via KeymapProvider, and register command bindings using the useBindings hook. ```jsx /** @jsxImportSource @opentui/react */ import { createCliRenderer } from "@opentui/core" import { createDefaultOpenTuiKeymap } from "@opentui/keymap/opentui" import { KeymapProvider, useBindings } from "@opentui/keymap/react" import { createRoot } from "@opentui/react" const renderer = await createCliRenderer() const keymap = createDefaultOpenTuiKeymap(renderer) function App() { useBindings( () => ({ commands: [ { name: "quit", run() { renderer.destroy() }, }, ], bindings: [{ key: "q", cmd: "quit" }], }), [], ) return Press q to quit } createRoot(renderer).render( , ) ``` -------------------------------- ### Install React DevTools Source: https://opentui.com/docs/bindings/react Instructions for installing the React DevTools core package for debugging OpenTUI React applications. ```bash bun add --dev react-devtools-core@7 ``` -------------------------------- ### Install OpenTUI with Bun Source: https://opentui.com/docs/getting-started Initialize a new project and add the OpenTUI core package. This is currently Bun exclusive. ```bash mkdir my-tui && cd my-tui bun init -y bun add @opentui/core ``` -------------------------------- ### Login Form Example Source: https://opentui.com/docs/bindings/react A complete example of a login form using OpenTUI React, including input fields, keyboard navigation, and status display. ```javascript import { createCliRenderer } from "@opentui/core" import { createRoot, useKeyboard } from "@opentui/react" import { useCallback, useState } from "react" function App() { const [username, setUsername] = useState("") const [password, setPassword] = useState("") const [focused, setFocused] = useState<"username" | "password">("username") const [status, setStatus] = useState("idle") useKeyboard((key) => { if (key.name === "tab") { setFocused((prev) => (prev === "username" ? "password" : "username")), } }) const handleSubmit = useCallback(() => { if (username === "admin" && password === "secret") { setStatus("success") } else { setStatus("error") } }, [username, password]) return ( Login Form {status.toUpperCase()} ) } const renderer = await createCliRenderer() createRoot(renderer).render() ``` -------------------------------- ### Install Native Packages for Multi-Platform Builds Source: https://opentui.com/docs/reference/standalone-executables Before compiling for multi-platform releases, install optional native packages for all target OS and CPU combinations using this command. Replace `` with the specific version of @opentui/core. ```bash bun install --os="*" --cpu="*" @opentui/core@ ``` -------------------------------- ### Create a Basic Solid App Source: https://opentui.com/docs/bindings/solid A minimal example of creating a Solid.js application with OpenTUI's `render` function and a basic `` component. ```typescript import { render } from "@opentui/solid" const App = () => Hello, World! render(App) ``` -------------------------------- ### File Menu Example Source: https://opentui.com/docs/components/select An example of creating a file menu using the Select component, including separators and descriptions for actions. It's wrapped in a Box for visual structure. ```typescript import { Box, Select, createCliRenderer } from "@opentui/core" const renderer = await createCliRenderer() const fileMenu = Select({ width: 25, height: 12, options: [ { name: "New", description: "Create new file (Ctrl+N)" }, { name: "Open...", description: "Open file (Ctrl+O)" }, { name: "Save", description: "Save file (Ctrl+S)" }, { name: "Save As...", description: "Save with new name" }, { name: "---", description: "" }, // Separator (visual only) { name: "Exit", description: "Quit application (Ctrl+Q)" }, ], }) const menuPanel = Box( { borderStyle: "single", borderColor: "#666", }, fileMenu, ) fileMenu.focus() renderer.root.add(menuPanel) ``` -------------------------------- ### Login Form Example Source: https://opentui.com/docs/components/input A comprehensive example demonstrating a login form with username and password inputs. It utilizes a `LabeledInput` component for structure and styling, and initializes the form by focusing the username field. ```typescript import { Box, Text, Input, delegate, createCliRenderer } from "@opentui/core" const renderer = await createCliRenderer() function LabeledInput(props: { id: string; label: string; placeholder: string }) { return delegate( { focus: `${props.id}-input` }, Box( { flexDirection: "row", marginBottom: 1 }, Text({ content: props.label.padEnd(12), fg: "#888888" }), Input({ id: `${props.id}-input`, placeholder: props.placeholder, width: 20, backgroundColor: "#222", focusedBackgroundColor: "#333", textColor: "#FFF", cursorColor: "#0F0", }), ), ) } const usernameInput = LabeledInput({ id: "username", label: "Username:", placeholder: "Enter username", }) const passwordInput = LabeledInput({ id: "password", label: "Password:", placeholder: "Enter password", }) const form = Box( { width: 40, borderStyle: "rounded", title: "Login", padding: 1, }, usernameInput, passwordInput, ) // Focus the username input usernameInput.focus() renderer.root.add(form) ``` -------------------------------- ### Delegate Mappings Example Source: https://opentui.com/docs/core-concepts/constructs Provides a concrete example of the mapping object used with `delegate()`, showing how method/property names are associated with descendant IDs for routing. ```typescript delegate( { focus: "inner-input", // .focus() -> find descendant "inner-input" and call focus() blur: "inner-input", // .blur() -> same add: "content-area", // .add() -> add children to "content-area" instead value: "inner-input", // .value get/set -> proxy to "inner-input" }, vnode, ) ``` -------------------------------- ### Start Continuous Rendering Source: https://opentui.com/docs/core-concepts/renderer Starts the render loop to run continuously at the target FPS. Use this for dynamic UIs that require constant updates. ```typescript renderer.start() // Start continuous rendering renderer.stop() // Stop the render loop ``` -------------------------------- ### Card Component Example Source: https://opentui.com/docs/components/box A functional example demonstrating how to create a reusable Card component using Box and Text, with custom styling and content. ```typescript import { Box, Text, t, bold, fg } from "@opentui/core" function Card(props: { title: string; description: string }) { return Box( { width: 40, borderStyle: "rounded", borderColor: "#666", padding: 1, margin: 1, }, Text({ content: t`${bold(fg("#00FFFF")(props.title))}`, }), Text({ content: props.description, fg: "#AAAAAA", }), ) } renderer.root.add( Box( { flexDirection: "row", flexWrap: "wrap" }, Card({ title: "Feature 1", description: "Description of feature 1" }), Card({ title: "Feature 2", description: "Description of feature 2" }), Card({ title: "Feature 3", description: "Description of feature 3" }), ), ) ``` -------------------------------- ### String Binding Examples Source: https://opentui.com/docs/keymap/core Demonstrates various string formats for defining key bindings, including single strokes, sequences, and modifier chords. ```text "x" "ctrl+x" "return" ``` ```text "dd" "s" "{count}j" ``` -------------------------------- ### Acquiring a shared resource Source: https://opentui.com/docs/keymap/core Use acquireResource(symbol, setup) to share ref-counted setup and teardown logic across multiple addon registrations. This is useful for managing shared resources efficiently. ```typescript keymap.acquireResource('myResource', async () => { // Setup logic return () => { // Teardown logic }; }); ``` -------------------------------- ### Install Bun Runtime Support Source: https://opentui.com/docs/plugins/core Import this once in your app entry to install Bun runtime support for `@opentui/core` and default core runtime entrypoints. Add first-party package runtime modules explicitly when a plugin imports them. ```typescript import "@opentui/core/runtime-plugin-support" ``` -------------------------------- ### Basic HTML Keymap Setup Source: https://opentui.com/docs/keymap/hosts Sets up a default keymap for an HTML host, registering a 'toggle-help' command bound to the '?' key. This is suitable for web applications requiring keyboard navigation or actions. ```typescript import { createDefaultHtmlKeymap } from "@opentui/keymap/html" const root = document.getElementById("app")! const keymap = createDefaultHtmlKeymap(root) keymap.registerLayer({ commands: [ { name: "toggle-help", run() { document.body.classList.toggle("help-open") }, }, ], bindings: [{ key: "?", cmd: "toggle-help" }]) ``` -------------------------------- ### Install C++ Runtime Libraries on Alpine Source: https://opentui.com/docs/reference/standalone-executables For Bun's Linux musl standalone runtime, install the standard C++ runtime libraries on Alpine Linux using this command. ```bash apk add --no-cache libstdc++ libgcc ``` -------------------------------- ### Object Binding Examples Source: https://opentui.com/docs/keymap/core Shows how to define bindings using an object format for direct normalization and for release events. ```javascript { name: "return", ctrl: true } ``` ```javascript { key: "a", event: "release", ...} ``` -------------------------------- ### Create TUI Project with React Template Source: https://opentui.com/docs/bindings/react Quickly start a new React TUI project using the 'create-tui' command with the 'react' template. ```bash bun create tui --template react ``` -------------------------------- ### Basic CLI Keymap Setup Source: https://opentui.com/docs/keymap/hosts Sets up a default keymap for the CLI, registering a 'quit' command bound to the 'q' key. This is useful for basic CLI applications needing keyboard shortcuts. ```typescript import { createCliRenderer } from "@opentui/core" import { createDefaultOpenTuiKeymap } from "@opentui/keymap/opentui" const renderer = await createCliRenderer() const keymap = createDefaultOpenTuiKeymap(renderer) keymap.registerLayer({ commands: [ { name: "quit", run() { renderer.destroy() }, }, ], bindings: [{ key: "q", cmd: "quit" }]) ``` -------------------------------- ### Declarative API Layout Example Source: https://opentui.com/docs/core-concepts/layout Shows how to construct a layout using the declarative OpenTUI API with nested Box and Text components. This example creates a container with left and right panels. ```typescript import { Box, Text } from "@opentui/core" renderer.root.add( Box( { flexDirection: "row", width: "100%", height: 10, }, Box( { flexGrow: 1, backgroundColor: "#333", padding: 1, }, Text({ content: "Left Panel" }), ), Box( { width: 20, backgroundColor: "#555", padding: 1, }, Text({ content: "Right Panel" }), ), ), ) ``` -------------------------------- ### Load External Plugins with Runtime Support Source: https://opentui.com/docs/plugins/react This snippet demonstrates loading external plugins from disk at runtime using Bun. It installs runtime support and then registers the loaded plugin. ```typescript import "@opentui/react/runtime-plugin-support" const mod = await import(pathToFileURL(pluginPath).href) registry.register(mod.loadExternalPlugin()) ``` -------------------------------- ### Basic Flexbox Container Setup Source: https://opentui.com/docs/core-concepts/layout Sets up a root container with row direction, space-between justification, and center alignment for child elements. Requires creating a CLI renderer and BoxRenderable instances. ```typescript import { BoxRenderable, createCliRenderer } from "@opentui/core" const renderer = await createCliRenderer() const container = new BoxRenderable(renderer, { id: "container", flexDirection: "row", justifyContent: "space-between", alignItems: "center", width: "100%", height: 10, }) const leftPanel = new BoxRenderable(renderer, { id: "left", flexGrow: 1, height: 10, backgroundColor: "#444", }) const rightPanel = new BoxRenderable(renderer, { id: "right", width: 20, height: 10, backgroundColor: "#666", }) container.add(leftPanel) container.add(rightPanel) renderer.root.add(container) ``` -------------------------------- ### Basic Line Number Setup Source: https://opentui.com/docs/components/line-number Demonstrates how to initialize and add a LineNumberRenderable to a CodeRenderable within a ScrollBoxRenderable. ```typescript import { CodeRenderable, LineNumberRenderable, ScrollBoxRenderable, SyntaxStyle, RGBA, createCliRenderer, } from "@opentui/core" const renderer = await createCliRenderer() const syntaxStyle = SyntaxStyle.fromStyles({ default: { fg: RGBA.fromHex("#E6EDF3") }, }) const code = new CodeRenderable(renderer, { id: "code", content: "const x = 1\nconst y = 2\n", filetype: "typescript", syntaxStyle, width: "100%", }) const lineNumbers = new LineNumberRenderable(renderer, { id: "code-lines", target: code, minWidth: 3, paddingRight: 1, fg: "#6b7280", bg: "#161b22", }) const scrollbox = new ScrollBoxRenderable(renderer, { id: "scrollbox", width: 70, height: 18, }) scrollbox.add(lineNumbers) renderer.root.add(scrollbox) ``` -------------------------------- ### Select Component API Source: https://opentui.com/docs/components/select This documentation outlines the API for the Select component, including its properties, events, and usage examples. ```APIDOC ## Select Component A vertical list for choosing from multiple options. Focus the select to enable keyboard input. ### Basic Usage #### Renderable API ```javascript import { SelectRenderable, SelectRenderableEvents, createCliRenderer } from "@opentui/core" const renderer = await createCliRenderer() const menu = new SelectRenderable(renderer, { id: "menu", width: 30, height: 8, options: [ { name: "New File", description: "Create a new file" }, { name: "Open File", description: "Open an existing file" }, { name: "Save", description: "Save current file" }, { name: "Exit", description: "Exit the application" }, ], }) menu.on(SelectRenderableEvents.ITEM_SELECTED, (index, option) => { console.log("Selected:", option.name) }) menu.focus() renderer.root.add(menu) ``` #### Construct API ```javascript import { Select, createCliRenderer } from "@opentui/core" const renderer = await createCliRenderer() const menu = Select({ width: 30, height: 8, options: [ { name: "Option 1", description: "First option" }, { name: "Option 2", description: "Second option" }, { name: "Option 3", description: "Third option" }, ], }) menu.focus() renderer.root.add(menu) ``` ### Keyboard Navigation When focused, the select responds to the following keys: | Key | Action | | --------------- | ----------------- | | `Up` / `k` | Move selection up | | `Down` / `j` | Move selection down | | `Shift+Up` / `Shift+Down` | Fast scroll (5 items) | | `Enter` | Select current item | ### Events #### Item Selected Fires when the user presses Enter on an option. ```javascript import { SelectRenderableEvents } from "@opentui/core" menu.on(SelectRenderableEvents.ITEM_SELECTED, (index: number, option: SelectOption) => { console.log(`Selected index ${index}: ${option.name}`) }) ``` #### Selection Changed Fires when the highlighted item changes. ```javascript menu.on(SelectRenderableEvents.SELECTION_CHANGED, (index: number, option: SelectOption) => { console.log(`Highlighted: ${option.name}`) // Update a preview pane, for example }) ``` ### Option Structure ```typescript interface SelectOption { name: string // Display text description: string // Displays below the name when showDescription is true value?: any // Optional value } ``` ### Styling ```javascript const styledMenu = new SelectRenderable(renderer, { id: "styled-menu", width: 40, height: 10, options: [...], backgroundColor: "#1a1a1a", selectedBackgroundColor: "#333366", selectedTextColor: "#FFFFFF", textColor: "#AAAAAA", descriptionColor: "#666666", }) ``` ### Properties | Property | Type | Default | Description | | ----------------------- | --------------------- | ------------- | ------------------------------- | | `width` | `number` | - | Component width | | `height` | `number` | - | Component height | | `options` | `SelectOption[]` | `[]` | Available options | | `selectedIndex` | `number` | `0` | Initially selected index | | `backgroundColor` | `string | RGBA` | `transparent` | Background color | | `textColor` | `string | RGBA` | `#FFFFFF` | Normal text color | | `focusedBackgroundColor`| `string | RGBA` | `#1a1a1a` | Background when focused | | `focusedTextColor` | `string | RGBA` | `#FFFFFF` | Text color when focused | | `selectedBackgroundColor`| `string | RGBA` | `#334455` | Selected item background | | `selectedTextColor` | `string | RGBA` | `#FFFF00` | Selected item text color | | `descriptionColor` | `string | RGBA` | `#888888` | Description text color | | `selectedDescriptionColor`| `string | RGBA` | `#CCCCCC` | Selected item description color | | `showDescription` | `boolean` | `true` | Show option descriptions | | `showScrollIndicator` | `boolean` | `false` | Show scroll position indicator | | `wrapSelection` | `boolean` | `false` | Wrap selection at list boundaries | | `itemSpacing` | `number` | `0` | Spacing between items | | `fastScrollStep` | `number` | `5` | Items to skip with Shift+Up/Down| ### Example: File Menu ```javascript import { Box, Select, createCliRenderer } from "@opentui/core" const renderer = await createCliRenderer() const fileMenu = Select({ width: 25, height: 12, options: [ { name: "New", description: "Create new file (Ctrl+N)" }, { name: "Open...", description: "Open file (Ctrl+O)" }, { name: "Save", description: "Save file (Ctrl+S)" }, { name: "Save As...", description: "Save with new name" }, { name: "---", description: "" }, // Separator (visual only) { name: "Exit", description: "Quit application (Ctrl+Q)" }, ], }) const menuPanel = Box( { borderStyle: "single", borderColor: "#666", }, fileMenu, ) fileMenu.focus() renderer.root.add(menuPanel) ``` ``` -------------------------------- ### Basic Audio Playback Source: https://opentui.com/docs/core-concepts/audio Demonstrates loading a sound file and playing it with basic options. Ensure the audio engine is created and started before playing sounds. Errors during playback are caught and logged. ```typescript import { Audio } from "@opentui/core" const audio = Audio.create({ autoStart: false }) audio.on("error", (error, context) => { console.error(`${context.action}: ${error.message}`) }) const sound = await audio.loadSoundFile("click.wav") if (sound != null && audio.start()) { audio.play(sound, { volume: 0.8, pan: 0, loop: false }) } audio.dispose() ``` -------------------------------- ### Acquire Shared Resource Source: https://opentui.com/docs/keymap/custom-addons Use acquireResource to share setup and teardown logic across multiple addon registrations on the same keymap. ```typescript acquireResource(symbol, setup); ``` -------------------------------- ### Basic Core Slot Registry and Plugin Registration Source: https://opentui.com/docs/plugins/core Demonstrates the basic usage of `createCoreSlotRegistry` and `registerCorePlugin`. This example sets up a registry for `BaseRenderable` nodes and registers a plugin that provides a 'statusbar' slot renderer. The `unregister` function can be called to remove the plugin. ```typescript import { BoxRenderable, createCliRenderer, createCoreSlotRegistry, registerCorePlugin, SlotRenderable, TextRenderable, } from "@opentui/core" type Slots = "statusbar" type SlotData = { label: string } const context = { appName: "core-app", version: "1.0.0" } const renderer = await createCliRenderer() const registry = createCoreSlotRegistry(renderer, context) const unregister = registerCorePlugin(registry, { id: "clock-plugin", order: 0, slots: { statusbar(_ctx, data) { return new TextRenderable(renderer, { id: "clock-status", content: `clock: ${data.label}`, }) }, }, }) const slot = new SlotRenderable(renderer, { id: "statusbar-slot", registry, name: "statusbar", data: { label: "ok" }, mode: "append", width: "100%", height: 3, flexDirection: "row", fallback: () => new TextRenderable(renderer, { id: "statusbar-fallback", content: "fallback", }), }) renderer.root.add(slot) // later slot.mode = "replace" slot.data = { label: "updated" } slot.refresh() slot.destroy() ``` -------------------------------- ### Available Core Constructs Source: https://opentui.com/docs/core-concepts/constructs Shows examples of various core constructs like Box, Text, Input, and others, illustrating their instantiation with different properties. These create VNodes, not actual Renderables. ```typescript import { ASCIIFont, Box, Code, FrameBuffer, Input, ScrollBox, Select, SyntaxStyle, TabSelect, Text, RGBA, } from "@opentui/core" // These create VNodes, not actual Renderables const syntaxStyle = SyntaxStyle.fromStyles({ default: { fg: RGBA.fromHex("#FFFFFF") }, }) const box = Box({ border: true }) const text = Text({ content: "Hello" }) const input = Input({ placeholder: "Type here..." }) const code = Code({ content: "const x = 1", filetype: "typescript", syntaxStyle }) const scrollBox = ScrollBox({ width: 40, height: 10 }) const frameBuffer = FrameBuffer({ width: 20, height: 10 }) const ascii = ASCIIFont({ text: "OPEN", font: "tiny" }) ``` -------------------------------- ### Create and Add a TextRenderable Source: https://opentui.com/docs/core-concepts/renderables Instantiate a TextRenderable with a renderer and options, then add it to the renderer's root. This is a basic example of creating a renderable element. ```typescript import { createCliRenderer, TextRenderable, BoxRenderable } from "@opentui/core" const renderer = await createCliRenderer() const greeting = new TextRenderable(renderer, { id: "greeting", content: "Hello, OpenTUI!", fg: "#00FF00", }) renderer.root.add(greeting) ``` -------------------------------- ### Basic Diff Rendering with Syntax Highlighting Source: https://opentui.com/docs/components/diff Demonstrates how to create and add a DiffRenderable component to the renderer. It includes setup for syntax styling and specifies the diff content, view type, filetype, and line number display. ```typescript import { DiffRenderable, SyntaxStyle, RGBA, createCliRenderer } from "@opentui/core" const renderer = await createCliRenderer() const syntaxStyle = SyntaxStyle.fromStyles({ default: { fg: RGBA.fromHex("#E6EDF3") }, string: { fg: RGBA.fromHex("#A5D6FF") }, keyword: { fg: RGBA.fromHex("#FF7B72"), bold: true }, }) const diff = new DiffRenderable(renderer, { id: "diff", width: "100%", height: 16, diff: `diff --git a/app.ts b/app.ts\nindex 1111111..2222222 100644\n--- a/app.ts\n+++ b/app.ts\n@@ -1,3 +1,3 @@\n-const a = 1\n+const a = 2\n`, view: "split", filetype: "typescript", syntaxStyle, showLineNumbers: true, }) renderer.root.add(diff) ``` -------------------------------- ### Solid Counter Example Source: https://opentui.com/docs/bindings/solid A basic counter component using Solid.js with OpenTUI. It utilizes `createSignal` for state management and `useKeyboard` for user input. The renderer can be destroyed by pressing ESC. ```typescript import { render, useKeyboard, useRenderer } from "@opentui/solid" import { createSignal } from "solid-js" const App = () => { const [count, setCount] = createSignal(0) const renderer = useRenderer() useKeyboard((key) => { if (key.name === "up") setCount((c) => c + 1) if (key.name === "down") setCount((c) => c - 1) if (key.name === "escape") renderer.destroy() }) return ( Count: {count()} Up/Down to change, ESC to close ) } render(App) ``` -------------------------------- ### Get Current Input Value Source: https://opentui.com/docs/components/input Retrieves the current text value of the input field. This property can be accessed at any time to get the latest content. ```typescript const currentValue = input.value ``` -------------------------------- ### Status Bar Example with Text and Box Components Source: https://opentui.com/docs/components/text Combines Text and Box components to create a status bar at the bottom of the screen, displaying file information and cursor position using rich text formatting. ```typescript import { Text, Box, t, bold, fg } from "@opentui/core" const statusBar = Box( { position: "absolute", bottom: 0, width: "100%", height: 1, backgroundColor: "#333333", flexDirection: "row", justifyContent: "space-between", paddingLeft: 1, paddingRight: 1, }, Text({ content: t`${bold("myfile.ts")} - ${fg("#888888")("TypeScript")}`, }), Text({ content: t`Ln ${fg("#00FF00")("42")}, Col ${fg("#00FF00")("15")}`, }), ) renderer.root.add(statusBar) ``` -------------------------------- ### Run OpenTUI 'Hello World' App Source: https://opentui.com/docs/getting-started Executes the TypeScript file using Bun to display the TUI. ```bash bun index.ts ``` -------------------------------- ### Basic Solid Keymap Integration Source: https://opentui.com/docs/keymap/solid Demonstrates setting up OpenTUI keymap bindings in a Solid application. It initializes the keymap, provides it via `KeymapProvider`, and registers commands and bindings using `useBindings`. ```typescript import { createCliRenderer } from "@opentui/core" import { createDefaultOpenTuiKeymap } from "@opentui/keymap/opentui" import { KeymapProvider, useBindings } from "@opentui/keymap/solid" import { render } from "@opentui/solid" const renderer = await createCliRenderer() const keymap = createDefaultOpenTuiKeymap(renderer) function App() { useBindings(() => ({ commands: [ { name: "quit", run() { renderer.destroy() }, }, ], bindings: [{ key: "q", cmd: "quit" }], })) return Press q to quit } await render( () => ( ), renderer, ) ``` -------------------------------- ### Basic Solid Slot Registry and Usage Source: https://opentui.com/docs/plugins/solid Demonstrates creating a Solid slot registry, registering a plugin with a statusbar slot, and rendering the slot with fallback content. ```typescript import { createCliRenderer } from "@opentui/core" import { createSolidSlotRegistry, Slot, render } from "@opentui/solid" type Slots = { statusbar: { user: string } } const context = { appName: "solid-app", version: "1.0.0" } const renderer = await createCliRenderer() const registry = createSolidSlotRegistry(renderer, context) const unregister = registry.register({ id: "clock-plugin", slots: { statusbar(ctx, props) { return {`${ctx.appName}:${props.user}`} }, }, }) const AppSlot = Slot const App = () => ( fallback-statusbar ) render(() => , renderer) ``` -------------------------------- ### Get Reactive Terminal Dimensions - OpenTUI Solid Source: https://opentui.com/docs/bindings/solid Use useTerminalDimensions to get reactive terminal dimensions as a Solid signal. Access the width and height properties from the returned signal. ```typescript import { useTerminalDimensions } from "@opentui/solid" const App = () => { const dimensions = useTerminalDimensions() return ( Terminal: {dimensions().width}x{dimensions().height} ) } ``` -------------------------------- ### Tabbed Interface Example Source: https://opentui.com/docs/components/tab-select Demonstrates creating a tabbed interface where selecting a tab changes the content displayed in an adjacent area. This example integrates TabSelect with Box and Text components. ```typescript import { Box, Text, TabSelect, createCliRenderer } from "@opentui/core" const renderer = await createCliRenderer() // Create content panels const panels = { home: Box({ padding: 1 }, Text({ content: "Home content here" })), files: Box({ padding: 1 }, Text({ content: "File browser here" })), settings: Box({ padding: 1 }, Text({ content: "Settings form here" })), } // Create the tabbed container const container = Box({ width: 60, height: 20, borderStyle: "rounded", }) const tabs = TabSelect({ width: 60, tabWidth: 20, options: [ { name: "Home", description: "Dashboard" }, { name: "Files", description: "Browse files" }, { name: "Settings", description: "Preferences" }, ], }) // Content area let currentPanel = panels.home const contentArea = Box({ flexGrow: 1, padding: 1, }) contentArea.add(currentPanel) // Handle tab changes tabs.on("itemSelected", (index, option) => { // Remove current panel if (currentPanel) { contentArea.remove(currentPanel.id) } // Add new panel based on selection switch (option.name) { case "Home": currentPanel = panels.home break case "Files": currentPanel = panels.files break case "Settings": currentPanel = panels.settings break } contentArea.add(currentPanel) }) container.add(tabs) container.add(contentArea) tabs.focus() renderer.root.add(container) ``` -------------------------------- ### Create and Use a Test Renderer Source: https://opentui.com/docs/core-concepts/testing Demonstrates how to create a test renderer, add components, render them once, capture the character frame output, and then destroy the renderer. ```typescript import { createTestRenderer } from "@opentui/core/testing" import { Text } from "@opentui/core" const { renderer, renderOnce, captureCharFrame } = await createTestRenderer({ width: 40, height: 10 }) renderer.root.add(Text({ content: "Hello" })) await renderOnce() console.log(captureCharFrame()) renderer.destroy() ``` -------------------------------- ### Create and Use Test Keymap Source: https://opentui.com/docs/keymap/custom-addons Set up a test keymap environment, register a custom addon, define commands and bindings, simulate key presses, and check for errors. ```typescript import { createTestKeymap } from "@opentui/keymap/testing" import { registerMyAddon } from "./my-addon" const { keymap, host, diagnostics, cleanup } = createTestKeymap({ defaultKeys: true }) registerMyAddon(keymap) keymap.registerLayer({ commands: [{ name: "save", run() {} }], bindings: [{ key: "x", cmd: "save" }], }) host.press("x") diagnostics.takeErrors() cleanup() ``` -------------------------------- ### Basic React Slot Registry and Usage Source: https://opentui.com/docs/plugins/react Demonstrates creating a React slot registry with defined slots and context, registering a plugin that renders UI into a statusbar slot, and using the Slot component in an App. ```typescript import { createCliRenderer } from "@opentui/core" import { createReactSlotRegistry, createRoot, Slot } from "@opentui/react" type Slots = { statusbar: { user: string } } const context = { appName: "react-app", version: "1.0.0" } const renderer = await createCliRenderer() const registry = createReactSlotRegistry(renderer, context) const unregister = registry.register({ id: "clock-plugin", slots: { statusbar(ctx, props) { return {`${ctx.appName}:${props.user}`} }, }, }) const AppSlot = Slot function App() { return ( fallback-statusbar ) } createRoot(renderer).render() ``` -------------------------------- ### Install Bun Runtime Support for External Plugins Source: https://opentui.com/docs/plugins/react Add this import once in your app entry to install Bun runtime support for external TS/TSX plugin modules. This ensures they resolve against the host runtime instances. ```typescript import "@opentui/react/runtime-plugin-support" ``` -------------------------------- ### Invert Entire Buffer Example Source: https://opentui.com/docs/reference/color-matrix Demonstrates how to invert all colors in the FrameBuffer using `colorMatrixUniform` with the predefined `INVERT_MATRIX`. ```typescript import { INVERT_MATRIX, TargetChannel } from "@opentui/core" frameBuffer.colorMatrixUniform(INVERT_MATRIX, 1.0, TargetChannel.Both) ``` -------------------------------- ### Resolve Slot Entries and Renderers Source: https://opentui.com/docs/plugins/slots Use `resolveEntries` to get plugin IDs and their renderers, or `resolve` for just the renderer callbacks. ```javascript const entries = registry.resolveEntries("statusbar") // Array<{ id: string, renderer: (ctx, props) => TNode }> const slotRenderers = registry.resolve("statusbar") // Array<(ctx, props) => TNode> ``` -------------------------------- ### Create a 'Hello World' OpenTUI App Source: https://opentui.com/docs/getting-started Renders 'Hello, OpenTUI!' in green text to the terminal. Press Ctrl+C to exit. ```typescript import { createCliRenderer, Text } from "@opentui/core" const renderer = await createCliRenderer({ exitOnCtrlC: true, }) renderer.root.add( Text({ content: "Hello, OpenTUI!", fg: "#00FF00", }), ) ``` -------------------------------- ### Sequence Pattern Runtime Predicate Source: https://opentui.com/docs/keymap/core Example of a `match` function within a sequence pattern that returns a captured value or undefined. ```javascript match: runtimeEventPredicate ``` -------------------------------- ### Vertical Slider Source: https://opentui.com/docs/components/slider Renders a vertical slider. This example demonstrates setting the orientation to 'vertical' and adjusting dimensions for a vertical layout. ```typescript const slider = new SliderRenderable(renderer, { orientation: "vertical", width: 2, height: 10, min: 0, max: 1, value: 0.5, }) ``` -------------------------------- ### Configure Bun Preload Script Source: https://opentui.com/docs/bindings/solid Add the OpenTUI Solid preload script to your `bunfig.toml` for runtime integration. ```toml preload = ["@opentui/solid/preload"] ``` -------------------------------- ### Automatic Render Mode Source: https://opentui.com/docs/core-concepts/renderer The default render mode where the renderer re-renders only when the component tree changes. No explicit start call is needed. ```typescript const renderer = await createCliRenderer() renderer.root.add(Text({ content: "Static content" })) // Triggers render ``` -------------------------------- ### Constructing Keymap Engine with Custom Host Source: https://opentui.com/docs/keymap/hosts Implement the `KeymapHost` interface yourself and construct the engine directly when neither built-in host fits your runtime. Ensure custom hosts provide conservative metadata. ```typescript import { Keymap, type KeymapHost } from "@opentui/keymap" const keymap = new Keymap(host as KeymapHost) ``` -------------------------------- ### ScrollBox scrollTo Method Examples Source: https://opentui.com/docs/components/scrollbox Illustrates the `scrollTo` method for programmatically scrolling to an absolute position, either the top/start or a specific coordinate. ```typescript // Scroll to top scrollbox.scrollTo(0) // Scroll to specific position scrollbox.scrollTo({ x: 0, y: 100 }) ``` -------------------------------- ### Styling Components with Direct Props Source: https://opentui.com/docs/bindings/react Demonstrates styling OpenTUI components using direct props like `backgroundColor` and `padding`. ```jsx // Direct props Hello ``` -------------------------------- ### Get Command Bindings by Name Source: https://opentui.com/docs/keymap/core Use getCommandBindings to retrieve bindings for specific commands when the UI already knows the commands it needs to display. ```javascript const bindingsByCommand = keymap.getCommandBindings({ visibility: "registered", commands: ["file.save", "app.quit"], }) const saveBindings = bindingsByCommand.get("file.save") ?? [] ``` -------------------------------- ### Basic Markdown Rendering with Custom Styles Source: https://opentui.com/docs/components/markdown Demonstrates how to create and render markdown content with custom syntax styling using MarkdownRenderable. Requires creating a renderer and defining a SyntaxStyle object. ```typescript import { MarkdownRenderable, SyntaxStyle, RGBA, createCliRenderer } from "@opentui/core" const renderer = await createCliRenderer() const syntaxStyle = SyntaxStyle.fromStyles({ "markup.heading.1": { fg: RGBA.fromHex("#58A6FF"), bold: true }, "markup.list": { fg: RGBA.fromHex("#FF7B72") }, "markup.raw": { fg: RGBA.fromHex("#A5D6FF") }, default: { fg: RGBA.fromHex("#E6EDF3") }, }) const markdown = new MarkdownRenderable(renderer, { id: "readme", width: 60, content: "# Hello\n\n- One\n- Two\n\n```ts\nconst x = 1\n```", syntaxStyle, }) renderer.root.add(markdown) ``` -------------------------------- ### Registering Command Bindings Source: https://opentui.com/docs/keymap/core Illustrates using the `commandBindings` helper to create a `Binding[]` array for `registerLayer()`, providing configuration sugar for commands. ```javascript commandBindings(map) ``` -------------------------------- ### Programmatic Control of TabSelect Source: https://opentui.com/docs/components/tab-select Shows how to control the TabSelect component programmatically. You can get the current selection, set it directly, or update the available tabs. ```typescript // Get current tab index const currentIndex = tabs.getSelectedIndex() // Set tab programmatically tabs.setSelectedIndex(1) // Update tabs dynamically tabs.setOptions([ { name: "New Tab 1", description: "Updated" }, { name: "New Tab 2", description: "Also updated" }, ]) ``` -------------------------------- ### Basic Textarea Rendering Source: https://opentui.com/docs/components/textarea Demonstrates how to create and render a basic textarea with custom styling and a placeholder. Ensure the renderer is initialized before creating the textarea. ```typescript import { TextareaRenderable, createCliRenderer } from "@opentui/core" const renderer = await createCliRenderer() const textarea = new TextareaRenderable(renderer, { id: "notes", width: 50, height: 6, placeholder: "Type notes here...", backgroundColor: "#1a1a1a", focusedBackgroundColor: "#222222", textColor: "#FFFFFF", cursorColor: "#00FF88", }) renderer.root.add(textarea) textarea.focus() ``` -------------------------------- ### Configure Keymap Runtime Modules Source: https://opentui.com/docs/plugins/solid For keymap-aware Solid plugins, import the runtime modules from `@opentui/keymap/runtime-modules` and pass them to `ensureRuntimePluginSupport`. ```typescript import { runtimeModules as keymapRuntimeModules } from "@opentui/keymap/runtime-modules" import { ensureRuntimePluginSupport } from "@opentui/solid/runtime-plugin-support/configure" ensureRuntimePluginSupport({ additional: keymapRuntimeModules, }) ``` -------------------------------- ### Create and Render Input (Construct API) Source: https://opentui.com/docs/components/input Shows how to create and render an Input component using the construct API. This method is a more concise way to instantiate the input element. ```typescript import { Input, createCliRenderer } from "@opentui/core" const renderer = await createCliRenderer() const input = Input({ placeholder: "Enter your name...", width: 25, }) input.focus() renderer.root.add(input) ``` -------------------------------- ### Get Reactive Terminal Dimensions with useTerminalDimensions Hook Source: https://opentui.com/docs/bindings/react Access the current terminal dimensions reactively within your React components using the useTerminalDimensions hook. ```jsx import { useTerminalDimensions } from "@opentui/react" function App() { const { width, height } = useTerminalDimensions() return ( Terminal: {width}x{height} ) } ``` -------------------------------- ### Create and Render Input (Renderable API) Source: https://opentui.com/docs/components/input Demonstrates how to create and render an Input component using the Renderable API. It sets up an input field, listens for change events, and focuses the input. ```typescript import { InputRenderable, InputRenderableEvents, createCliRenderer } from "@opentui/core" const renderer = await createCliRenderer() const input = new InputRenderable(renderer, { id: "name-input", width: 25, placeholder: "Enter your name...", }) input.on(InputRenderableEvents.CHANGE, (value) => { console.log("Input value:", value) }) input.focus() renderer.root.add(input) ```