Select
A vertical list for choosing from multiple options. Focus the select to enable keyboard input.
Basic usage
Renderable API
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
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 these 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:
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:
menu.on(SelectRenderableEvents.SELECTION_CHANGED, (index: number, option: SelectOption) => {
console.log(`Highlighted: ${option.name}`)
// Update a preview pane, for example
})
Option structure
interface SelectOption {
name: string // Display text
description: string // Displays below the name when showDescription is true
value?: any // Optional value
}
Styling
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 |
showSelectionIndicator |
boolean |
true |
Show the selection marker and gutter |
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
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)
Programmatic control
// Get current selection index
const currentIndex = menu.getSelectedIndex()
// Get currently selected option
const option = menu.getSelectedOption()
// Set selection programmatically
menu.setSelectedIndex(2)
// Navigate programmatically
menu.moveUp() // Move up one item
menu.moveDown() // Move down one item
menu.moveUp(3) // Move up multiple items
menu.selectCurrent() // Trigger selection of current item
// Update options dynamically
menu.options = [
{ name: "New Option 1", description: "First" },
{ name: "New Option 2", description: "Second" },
]
// Toggle display options
menu.showDescription = false
menu.showScrollIndicator = true
menu.showSelectionIndicator = false
menu.wrapSelection = true