Native Select
A select that opens the operating system's own picker: a wheel on iOS, a list on Android, a dropdown on desktop. Best for long, simple lists in forms and on phones.
Preview
Mirrored is the same English content laid out right to left: it separates a mirroring bug from a translation one.
Installation
Add the component
npx ritla add native-selectAlso works with shadcn:
npx shadcn@latest add @ritla/native-selectDependencies it brings
@base-ui/react@phosphor-icons/reactOr copy by hand
Installing by hand copies the component's source into your project. The source comes with a Ritla UI license, so the CLI is the short way to the same files.
Usage
import { NativeSelect } from "@/components/ui/native-select";<NativeSelect label="Governorate" name="governorate" required> <option value="">Choose a governorate</option> <option value="amman">Amman</option> <option value="irbid">Irbid</option></NativeSelect>Examples
States
A first option with an empty value is the placeholder, drawn in gray. Once something is chosen the field turns white. error with a message replaces the helper text, and disabled switches it off.
API reference
NativeSelect
Also takes every <select> prop (name, value, defaultValue, onChange, autoComplete…). The options are plain <option> and <optgroup> elements.
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | None | Figma's Label. Required and always visible. |
required | boolean | false | The asterisk and required on the select. |
helperText | ReactNode | None | Figma's Helper text. |
error | ReactNode | boolean | None | State = Error. A message replaces the helper text. |
disabled | boolean | false | State = Disabled. |
children | ReactNode | None | The <option> elements. Start with <option value=""> for a placeholder. |
Accessibility
Keyboard
Keys are written for left-to-right. In right-to-left the arrow keys swap: the one pointing toward the reading direction moves forward.
| Key | Action |
|---|---|
| Tab | Moves focus to the select, with a dark blue border and a soft halo like every field. |
| SpaceEnter | Opens the system picker; arrows and typed letters choose as the browser decides. |
ARIA
- A real
<select>: screen readers and phone pickers know it without any extra ARIA. - The label is tied to the select, the helper text or error through
aria-describedby, and an error setsaria-invalid. - The up-and-down caret is decorative.
Arabic and RTL notes
Mirrors
- The label and value sit at the inline start (the right), the caret at the end (the left).
Does not mirror
- The up-and-down caret is vertical and doesn't mirror; the system picker follows the device language.
- Numerals
- Option text shows as you write it: write numbers in the form you want.
- Arabic typography
- The value is
label-16and the labellabel-12, in a 48px field. - Mixed-direction text
- The select takes the page's direction, not
dir="auto", so the caret stays at the inline end even when the chosen option is Latin.
Checks it passes
The Ritla checks this component satisfies by construction. Used as documented, it does not bring these defects onto your page.
- Arabic text falling back past the declared font family (measured, declared, or a webfont that failed to load)
- letter-spacing applied to Arabic text (breaks the connected script)
- Clipped text: content wider than its box with overflow hidden and no ellipsis
- Fixed-pixel-width container whose Arabic text exceeds the space