Ink Web

Select Input

A terminal select input component with keyboard navigation. Navigate with arrow keys or j/k, press Enter to select.

Terminal

Installation

npx shadcn@latest add https://raw.githubusercontent.com/cjroth/ink-web/main/packages/ink-ui/registry/select-input.json
npx shadcn@latest add https://raw.githubusercontent.com/cjroth/ink-web/main/packages/ink-ui/registry/select-input.json
pnpm dlx shadcn@latest add https://raw.githubusercontent.com/cjroth/ink-web/main/packages/ink-ui/registry/select-input.json
bunx shadcn@latest add https://raw.githubusercontent.com/cjroth/ink-web/main/packages/ink-ui/registry/select-input.json

Usage

app/page.tsx
"use client";

import dynamic from "next/dynamic";

const Terminal = dynamic(() => import("./terminal"), {
  ssr: false,
});

export default function Home() {
  return <Terminal />;
}
app/terminal.tsx
"use client";

import { Box, Text } from "ink";
import { InkXterm } from "ink-web";
import { SelectInput } from '@/components/ui/select-input'
import "ink-web/css";
import "xterm/css/xterm.css";

const items = [
  { label: 'First', value: 'first' },
  { label: 'Second', value: 'second' },
  { label: 'Third', value: 'third' },
];

export default function Terminal() {
  return (
    <InkXterm focus>
      <Box flexDirection="column">
        <Text>Select an option:</Text>
        <SelectInput
          items={items}
          onSelect={(item) => console.log('Selected:', item.value)}
        />
      </Box>
    </InkXterm>
  )
}

Props

PropTypeDefaultDescription
itemsSelectInputItem<V>[][]Items to display. Each item must have label and value, optionally key
isFocusedbooleantrueWhether the component listens to user input
initialIndexnumber0Index of initially-selected item
limitnumber-Number of items to display at once (enables scrolling)
indicatorComponentFC<IndicatorProps>-Custom indicator component
itemComponentFC<ItemProps>-Custom item component
onSelect(item) => void-Called when user selects an item (Enter key)
onHighlight(item) => void-Called when user highlights an item (navigation)

Examples

Basic Select

const items = [
  { label: 'Apple', value: 'apple' },
  { label: 'Banana', value: 'banana' },
  { label: 'Cherry', value: 'cherry' },
];

<SelectInput items={items} onSelect={handleSelect} />

With Limit (Scrollable)

<SelectInput
  items={items}
  limit={5}
  onSelect={handleSelect}
/>

With Initial Selection

<SelectInput
  items={items}
  initialIndex={2}
  onSelect={handleSelect}
/>

Multiple Select Inputs

Use isFocused to route input between multiple components:

const [activeInput, setActiveInput] = useState<'first' | 'second'>('first');

<SelectInput
  items={firstItems}
  isFocused={activeInput === 'first'}
  onSelect={(item) => {
    handleFirst(item);
    setActiveInput('second');
  }}
/>
<SelectInput
  items={secondItems}
  isFocused={activeInput === 'second'}
  onSelect={handleSecond}
/>

Keyboard Navigation

  • ↑/k - Move selection up
  • ↓/j - Move selection down
  • Enter - Select highlighted item
  • 1-9 - Instantly select item by number