Skip to main content
Version: Next 🚧

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:

PropertyValue
accessibilityRoleadjustable
accessibilityValuethe current label, e.g. "45"
accessibilityActionsincrement, decrement: swipe up / down moves one row
accessibilityLabelthe 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 button labelled with the full date in the calendar's locale ("Wednesday, 14 October 2026"), with selected and disabled states.
  • The arrows are buttons labelled Previous and Next, with a disabled state 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 button labelled with label (or the placeholder). Its hint lists the selected options, and it has an expanded state.
  • Options are buttons in single mode and checkboxes in multiple mode, with selected, checked and disabled.
  • Chips are buttons labelled Remove {label}, and × is labelled Clear.
  • The search input is labelled with searchPlaceholder.
  • While loading, the loader is a progressbar.

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:

KeyWhat it does
TabMoves between fields, buttons, wheels and sliders
Enter / SpaceOpens 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 / EndJumps to the first or last cell, or to the ends of a wheel or slider
EscCloses 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 / searchPlaceholder props.
  • Keep custom renderDay / renderOption content as plain views and text. The library already provides the pressable and its accessibility props.
  • Keep colour contrast when theming: textSecondary on background should meet WCAG AA (4.5:1) for body text.