Select
One choice from a list, in a popover
New workspace
Region: Europe — West (Ireland) · Machine: none
Installation
npx shadcn@latest add @sudokw/primitives-selectimport { Select } from "@gpuixui/primitives";Usage
import { useState } from "react";
import { Label, Select } from "@gpuixui/primitives";
const regions = [
{
label: "Europe",
options: [
{ value: "eu-west", label: "Europe — West (Ireland)" },
{ value: "eu-central", label: "Europe — Central (Frankfurt)" },
],
},
{
label: "Americas",
options: [
{ value: "us-east", label: "United States — East" },
{ value: "us-west", label: "United States — West" },
],
},
];
export const DeployTarget = () => {
const [region, setRegion] = useState("eu-west");
return (
<>
<Label>Region</Label>
<Select
label="Region"
onValueChange={setRegion}
options={regions}
value={region}
/>
</>
);
};Composition
Select
├── trigger (built in)
├── content
│ └── item
└── group / label / separatorAPI reference
| Prop | Type | Default | Consequence |
|---|---|---|---|
options | ReadonlyArray<SelectOption | SelectOptionGroup> | required | the rows, or named groups of them, in render order |
value | string | none | controlled selection |
defaultValue | string | none | initial selection when uncontrolled |
selectedValue | string | value ?? defaultValue | the choice a closed trigger announces — a parent's mirror of an uncontrolled select's value |
open | boolean | none | controlled open state |
defaultOpen | boolean | false | the list's initial state while open is omitted |
onOpenChange | (open: boolean) => void | none | the open state the runtime reported |
onValueChange | (value: string) => void | none | the committed value |
onChange | (value: string) => void | none | deprecated alias; onValueChange wins when both are passed |
placeholder | string | none | the trigger's text before a choice |
disabled | boolean | false | refuses to open |
invalid | boolean | false | destructive edge on the trigger |
size | "sm" | "md" | "lg" | "md" | height and padding from density |
fullWidth | boolean | false | trigger and list fill the parent |
side | FloatingSide | the runtime's choice | which side the list opens on |
align | FloatingAlign | GPUix's default | how the list is aligned against the trigger |
label | string | none | the accessible name — put a visible Label beside it |
description | string | none | announced help after the name; a blank one publishes nothing |
ref / aria-id / onLayout | host props | none | the trigger is the addressed element — the one a form focuses, an automation host names and a layout measures |
style | StyleDesc | none | merged last on the wrapper, which paints only its width |
triggerStyle | StateStyle<SelectTriggerState> | none | resolved against the trigger's live state, merged last |
itemStyle | StateStyle<SelectItemState> | none | resolved per row against that row's state, merged last |
testId | string | none | locator for the wrapper — it is not the trigger |
triggerTestId | string | none | locator for the element that opens the list |
itemTestId | (value: string) => string | none | locator for an option row, derived from its value |
Keyboard
- Arrow DownArrow Up
- opens the list on the trigger, then moves the highlight a row
- Ctrl+NCtrl+P
- the same move by its chord, and the same open from the trigger
- EnterSpace
- opens or closes the list on the trigger, then chooses the highlighted row
- Escape
- closes the open list
- Tab
- stays in the open list; it moves on once the list closes
The list is modal while it is open: a press outside closes it.
read from select.js in the pinned GPUix runtime
Edit this page on GitHubapps/docs/content/docs/components/select.mdx