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:

KeyAction
Up / kMove selection up
Down / jMove selection down
Shift+Up / Shift+DownFast scroll (5 items)
EnterSelect 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

PropertyTypeDefaultDescription
widthnumber-Component width
heightnumber-Component height
optionsSelectOption[][]Available options
selectedIndexnumber0Initially selected index
backgroundColorstring | RGBAtransparentBackground color
textColorstring | RGBA#FFFFFFNormal text color
focusedBackgroundColorstring | RGBA#1a1a1aBackground when focused
focusedTextColorstring | RGBA#FFFFFFText color when focused
selectedBackgroundColorstring | RGBA#334455Selected item background
selectedTextColorstring | RGBA#FFFF00Selected item text color
descriptionColorstring | RGBA#888888Description text color
selectedDescriptionColorstring | RGBA#CCCCCCSelected item description color
showDescriptionbooleantrueShow option descriptions
showScrollIndicatorbooleanfalseShow scroll position indicator
wrapSelectionbooleanfalseWrap selection at list boundaries
itemSpacingnumber0Spacing between items
fastScrollStepnumber5Items 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