Components
SelectInput
A single-selection list with radio indicators and groups
A single-selection list with radio indicators, keyboard navigation, group headers, and a submitted state.
SelectInput
Run demo
bunx @gridland/demo select-inputcurl -fsSL https://raw.githubusercontent.com/thoughtfulllc/gridland/main/scripts/run-demo.sh | bash -s select-inputInstallation
bunx shadcn@latest add @gridland/select-inputUsage
import { SelectInput } from "@/components/ui/select-input"
import { useKeyboard } from "@gridland/utils"<SelectInput
items={[
{ label: "TypeScript", value: "ts" },
{ label: "JavaScript", value: "js" },
{ label: "Python", value: "py" },
]}
title="Select a language"
useKeyboard={useKeyboard}
onSubmit={(value) => console.log("Selected:", value)}
/>Examples
Controlled
Use value and onChange to control the selection externally.
const [value, setValue] = useState<string>("ts")
<SelectInput
items={[
{ label: "TypeScript", value: "ts" },
{ label: "JavaScript", value: "js" },
{ label: "Python", value: "py" },
]}
value={value}
onChange={setValue}
title="Select a language"
useKeyboard={useKeyboard}
onSubmit={(value) => console.log("Selected:", value)}
/>Default Value
Set the initially selected item in uncontrolled mode.
<SelectInput
items={[
{ label: "TypeScript", value: "ts" },
{ label: "JavaScript", value: "js" },
{ label: "Python", value: "py" },
]}
defaultValue="ts"
title="Select a language"
useKeyboard={useKeyboard}
onSubmit={(value) => console.log("Selected:", value)}
/>Groups
Use the group field on items to render group headers with separators.
<SelectInput
items={[
{ label: "TypeScript", value: "ts", group: "Languages" },
{ label: "Python", value: "py", group: "Languages" },
{ label: "React", value: "react", group: "Frameworks" },
{ label: "Vue", value: "vue", group: "Frameworks" },
]}
title="Select a tool"
useKeyboard={useKeyboard}
onSubmit={(value) => console.log(value)}
/>Disabled Items
Disable individual items so they cannot be selected.
<SelectInput
items={[
{ label: "TypeScript", value: "ts" },
{ label: "JavaScript", value: "js", disabled: true },
{ label: "Python", value: "py" },
]}
title="Select a language"
useKeyboard={useKeyboard}
onSubmit={(value) => console.log(value)}
/>Required
Show a required indicator and use invalid to display an error state.
<SelectInput
items={[
{ label: "TypeScript", value: "ts" },
{ label: "JavaScript", value: "js" },
{ label: "Python", value: "py" },
]}
required
invalid={!hasSelected}
title="Select a language"
useKeyboard={useKeyboard}
onSubmit={(value) => console.log(value)}
/>Disabled
Disable the entire component. Navigation and submission are blocked.
<SelectInput
items={[
{ label: "TypeScript", value: "ts" },
{ label: "JavaScript", value: "js" },
]}
disabled
title="Select a language"
useKeyboard={useKeyboard}
/>Placeholder
Show placeholder text when the items list is empty.
<SelectInput
items={[]}
placeholder="No options available"
title="Select a language"
useKeyboard={useKeyboard}
/>Controls
- ↑/↓ or j/k: Navigate and select
- Enter: Submit selected item
API Reference
SelectInput
| Prop | Type | Default | Description |
|---|---|---|---|
items | SelectInputItem<V>[] | [] | Array of selectable items |
defaultValue | V | - | Initially selected value (uncontrolled) |
value | V | - | Selected value (controlled) |
onChange | (value: V) => void | - | Called when selection changes |
disabled | boolean | false | Disable the entire component |
invalid | boolean | false | Show error state with destructive styling |
required | boolean | false | Show required indicator (*) next to title |
placeholder | string | - | Placeholder text when items list is empty |
title | string | "Select" | Title shown next to the diamond indicator |
submittedStatus | string | "submitted" | Status text shown after submit |
limit | number | 12 | Max visible rows before scrolling |
highlightColor | string | theme.primary | Color of the highlighted item |
onSubmit | (value: V) => void | - | Called on Enter with the selected value |
useKeyboard | (handler: (event: any) => void) => void | - | Keyboard hook from @opentui/react |
SelectInputItem
| Field | Type | Description |
|---|---|---|
label | string | Display text |
value | V | Item value |
key | string? | Optional React key |
group | string? | Group header label |
disabled | boolean? | Disable individual item |