Select
Select with a menu that unfolds downward, a pixel highlight that springs between options and type-ahead by first letter.
Playground
Change a prop and the component re-renders. Props marked remounts set an initial value, so the component starts over.
<PxSelect
label="Model"
hint="You can change this per chat"
options={[
{
value: "opus",
label: "Opus 5.5",
description: "Most capable"
},
{
value: "sonnet",
label: "Sonnet 5.5",
description: "Balanced"
},
{
value: "haiku",
label: "Haiku 4.5",
description: "Fastest"
}
]}
defaultValue="sonnet"
/>Installation
pnpm dlx shadcn@latest add @lumesec/px-selectFirst timeRegister the @lumesec registry once, or install by URL+
Adds @lumesec to your components.json:
pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.jsonOr skip the setup and install by URL:
npx shadcn@latest add https://elements.lumesec.ai/r/px-select.jsonUsage
import { PxSelect } from "@/components/lumesec/px-select";
export function Example() {
return (
<PxSelect
name="model"
label="Model"
hint="You can change this per chat"
defaultValue="sonnet"
options={[
{ value: "opus", label: "Opus 5.5", description: "Most capable" },
{ value: "sonnet", label: "Sonnet 5.5", description: "Balanced" },
{ value: "haiku", label: "Haiku 4.5", description: "Fastest" },
]}
/>
);
}Behaviour
Takes a typed list of options. The menu unfolds downward, a pixel highlight follows your pointer or the arrow keys, and typing a letter jumps to it.
API reference
Props
Also accepts every prop of <div> (React.ComponentProps<"div">), spread onto the root element.
optionsTypereadonly PxSelectOption[]The choices: { value?: string; label: string; description?: string }. value defaults to label; description is a second line in the menu.
valueTypestringControlled selected value. Use with onValueChange.
defaultValueTypestringDefaultfirst optionInitially selected value when uncontrolled. A form reset restores it.
openTypebooleanControlled open state of the menu. Use with onOpenChange.
defaultOpenTypebooleanDefaultfalseInitial open state when uncontrolled.
labelTypeReact.ReactNodeLabel above the trigger; also names the listbox.
hintTypeReact.ReactNodeHelp text under the trigger.
nameTypestringForm field name; the selected value submits under it.
disabledTypebooleanDefaultfalseDims the select and disables the trigger.
onValueChangeType(value: string) => voidCalled when the user picks a different option.
onOpenChangeType(open: boolean) => voidCalled when the menu opens or closes.
Ref
ref points at the root HTMLDivElement.
Keyboard
| Keys | Action |
|---|---|
| ArrowDown / ArrowUp (on the trigger) | Open the menu. |
| ArrowDown / ArrowUp (in the menu) | Move the highlight; stops at the first and last option. |
| Home / End | Highlight the first / last option. |
| Enter / Space | Choose the highlighted option and close. |
| Escape / Tab | Close and return focus to the trigger. |
| Printable character | Highlight the next option whose label starts with that character. |
Accessibility
- The trigger is a native button with
aria-haspopup="listbox",aria-expandedandaria-labelledbypointing at the label and the selected value. - The menu is a
role="listbox"labelled by the label, witharia-activedescendanton the highlighted option; options haverole="option"andaria-selected. - Opening moves focus to the listbox; choosing, Escape or Tab return it to the trigger. A pointer press outside closes the menu without moving focus.
hintis not linked witharia-describedby. The highlight canvas isaria-hidden.- With
name, a hidden input submits the selected option's value. There is no validation. Form reset restoresdefaultValue(or the first option) and callsonValueChangewhen that changes the value. - Reduced motion: the menu opens without unfolding, the chevron does not rotate, the highlight jumps and the value swaps without rolling.
Theming
Styled with Tailwind classes on your shadcn theme tokens, so light and dark follow your theme. The accent comes from --lumesec. See Theming.
This component reads --foreground, --muted-foreground, --card, --border and --lumesec.
Notes
- The menu opens below the whole component, under the hint, and overlays the content after it (
z-index: 30). - The root carries
data-state="open"ordata-state="closed".
Related
Was this page helpful?