Input
Text input field with cursor, placeholder text, and focus states. Focus the input to receive keyboard input.
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)
Construct api
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)
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",
})
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 when the input loses focus (blur) or when you press Enter, but only if the value changed since focus:
input.on(InputRenderableEvents.CHANGE, (value: string) => {
console.log("Value committed:", value)
})
Enter event
Emitted when an Enter/Return submit succeeds. No event is emitted 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
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)
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()
}
})