Accessibility
Accessibility is built in. Here's what each component exposes to VoiceOver (iOS), TalkBack (Android), screen readers on the web and the keyboard.
Wheels
WheelPicker (and each column of MultiWheelPicker, TimePicker and DateWheelPicker) is a single element with:
| Property | Value |
|---|---|
accessibilityRole | adjustable |
accessibilityValue | the current label, e.g. "45" |
accessibilityActions | increment, decrement: swipe up / down moves one row |
accessibilityLabel | the accessibilityLabel prop |
Name your wheels, especially multi-column ones:
<WheelPicker accessibilityLabel="Shirt size" items={sizes} value={size} onChange={setSize} />
<MultiWheelPicker
columns={[
{ key: 'h', accessibilityLabel: 'Hours', items: hours, value: h, onChange: setH },
{ key: 'm', accessibilityLabel: 'Minutes', items: minutes, value: m, onChange: setM },
]}
/>
Calendar
- Each day is a
buttonlabelled with the full date in the calendar's locale ("Wednesday, 14 October 2026"), withselectedanddisabledstates. - The arrows are buttons labelled Previous and Next, with a
disabledstate at min / max. - The month title is a button (quick jump) or a
header. - Quick-jump grid cells expose
selected/disabled.
Select
- The field is a
buttonlabelled withlabel(or the placeholder). Its hint lists the selected options, and it has anexpandedstate. - Options are
buttons in single mode andcheckboxes in multiple mode, withselected,checkedanddisabled. - Chips are buttons labelled
Remove {label}, and × is labelled Clear. - The search input is labelled with
searchPlaceholder. - While
loading, the loader is aprogressbar.
Horizontal list
The list is a radiogroup named by accessibilityLabel; each item is a radio labelled with its label, with checked and disabled states.
Emoji
Every emoji cell is a button labelled with its name ("thumbs up"). Category tabs are tabs with a selected state, and the skin-tone button is labelled Skin tone.
Sheets
The sheet is marked accessibilityViewIsModal, so focus stays inside it. The backdrop is a button labelled Close, string titles have the header role, and Android back closes the sheet.
Keyboard
On the web, every picker works without a mouse:
| Key | What it does |
|---|---|
| Tab | Moves between fields, buttons, wheels and sliders |
| Enter / Space | Opens a field, picks the focused day, option or emoji |
| ↑ ↓ | On a wheel, steps one row. In a calendar, list or grid, moves to the cell above or below. From a search field, goes into the results, and back |
| ← → | Moves to the next cell, wrapping to the next row, or to the next wheel of a date or time |
| Home / End | Jumps to the first or last cell, or to the ends of a wheel or slider |
| Esc | Closes a sheet or dropdown |
Arrows follow what's drawn, so they go the right way in RTL and in any custom layout. Colour sliders and the colour square move with the arrows, and the clock dial steps its hand. When a sheet or dropdown closes, focus goes back to the field that opened it.
Your checklist
- Give every wheel an
accessibilityLabel. - Translate the English accessibility strings by passing translated
label/placeholder/searchPlaceholderprops. - Keep custom
renderDay/renderOptioncontent as plain views and text. The library already provides the pressable and its accessibility props. - Keep colour contrast when theming:
textSecondaryonbackgroundshould meet WCAG AA (4.5:1) for body text.