Examples
Default
usage.astro | astro
<SelectPrimitive
label="Country"
name="country"
options={[
{ value: 'no', label: 'Norway' },
{ value: 'se', label: 'Sweden' },
{ value: 'dk', label: 'Denmark' },
{ value: 'fi', label: 'Finland' },
{ value: 'is', label: 'Iceland' },
]}
placeholder="Choose a country…"
/> With hint + preselected value
Used to determine your tax region.
usage.astro | astro
<SelectPrimitive
label="Country"
name="country"
options={countryOptions}
value="no"
hint="Used to determine your tax region."
/> With a disabled option
'Urgent' is reserved for paid plans.
usage.astro | astro
<SelectPrimitive
label="Priority"
name="priority"
options={[
{ value: 'low', label: 'Low' },
{ value: 'med', label: 'Medium' },
{ value: 'high', label: 'High' },
{ value: 'urgent', label: 'Urgent', disabled: true },
]}
placeholder="Select priority…"
hint="'Urgent' is reserved for paid plans."
/> Error state
Please pick a country before continuing.
usage.astro | astro
<SelectPrimitive
label="Country"
name="country"
options={countryOptions}
placeholder="Choose a country…"
error="Please pick a country before continuing."
required
/> Success state
Region verified against your billing address.
usage.astro | astro
<SelectPrimitive
label="Verified region"
name="verified-region"
options={countryOptions}
value="se"
variant="success"
hint="Region verified against your billing address."
/> Sizes
usage.astro | astro
<SelectPrimitive label="Small" name="size-sm" size="sm" options={countryOptions} placeholder="sm" />
<SelectPrimitive label="Medium" name="size-md" size="md" options={countryOptions} placeholder="md" />
<SelectPrimitive label="Large" name="size-lg" size="lg" options={countryOptions} placeholder="lg" /> Disabled
usage.astro | astro
<SelectPrimitive
label="Locked region"
name="locked-region"
options={countryOptions}
value="no"
disabled
/> Anatomy
| Property | Behavior |
|---|---|
| Label | Renders above the trigger as a real `<label for>`. |
| Trigger | Native `<select>` styled to match Input. Chevron is a CSS background-image. |
| Chevron | Static down-chevron icon at the suffix position — cosmetic only. |
| Hint | Plain helper text below the trigger; `aria-describedby` is wired automatically. |
| Error | Replaces the hint when `error` is set; toggles `aria-invalid="true"`. |
Accessibility
- Renders a real native
<select>, so keyboard navigation (typeahead, ArrowUp/Down, Home/End) and the platform's own option dialog are inherited from the browser. labelrenders as a paired<label for>; clicking the label focuses the select.hint+errorare wired viaaria-describedbyand announced by SR after the field's name.- Setting
errorsetsaria-invalid="true"on the trigger. - Disabled options use the native
disabledattribute, so SR announce them as "dimmed" / "unavailable." - Focus uses the system focus ring (
--ds-shadow-focus-ring) — visible on every surface.
Do / Don't
| Property | Do | Don't |
|---|---|---|
| Native first | Use SelectPrimitive for short, flat option lists where the browser picker is acceptable. | Reach for SelectPrimitive when you need grouping, search, or rich option rendering — wait for the Combobox primitive. |
| Option count | Keep total options under ~12; sort alphabetically or by frequency. | Dump 200 items into the native picker — UX collapses on mobile. |
| Placeholder | Show a `placeholder` only when no `value` makes sense as default. | Use the placeholder to convey constraints — put those in `hint`. |
| Disabled opts | Mark a single option `disabled: true` when context (plan, role) forbids it. | Disable the whole select to hide that an option exists — surface why instead. |
| Error copy | Explain what changed ("Pick a country before continuing"). | Use vague copy ("Invalid") — users have no way to recover. |
Props
| Property | Type | Default |
|---|---|---|
| label | string | required |
| name | string | required |
| options | {value, label, disabled?}[] | required |
| value | string | - |
| placeholder | string | - |
| hint | string | - |
| error | string | - |
| variant | default | error | success | 'default' |
| size | sm | md | lg | 'md' |
| required | boolean | false |
| disabled | boolean | false |
| className | string | '' |
Source
SelectPrimitive.astro | astro
<SelectPrimitive
label="Country"
name="country"
options={[
{ value: 'no', label: 'Norway' },
{ value: 'se', label: 'Sweden' },
{ value: 'dk', label: 'Denmark' },
]}
placeholder="Choose a country…"
hint="Used to determine your tax region."
/>
<SelectPrimitive
label="Priority"
name="priority"
options={[
{ value: 'low', label: 'Low' },
{ value: 'med', label: 'Medium' },
{ value: 'high', label: 'High' },
{ value: 'urgent', label: 'Urgent', disabled: true },
]}
error="Please pick a priority."
required
/>