Native Select
A native HTML select element with custom styling.
When to Use
Use Native Select when you need to:
- Provide a dropdown with native browser behavior and mobile-optimized pickers
- Allow users to choose a single option from a predefined list of 5-15 items
- Use a form control that works without JavaScript for progressive enhancement
- Leverage the operating system's native accessibility features for selection
- Group related options into categories using option groups
When Not to Use
- Custom styled dropdowns with animations - use Select
- Searchable or filterable option lists - use Combobox
- Fewer than 3 mutually exclusive options - use Radio Group
- Multi-selection or complex option rendering with icons, avatars, or descriptions
Default
A native select with a list of status options.
With Groups
Organize options into logical categories using NativeSelectOptGroup for better scannability.
Disabled
Disabled state prevents all user interaction and reduces opacity to indicate unavailability.
Invalid State
Show validation errors with the aria-invalid attribute. Applies a destructive border and ring color.
Form Example
Native select paired with a Label component inside a form layout for proper accessibility.
UX & Design Guidelines
Visual Hierarchy
Native selects use a subtle border and chevron icon to signal interactivity. The chevron is styled with text-muted-foreground at 50% opacity to remain visible without competing with the selected value text. Use a placeholder option (empty value) as the first option to prompt selection.
Spacing & Layout
The default height is h-9 (36px) with px-3 py-2 padding. Use size="sm" for compact layouts at h-8 (32px). When placing selects in forms, maintain consistent spacing with gap-4 between form fields.
Responsive Behavior
Native selects automatically use the platform's native picker on mobile devices, providing a familiar scrolling interface on iOS and a dropdown dialog on Android. The wrapper uses w-fit by default; apply w-full to the wrapper for full-width selects in responsive form layouts.
Color & Contrast
The select uses border-input for the border and transparent background in light mode. In dark mode, it applies dark:bg-input/30 with a hover state of dark:hover:bg-input/50 for subtle visual feedback. Selection highlighting uses bg-primary with text-primary-foreground.
Accessibility
Keyboard Navigation
- Tab — Move focus to/from the select
- Space or Enter — Open the dropdown on most browsers
- Arrow Up / Arrow Down — Navigate through options
- Home / End — Jump to first/last option
- Type a character to jump to matching options (native type-ahead)
Screen Reader Support
- Native HTML
<select>provides built-in screen reader support - Options and option groups are announced with their labels automatically
- The currently selected value is read aloud when the select receives focus
- Use a visible
<Label>with matchinghtmlForandidfor best results
Focus Management
Focus ring uses focus-visible:ring-[3px] with ring-ring/50 color and focus-visible:border-ring. Invalid selects display a destructive ring with aria-invalid:ring-destructive/20. The decorative chevron icon is marked aria-hidden="true" so it does not interfere with assistive technology.
ARIA Attributes
{/* Associate with a visible label */}
<Label htmlFor="country">Country</Label>
<NativeSelect id="country">
<NativeSelectOption value="">Select a country</NativeSelectOption>
<NativeSelectOption value="us">United States</NativeSelectOption>
</NativeSelect>
{/* Standalone select with aria-label */}
<NativeSelect aria-label="Filter by status">
<NativeSelectOption value="">All statuses</NativeSelectOption>
<NativeSelectOption value="active">Active</NativeSelectOption>
<NativeSelectOption value="archived">Archived</NativeSelectOption>
</NativeSelect>
{/* Invalid state with error description */}
<NativeSelect
aria-invalid="true"
aria-describedby="role-error"
>
<NativeSelectOption value="">Select role</NativeSelectOption>
</NativeSelect>
<span id="role-error" className="text-sm text-destructive">
Please select a role
</span>Related Components
API Reference
The NativeSelect component accepts the following props in addition to standard HTML select attributes.
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "sm" | "default" | "default" | The size of the select. Small size reduces height. |
| disabled | boolean | false | When true, prevents user interaction and applies disabled styles. |
| aria-invalid | boolean | string | false | When true, applies error/invalid styling with destructive border and ring. |
| aria-label | string | — | Accessible label for the select when no visible label is present. |
| className | string | — | Additional CSS classes to apply to the select element. |
NativeSelectOption Props
Individual option within the select. Extends standard HTML option attributes.
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | — | The value submitted with the form when this option is selected. |
| disabled | boolean | false | When true, prevents selection of this option. |
| className | string | — | Additional CSS classes to apply to the option. |
NativeSelectOptGroup Props
Groups related options together with a visible label. Extends standard HTML optgroup attributes.
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | — | The visible label for the option group. |
| disabled | boolean | false | When true, disables all options within the group. |
| className | string | — | Additional CSS classes to apply to the option group. |