Forms
Select
One choice from many. A styled listbox rather than a native select, which is a trade rather than a free win.
Basic
Open it and type to jump to an option.
<Select.Root defaultValue="public"> <Select.Trigger> <Select.Value placeholder="Choose access…" /> </Select.Trigger> <Select.Content> <Select.Group> <Select.Label>Registry</Select.Label> <Select.Item value="public">Public</Select.Item> <Select.Item value="restricted">Restricted</Select.Item> </Select.Group> <Select.Separator /> <Select.Group> <Select.Label>Internal</Select.Label> <Select.Item value="private">Private</Select.Item> <Select.Item value="none" disabled>Unpublished</Select.Item> </Select.Group> </Select.Content></Select.Root>Select.Label only works inside Select.Group and throws if it is not. The label is the group's accessible name, so a label with no group names nothing.A value too long for the trigger truncates, and the list is free to be wider than the trigger it drops from. The control has a width to keep in a form column; the list only has to be readable, and stops at the edge of the viewport.
A native
select gets the platform's own picker on mobile, which usually beats anything a web page can draw. Reach for this one when options need icons, descriptions or grouping the native element cannot express.In a Field
Field.Control hands its props to the trigger.
Public packages cannot be made private later.
<Field.Root required> <Field.Label>Access</Field.Label> <Field.Control> {props => ( <Select.Root> <Select.Trigger {...props}> <Select.Value placeholder="Choose…" /> </Select.Trigger> <Select.Content> <Select.Item value="public">Public</Select.Item> <Select.Item value="private">Private</Select.Item> </Select.Content> </Select.Root> )} </Field.Control> <Field.Description>Public packages cannot be made private later.</Field.Description></Field.Root>Parts
Import it as a namespace, and the parts work on either side of the server boundary.
import * as Select from '@minuk-hwang-design-system/components-react/select';| Part | What it is |
|---|---|
Select.Root | Owns the value. |
Select.Trigger | The control. Sized like Input, with the chevron built in. |
Select.Value | Renders the chosen label, or the placeholder. |
Select.Content | The list. Viewport and scroll buttons included. |
Select.Item | One option, with the check-mark gutter. |
Select.Group | Wraps a label and the items it names. Required around Select.Label. |
Select.Label | Names the group it is in. Skipped by the keyboard, and throws outside a Group. |
Select.Separator | Divider between groups. |
Props
| Prop | Type | Default | Notes |
|---|---|---|---|
value | string | — | Controlled selection, on Root. |
defaultValue | string | — | On Root. The starting choice when the value is left uncontrolled. |
onValueChange | (value: string) => void | — | On Root. Fires with the value of the chosen item. |
size | 's' | 'm' | 'l' | 'm' | On Trigger. Height, inset and type, all matching Input. |
placeholder | string | — | On Value. Shown while nothing is chosen. |