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
An empty input displays its placeholder:
Name
Enter your nameFocus states
The input uses its focused colors while it has focus:
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 LovelaceEvents
Input event
Emitted after these operations:
Typing, paste, or
insertText()inserts text.A delete key, a delete method such as
deleteCharBackward(),undo(), orredo()runs.You assign a different
value.
The listener receives the current value. Other buffer methods, such as setText(), insertChar(), deleteSelection(),
and deleteRange(), do not emit it:
import { InputRenderableEvents } from "@opentui/core"
input.on(InputRenderableEvents.INPUT, (value: string) => {
console.log("Current value:", value)
})Change event
Emitted 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)
})The constructor and each focus() call set 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 submit() succeeds. Return, keypad Enter, and linefeed call submit(). If the current UTF-16 code-unit length
is less than minLength, submit() fails and the input emits no event:
input.on(InputRenderableEvents.ENTER, (value: string) => {
console.log("Submitted value:", value)
})Getting the current value
const currentValue = input.valueSetting 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, with newlines removed |
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" | Positioning mode |
Example: login form
Input has no password-masking mode. This example shows the password value as normal terminal text. Do not use this
pattern for real secrets.
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.