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 |
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.wrapSelection = true