Native Select
Styled HTML select element with option groups. Zero JS — best for mobile forms.
Examples
Disabled
Add the disabled prop to the NativeSelect component to disable the select.
import { NativeSelect, NativeSelectOption } from "@codefast/ui/native-select";
export function NativeSelectDisabled() {
return (
<NativeSelect disabled>
<NativeSelectOption value="">Disabled</NativeSelectOption>
<NativeSelectOption value="apple">Apple</NativeSelectOption>
<NativeSelectOption value="banana">Banana</NativeSelectOption>
<NativeSelectOption value="blueberry">Blueberry</NativeSelectOption>
</NativeSelect>
);
}
Groups
Use NativeSelectOptGroup to organize options into categories.
import { NativeSelect, NativeSelectOptGroup, NativeSelectOption } from "@codefast/ui/native-select";
export function NativeSelectGroups() {
return (
<NativeSelect>
<NativeSelectOption value="">Select department</NativeSelectOption>
<NativeSelectOptGroup label="Engineering">
<NativeSelectOption value="frontend">Frontend</NativeSelectOption>
<NativeSelectOption value="backend">Backend</NativeSelectOption>
<NativeSelectOption value="devops">DevOps</NativeSelectOption>
</NativeSelectOptGroup>
<NativeSelectOptGroup label="Sales">
<NativeSelectOption value="sales-rep">Sales Rep</NativeSelectOption>
<NativeSelectOption value="account-manager">Account Manager</NativeSelectOption>
<NativeSelectOption value="sales-director">Sales Director</NativeSelectOption>
</NativeSelectOptGroup>
<NativeSelectOptGroup label="Operations">
<NativeSelectOption value="support">Customer Support</NativeSelectOption>
<NativeSelectOption value="product-manager">Product Manager</NativeSelectOption>
<NativeSelectOption value="ops-manager">Operations Manager</NativeSelectOption>
</NativeSelectOptGroup>
</NativeSelect>
);
}
Invalid
Use aria-invalid to show validation errors and the data-invalid attribute to the Field component for styling.
import { NativeSelect, NativeSelectOption } from "@codefast/ui/native-select";
export function NativeSelectInvalid() {
return (
<NativeSelect aria-invalid="true">
<NativeSelectOption value="">Error state</NativeSelectOption>
<NativeSelectOption value="apple">Apple</NativeSelectOption>
<NativeSelectOption value="banana">Banana</NativeSelectOption>
<NativeSelectOption value="blueberry">Blueberry</NativeSelectOption>
</NativeSelect>
);
}
RTL
Right-to-left layout support for languages such as Arabic and Hebrew.
Translations are AI-generated for demonstration and may be imperfect.
import { NativeSelect, NativeSelectOption } from "@codefast/ui/native-select";
import type { Translations } from "#/features/components-catalog/components/detail/language";
import { useTranslation } from "#/features/components-catalog/components/detail/language-context";
const translations: Translations = {
en: {
dir: "ltr",
values: {
placeholder: "Select status",
todo: "Todo",
inProgress: "In Progress",
done: "Done",
cancelled: "Cancelled",
},
},
ar: {
dir: "rtl",
values: {
placeholder: "اختر الحالة",
todo: "مهام",
inProgress: "قيد التنفيذ",
done: "منجز",
cancelled: "ملغي",
},
},
he: {
dir: "rtl",
values: {
placeholder: "בחר סטטוס",
todo: "לעשות",
inProgress: "בתהליך",
done: "הושלם",
cancelled: "בוטל",
},
},
};
export function NativeSelectRtl() {
const { dir, t } = useTranslation(translations, "ar");
return (
<NativeSelect dir={dir}>
<NativeSelectOption value="">{t.placeholder}</NativeSelectOption>
<NativeSelectOption value="todo">{t.todo}</NativeSelectOption>
<NativeSelectOption value="in-progress">{t.inProgress}</NativeSelectOption>
<NativeSelectOption value="done">{t.done}</NativeSelectOption>
<NativeSelectOption value="cancelled">{t.cancelled}</NativeSelectOption>
</NativeSelect>
);
}
Usage
The minimal import and composition — see Examples below for styled, real-world variants.
import { NativeSelect, NativeSelectOption } from "@codefast/ui/native-select";
export function NativeSelectUsage() {
return (
<NativeSelect defaultValue="apple">
<NativeSelectOption value="apple">Apple</NativeSelectOption>
<NativeSelectOption value="banana">Banana</NativeSelectOption>
<NativeSelectOption value="blueberry">Blueberry</NativeSelectOption>
</NativeSelect>
);
}
Anatomy
How the parts nest — every slot the component exposes, in composition order.
Features
- A real native <select> — zero JS, full OS-native keyboard and screen-reader support, and the mobile picker UI.
- Two sizes (default, sm).
- NativeSelectOption/NativeSelectOptGroup use the Canvas/CanvasText CSS system colors, so options render correctly inside the browser's native dropdown popup in both light and dark mode.
API reference
Props for each part of the component. All native element props are also forwarded.
NativeSelect
A styled native <select>. Forwards all native select props.
valuestringThe controlled value.
onChangeReact.ChangeEventHandler<HTMLSelectElement>Called when the selected value changes.
disabledbooleanDisables the control.
Default
false
NativeSelectOptGroup
labelstringThe group heading text.
NativeSelectOption
valuestringThe option’s submitted value.
Accessibility
Built to be keyboard-navigable and screen-reader friendly out of the box.
- It’s a real <select> — full native keyboard and screen-reader support, zero JS.
- Best for mobile and long lists where the OS picker is ideal.
- Pair with a Label via htmlFor / id.
Guidelines
Conventions that keep usage consistent across an app.
Do
- Use on mobile forms and when you want the native picker.
- Group long option lists with opt-groups.
Don’t
- Don’t use it when you need custom option rendering — use Select.
- Don’t omit a label.
Explore further
Ready to integrate?
Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.