docs/components/input.mdx
docs/components/input.mdxBrowse 89 files
6,524 bytes
Token encoding: o200k_base
Snapshot ac753b4
title: Input description: Accept one line of text with cursor, focus, and submit events skill: entry: true intents: [input, form, editing, focus]
Input
Input edits one line of text and supplies a cursor, placeholder, and focus styles. Use Textarea for multi-line editing.
Focus the input to receive keyboard input.
Availability
| Field | Availability |
|---|---|
| Package | @opentui/core |
| Core renderable | InputRenderable |
| React | <input> (automatic) |
| Solid | <input> (automatic) |
| Status | Built in |
Basic usage
Renderable API
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)
An empty input displays its placeholder:
Name
Enter your name
Focus states
The input changes appearance when focused:
const input = new InputRenderable(renderer, {
id: "styled-input",
width: 30,
placeholder: "Type here...",
backgroundColor: "#1a1a1a",
focusedBackgroundColor: "#2a2a2a",
textColor: "#FFFFFF",
cursorColor: "#00FF00",
})
After focusing the input and typing a name:
Name
Ada Lovelace
Events
Input event
Emitted after text insertion and deletion operations, and when assigning a different value. The listener receives the current value:
import { InputRenderableEvents } from "@opentui/core"
input.on(InputRenderableEvents.INPUT, (value: string) => {
console.log("Current value:", value)
})
Change event
Fires on blur or after a successful submit() when the value differs from the last commit baseline:
input.on(InputRenderableEvents.CHANGE, (value: string) => {
console.log("Value committed:", value)
})
Each focus() call sets the baseline. Each emitted CHANGE event updates it. Thus, blur does not emit another event if
the value did not change after a successful commit.
Enter event
Emitted when an Enter/Return submit succeeds. The input emits no event when the current UTF-16 code-unit length is less
than minLength:
input.on(InputRenderableEvents.ENTER, (value: string) => {
console.log("Submitted value:", value)
})
Getting the current value
const currentValue = input.value
Setting the value
input.value = "New value"
Properties
| Property | Type | Default | Description |
|---|---|---|---|
width | number, "auto", or percentage string | "auto" | Input field width |
value | string | "" | Initial text value |
placeholder | string | "" | Placeholder text when empty |
minLength | number | 0 | Minimum UTF-16 code-unit length required for submit |
maxLength | number | 1000 | Maximum UTF-16 code-unit length |
backgroundColor | string | RGBA | "transparent" | Background when unfocused |
focusedBackgroundColor | string | RGBA | backgroundColor, else "transparent" | Background when focused |
textColor | string | RGBA | "#FFFFFF" | Text color |
cursorColor | string | RGBA | "#FFFFFF" | Cursor color |
position | "relative" | "absolute" | "relative" | Effective positioning mode |
Example: login form
Input has no password-masking mode. This demonstration displays the password value as normal terminal text. Do not
use this pattern for real secrets.
import { BoxRenderable, InputRenderable, TextRenderable, createCliRenderer } from "@opentui/core"
const renderer = await createCliRenderer()
const form = new BoxRenderable(renderer, {
width: 40,
borderStyle: "rounded",
title: "Login",
padding: 1,
gap: 1,
})
const usernameInput = new InputRenderable(renderer, {
id: "username-input",
placeholder: "Enter username",
width: 20,
backgroundColor: "#222",
focusedBackgroundColor: "#333",
})
const passwordInput = new InputRenderable(renderer, {
id: "password-input",
placeholder: "Enter password",
width: 20,
backgroundColor: "#222",
focusedBackgroundColor: "#333",
})
form.add(new TextRenderable(renderer, { content: "Username:", fg: "#888888" }))
form.add(usernameInput)
form.add(new TextRenderable(renderer, { content: "Password:", fg: "#888888" }))
form.add(passwordInput)
renderer.root.add(form)
usernameInput.focus()
Tab navigation
Add tab navigation between inputs:
const inputs = [usernameInput, passwordInput]
let focusIndex = 0
renderer.keyInput.on("keypress", (key) => {
if (key.name === "tab") {
focusIndex = (focusIndex + 1) % inputs.length
inputs[focusIndex].focus()
}
})
Related concepts
Read Interaction, focus, and selection for focus and event behavior. Read Text and terminal cells before enforcing limits that depend on code points, graphemes, or display cells.
Referenced from SKILL.md
Source excerpt starting at line 82.SKILL.mdView in source ↗82| `text`, `styling`, `content`, `selection` | `docs/components/text.mdx` |83| `input`, `form`, `editing`, `focus` | `docs/components/input.mdx` |84| `image`, `image-renderable`, `image-display`, `kitty`, `sixel` | `docs/components/image.mdx` |
Source excerpt starting at line 120.120- `docs/components/text.mdx`121- `docs/components/input.mdx`122- `docs/components/image.mdx`