Skip to content

<Select>

A scrollable single-choice list, mapping to OpenTUI's select renderable. v-model binds the highlighted index; select fires when the user commits a choice with Enter.

vue
<script setup lang="ts">
import { Select, ref } from 'vue-termui'
import type { SelectOption } from 'vue-termui'

const options: SelectOption[] = [
  { name: 'Vue', description: 'The progressive framework' },
  { name: 'OpenTUI', description: 'Native terminal renderer' },
  { name: 'vue-termui', description: 'Vue 3 in the terminal' },
]

const index = ref(0)

function onPick(option: SelectOption | null, i: number) {
  // ...
}
</script>

<template>
  <Select v-model="index" :options="options" showDescription focus @select="onPick" />
</template>

While focused, / move the highlight and Enter commits. Pass focus to focus on mount.

Props

PropTypeDefaultDescription
optionsSelectOption[][]The choices to display
modelValuenumber0Index of the highlighted option (v-model)
focusbooleanfalseFocus the list as soon as it mounts
showDescriptionbooleanShow each option's description
wrapSelectionbooleanWrap around when navigating past the ends

SelectOption

ts
interface SelectOption {
  name: string // label shown for the option
  description?: string // secondary text (shown when showDescription)
  value?: unknown // arbitrary value you associate with the option
}

Events

EventPayloadFires when
update:modelValuenumberThe highlight moves (v-model)
select(option: SelectOption | null, index: number)Enter commits a choice

Reading the choice

v-model tracks the highlighted option as the user navigates; @select tells you what they committed. Use whichever fits:

vue
<script setup lang="ts">
import { Select, ref, computed } from 'vue-termui'
import type { SelectOption } from 'vue-termui'

const options: SelectOption[] = [
  { name: 'Small', value: 'sm' },
  { name: 'Medium', value: 'md' },
  { name: 'Large', value: 'lg' },
]

const index = ref(0)
const highlighted = computed(() => options[index.value])
const chosen = ref<SelectOption | null>(null)
</script>

<template>
  <Select v-model="index" :options="options" focus @select="(o) => (chosen = o)" />
  <Text>Highlighted: {{ highlighted?.name }}</Text>
  <Text v-if="chosen">Chosen: {{ chosen.name }} ({{ chosen.value }})</Text>
</template>

Released under the MIT License.