Skip to content

SelectList

Keyboard-navigable single-select list with built-in j/k, arrow keys, and Enter to confirm.

Import

tsx
import { SelectList } from "silvery"

Usage

tsx
const items = [
  { label: "Apple", value: "apple" },
  { label: "Banana", value: "banana" },
  { label: "Cherry", value: "cherry", disabled: true },
]

<SelectList items={items} onSelect={(opt) => console.log(opt.value)} />

Props

PropTypeDefaultDescription
itemsSelectOption[]requiredList of options to display
highlightedIndexnumberControlled: current highlighted index
onHighlight(index: number) => voidCalled when highlight changes
onSelect(option: SelectOption, index: number) => voidCalled when Enter is pressed on an item
initialIndexnumberfirst enabledStarting index for uncontrolled mode
maxVisiblenumberMax visible items before scrolling
isActivebooleantrueWhether this list captures keyboard input
indicatorstring"▸ "Selection indicator prefix. Non-highlighted items get equal-width spaces. Pass "" to hide.

SelectOption

ts
interface SelectOption {
  label: string
  value: string
  disabled?: boolean
}

Keyboard Shortcuts

KeyAction
j / DownMove highlight down
k / UpMove highlight up
EnterSelect the highlighted item
Ctrl+AJump to first enabled item
Ctrl+EJump to last enabled item

Disabled items are automatically skipped during navigation.

Examples

Uncontrolled (Internal State)

tsx
<SelectList
  items={[
    { label: "Small", value: "sm" },
    { label: "Medium", value: "md" },
    { label: "Large", value: "lg" },
  ]}
  onSelect={(opt) => setSize(opt.value)}
/>

Controlled (External State)

tsx
const [index, setIndex] = useState(0)

<SelectList
  items={options}
  highlightedIndex={index}
  onHighlight={setIndex}
  onSelect={(opt) => handleSelect(opt)}
/>

Scrollable with Max Visible

tsx
<SelectList items={longList} maxVisible={5} onSelect={(opt) => console.log(opt.value)} />

The visible window auto-centers around the highlighted item.

Released under the MIT License.