Select

一个用于从多个选项中进行选择的垂直列表。聚焦 Select 以启用键盘输入。

基本用法

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)

键盘导航

当获得焦点时,Select 响应以下按键:

按键操作
Up / k将选择向上移动
Down / j将选择向下移动
Shift+Up / Shift+Down快速滚动(5 个选项)
Enter选择当前选项

事件

选项选中

当用户在某个选项上按下 Enter 时触发:

import { SelectRenderableEvents } from "@opentui/core"

menu.on(SelectRenderableEvents.ITEM_SELECTED, (index: number, option: SelectOption) => {
  console.log(`Selected index ${index}: ${option.name}`)
})

选择变更

当高亮选项发生变化时触发:

menu.on(SelectRenderableEvents.SELECTION_CHANGED, (index: number, option: SelectOption) => {
  console.log(`Highlighted: ${option.name}`)
  // Update a preview pane, for example
})

选项结构

interface SelectOption {
  name: string // Display text
  description: string // Displays below the name when showDescription is true
  value?: any // Optional value
}

样式设置

const styledMenu = new SelectRenderable(renderer, {
  id: "styled-menu",
  width: 40,
  height: 10,
  options: [...],
  backgroundColor: "#1a1a1a",
  selectedBackgroundColor: "#333366",
  selectedTextColor: "#FFFFFF",
  textColor: "#AAAAAA",
  descriptionColor: "#666666",
})

属性

属性类型默认值描述
widthnumber-组件宽度
heightnumber-组件高度
optionsSelectOption[][]可用选项
selectedIndexnumber0初始选中的索引
backgroundColorstring | RGBAtransparent背景颜色
textColorstring | RGBA#FFFFFF普通文本颜色
focusedBackgroundColorstring | RGBA#1a1a1a聚焦时的背景颜色
focusedTextColorstring | RGBA#FFFFFF聚焦时的文本颜色
selectedBackgroundColorstring | RGBA#334455选中项的背景颜色
selectedTextColorstring | RGBA#FFFF00选中项的文本颜色
descriptionColorstring | RGBA#888888描述文本颜色
selectedDescriptionColorstring | RGBA#CCCCCC选中项的描述颜色
showDescriptionbooleantrue显示选项描述
showScrollIndicatorbooleanfalse显示滚动位置指示器
wrapSelectionbooleanfalse在列表边界处循环选择
itemSpacingnumber0选项之间的间距
fastScrollStepnumber5使用 Shift+Up/Down 时跳过的选项数

示例:文件菜单

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)

编程控制

// 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