API reference for the Select component
A single-select list.
Works in controlled or uncontrolled mode. Pass value and onChange to own the selection state yourself; omit them to let the component manage it internally. Use onHighlight to observe cursor movement without taking ownership of state.
By default, onChange fires when Enter is pressed. Set immediate to fire onChange on every highlight change instead — useful for previewing the selected option as you browse. Use onSubmit to handle the final confirmation separately.
The direction prop controls both layout and navigation keys. Vertical uses j/k/Up/Down, horizontal uses h/l/Left/Right.
import { Select } from 'giggles/ui';
const languages = [
{ label: 'TypeScript', value: 'ts' },
{ label: 'Rust', value: 'rs' },
{ label: 'Go', value: 'go' },
];
// uncontrolled — no useState needed
function LanguagePicker() {
return <Select options={languages} onSubmit={(lang) => console.log(lang)} />;
}
// controlled — caller owns selection state
function ControlledLanguagePicker() {
const [lang, setLang] = useState('ts');
return <Select options={languages} value={lang} onChange={setLang} />;
}Option values must be unique. Duplicate values will throw a GigglesError. Use primitive types (strings, numbers) for option values — object references are compared with ===.
Select
Prop
Type
Keybindings
| Key | Action |
|---|---|
j / ↓ | Highlight next (vertical) |
k / ↑ | Highlight previous (vertical) |
l / → | Highlight next (horizontal) |
h / ← | Highlight previous (horizontal) |
Enter | Confirm selection |
Tab / Shift+Tab | Move to next/previous component |
SelectOption
Prop
Type
SelectRenderProps
Prop
Type
Immediate mode with preview
function FileTypePicker() {
const [type, setType] = useState('json');
const [preview, setPreview] = useState('');
return (
<Box flexDirection="row" gap={2}>
<Select
options={fileTypes}
value={type}
onChange={setType}
onHighlight={(v) => setPreview(loadPreview(v))}
immediate
/>
<Text>{preview}</Text>
</Box>
);
}Custom render
<Select
options={options}
value={selected}
onChange={setSelected}
render={({ option, highlighted, selected }) => (
<Text color={highlighted ? 'cyan' : 'white'} bold={selected}>
{highlighted ? '→' : ' '} {option.label}
</Text>
)}
/>