Skip to main content
Version: v0.23.2

For AI assistants

This documentation is published in machine-readable form, following the llms.txt convention:

FileContents
/llms.txtIndex of every page with a one-line summary
/llms-full.txtThe entire documentation in one Markdown file: every component, prop table and example
/docs/**/*.mdEach page as plain Markdown

Paste llms-full.txt into your assistant's context, or point Cursor / Claude / Copilot at the URL.

llms-full.txt also ships inside the npm package, so a coding agent can read it offline from node_modules/@elik56a/react-native-pickers/llms-full.txt, always matching the installed version.

Cheat sheet​

Package: @elik56a/react-native-pickers (npm i @elik56a/react-native-pickers)
Zero native code (pure JS), no peer deps besides react >=18 and react-native >=0.72.
Works in Expo Go, bare RN, React Native Web. All exports are named exports from the package root.
Looks native per platform by default (design 'auto': iOS on iOS, Material on Android, web on web). One look everywhere:
<PickersProvider design="ios"> (or 'material' | 'web'); per component: design="material". theme/styles/explicit props always win over the design.
Every component takes: theme (DeepPartial<PickerTheme>), design ('ios'|'material'|'web'), styles (slot styles), style, testID.
Native apps: prefer subpaths so Metro skips unused pickers (root import bundles ~130 KB of emoji data):
/wheel /time /date /calendar /datetime /select /list /emoji /sheet /core e.g. '@elik56a/react-native-pickers/date'
PickersProvider and theme/date utils live in /core. Subpaths need RN 0.79+ (Metro package exports).

Controlled: value + onChange. Uncontrolled: defaultValue. SelectPicker/SelectList/HorizontalList are controlled-only.
onChange fires on user changes only (not when value is set programmatically). Wheels fire onChange when they settle;
onValueChanging fires on every row crossing (use for haptics).

WheelPicker<T> items: (T | {label, value, disabled?})[] value onChange(value, index) loop itemHeight=40 visibleItems=5
variant '3d'|'flat' keyboardInput=true isEqual renderItem({item,index,selected,theme}) styles
MultiWheelPicker columns: [{ key, items, value, onChange, flex?, width?, loop?, suffix? }] separator: node | (leftIndex)=>node (suffix = unit text after a column)
TimePicker value: Date onChange(date) format '12h'|'24h'|'auto' minuteInterval showSeconds minTime/maxTime locale
display 'wheel'(ios) | 'dial'(material clock) | 'input'(typed fields) | 'list'(web columns); default from the design
DurationPicker a length of time, not a time of day: value: number (seconds) onChange(seconds) showHours=true showSeconds=false
display 'wheel'(ios) | 'input'(material number boxes) | 'list'(web columns); default from the design
min max (seconds; default max 23h59m59s, or 59m59s without hours) minuteInterval secondInterval loop (minutes/seconds)
labels {hours:'h',minutes:'min',seconds:'s'} formatDuration(5400) β†’ '1 h 30 min'
DateTimePicker value: Date onChange(date) display 'wheel'(ios default)|'calendar'(material/web default) minDate maxDate (moments)
timePosition 'beside'|'below' timeDisplay 'wheel'|'dial'|'input'|'list' minuteInterval format locale calendarProps
DatePicker display 'calendar'(default)|'wheel'
mode 'single' value: Date|null onChange(date)
mode 'range' value: {start,end} onChange(range) minRangeDays maxRangeDays allowSingleDayRange
mode 'multiple' value: Date[] onChange(dates) maxSelections
mode 'ranges' value: DateRange[] onChange(ranges) maxRanges minRangeDays maxRangeDays allowSingleDayRange
minDate maxDate isDateDisabled(date) markedDates{'YYYY-MM-DD':{dots?,label?,textColor?,disabled?}}
locale firstDayOfWeek(0=Sun) initialMonth onMonthChange renderDay(state,theme) dayHeight=44
DateWheelPicker value: Date onChange order ['day','month','year'] monthFormat 'long'|'short'|'numeric' min/maxDate
MonthPicker a month without a day: value: Date (first of the month) onChange(month) display 'wheel'(ios: month+year wheels) | 'grid'(material/web: months under the year, tap the year for years)
minDate maxDate (any day in the month) yearRange monthFormat 'long'|'short'|'numeric' (wheels) locale
WeekStrip one week of days in a row: value: Date|null onChange(date) swipe/arrows page weeks onWeekChange(weekStart) initialWeek
minDate maxDate isDateDisabled markedDates firstDayOfWeek locale showHeader formatTitle(weekStart) weekdayFormat renderDay (calendar's day cells and slots)
SelectPicker<T> options: {label,value,description?,icon?,group?,disabled?,keywords?}[] value onChange(value, option)
multiple β†’ value T[], onChange(values, options), maxSelected, chips
label placeholder searchable(dropdown: type in field, default on; sheet: >8 auto) clearable+onClear (single: reset value in onClear) renderTrigger({open,selected}) renderChevron({open,theme})
presentation 'auto'(dropdown on web, bottom sheet on native)|'bottomSheet'|'modal'|'dropdown'
SelectList<T> same list inline: options value onChange multiple listHeight
server search: loadOptions(query) => Promise<options> (debounced by searchDebounce=300ms, loader until results, stale answers ignored; options = shown before typing; searchPrompt='Type to search' when none, emptyText after an empty search)
or manual: onSearchChange(query) + loading + onEndReached; loadingText renderLoading(theme); no local filtering with either
CountryPicker a SelectPicker with ~250 countries built in: value CountryCode ('IL') or CountryCode[] with multiple onChange(code, option)
preferred (pinned on top) countries exclude showDialCode locale (names via Intl.DisplayNames, English fallback; search matches English/native names, ISO code, +dial)
every SelectPicker prop except options/loadOptions/server search; getCountry(code) β†’ {code,name,nativeName?,dialCode,flag,keywords} getAllCountries() getCountryFlag(code)
PhoneField phone number input: flag + calling code button (CountryPicker list) then the number, formatted as typed ('(201) 555-0123', '54-123-4567')
value/defaultValue: E.164 string ('+972541234567', '' when empty) onChange(value, {country, nationalNumber, valid}) valid = length fits the country
country/defaultCountry='US'/onCountryChange label placeholder(default example) disabled presentation countrySheetTitle='Country code' sheet
preferred countries exclude locale preferredLabel allCountriesLabel; styles: label field input countryButton dialCode chevron
a leading trunk 0 is dropped (not IT/SM/VA); pasting '+44…' switches country; ~50 country formats, others grouped in threes
utils: parsePhone(intl, current?) β†’ {country?, nationalNumber} formatNationalNumber(digits, code) isValidPhone(digits, code) toE164(digits, code)
TimeZonePicker a SelectPicker with all 418 IANA zones built in: value IANA name ('Europe/Lisbon') or string[] with multiple onChange(id, option)
label = city, description 'GMT+1 Β· Central European Standard Time' (zone name where the engine has it, else region); sorted by offset
preferred (default: the device's zone, under 'Your time zone'; [] pins none) timeZones (only these) date (offsets for that moment, DST-aware) locale
old names ('Asia/Calcutta', 'Europe/Kiev') accepted as value, reported as current ('Asia/Kolkata'); search matches city, IANA name, region, GMT/UTC offset, zone name
utils: getDeviceTimeZone() getTimeZoneOffset(id, date?) β†’ minutes formatGmtOffset(330) β†’ 'GMT+5:30' getTimeZoneName(id, locale?, date?) normalizeTimeZone(id) getTimeZone(id) getAllTimeZones()
HorizontalList<T> items: {label,value,disabled?,icon?}[] (icon: node or ({selected,disabled,color}) => node) value onChange(value, item) variant 'segmented'|'chips' iconPosition 'left'|'right'|'top'|'bottom' showArrows (β€Ή β€Ί scroll buttons, default false) arrowPosition 'outside'|'overlay' (default 'outside') renderArrow(side, disabled) renderItem (tap at the edge scrolls the next item into view)
EmojiPicker onSelect(emoji, data) columns=8 height=380 categories exclude maxEmojiVersion skinTone recent onRecentChange categoryBarPosition 'auto'(bottom on ios/material, top on web)|'top'|'bottom'
ColorPicker value: hex ('#E4572E', or '#E4572E80' with showAlpha) onChange('#RRGGBB'|'#RRGGBBAA', fires while dragging)
display 'tabs'(ios: Grid/Spectrum/Sliders) | 'swatches'(material: circles + Custom) | 'spectrum'(web: square, hue, hex, eyedropper); default from the design
colors (hex | {value,label})[]=DEFAULT_COLORS showCustom=true showAlpha=false onCopy(hex) (copy button; web clipboard by default, native needs it, e.g. expo-clipboard) labels normalizeHex hexToHsv hsvToHex withAlpha
BottomSheet visible onClose title headerLeft headerRight footer height(<=1 fraction | px) enableSwipeToClose draggable(header drags too; native:true web:false; handle always drags) expandable expandedHeight
Sheets (draft; commit on Done):
DatePickerSheet visible onClose value onConfirm + all calendar props + mode + display + confirmOnSelect
TimePickerSheet visible onClose value onConfirm + TimePicker props
WheelPickerSheet visible onClose items value onConfirm
EmojiPickerSheet visible onClose onSelect closeOnSelect=true
ColorPickerSheet visible onClose value onConfirm(color) + ColorPicker props
DateTimePickerSheet visible onClose value onConfirm + DateTimePicker props
DurationPickerSheet visible onClose value onConfirm(seconds) + DurationPicker props
MonthPickerSheet visible onClose value onConfirm(month) + MonthPicker props
PickerSheet visible onClose onConfirm children + useDraft(value, visible)
Fields (a SelectPicker-style field that opens the sheet and shows the confirmed value; field owns open state):
DatePickerField / TimePickerField / DateTimePickerField / DurationPickerField / MonthPickerField / ColorPickerField / WheelPickerField / EmojiPickerField
= the matching *Sheet props WITHOUT visible (value, onConfirm | onSelect, mode, locale, title...)
+ label placeholder='Select…' displayValue(default: value formatted for locale) clearable+onClear(reset value there)
disabled renderTrigger({open,displayValue,disabled}) renderChevron({open,theme}) onOpen onClose style testID
presentation 'auto'(dropdown on web, bottom sheet on native)|'bottomSheet'|'modal'|'dropdown'; design is passed on to the sheet
styles = field slots (label trigger triggerText placeholder chevron clear) + the picker's slots
EmojiPickerField also takes value: string (the emoji shown). Sheet title defaults to label.
PickerField same field props, children: ({visible, onClose}) => <AnySheet .../>
Theme: <PickersProvider colorScheme='auto'|'light'|'dark' theme={...} darkTheme={...} platform?='ios'|'android'|'web' design='auto'|'ios'|'material'|'web'>; per-component `theme` and `design` props. `platform` makes pickers behave as on that OS (preview native in a browser). `design` is the look: 'auto' = ios on iOS, web on web, material elsewhere; sheet actions in the header (ios: Cancel/Done) or footer (material: Cancel/OK), radios for single select and outlined floating-label fields in material, a date headline above Material calendars, TimePicker display: 'wheel' (ios) | 'dial' (material clock dial with a keyboard-entry toggle) | 'input' (typed hour/minute fields) | 'list' (web: hour/minute/AM-PM columns to click); dial and input fall back to wheels with showSeconds. DateTimePicker display defaults: 'wheel' on ios, 'calendar' in material (time input under it) and web (time columns beside it); timePosition 'beside'|'below' overrides where the time goes (beside moves below when both don't fit), timeDisplay 'wheel'|'dial'|'input'|'list' how it's picked. Calendar: ios tints the chosen day, material fills it and rings today with narrow S M T weekdays, web uses filled rounded squares, ripple in material and a dim while pressed on ios/web.
tokens: colors{background,surface,sheet,text,textSecondary,textDisabled,primary,onPrimary,primaryMuted,border,backdrop,indicator,handle}
radius{sm,md,lg,full,sheet} spacing{xs..xl} typography{fontFamily,fontFamilyMedium,sizes,weights} animation{duration}
Keyboard (web, built in): arrows move focus through calendars, lists and grids by position (RTL-aware) and step wheels, sliders and the dial; Home/End; Esc closes sheets; focus returns to the field.
Slots: every component takes `styles={{ slotName: style }}`.
Utils: toDateKey(d) 'YYYY-MM-DD' local; addDays addMonths isSameDay compareDay isBetweenDays formatDate(d, locale, opts)
searchEmojis findEmoji withSkinTone getAllEmojis; defaultFilter for select search.

Canonical examples​

import { useState } from 'react';
import {
DatePicker,
DatePickerField,
DatePickerSheet,
DateTimePicker,
HorizontalList,
PickersProvider,
SelectPicker,
TimePicker,
TimePickerField,
WheelPicker,
} from '@elik56a/react-native-pickers';
import type { DateRange } from '@elik56a/react-native-pickers';

function Examples() {
const [size, setSize] = useState('M');
const [time, setTime] = useState(new Date());
const [date, setDate] = useState<Date | null>(null);
const [range, setRange] = useState<DateRange>({ start: null, end: null });
const [country, setCountry] = useState<string | null>(null);
const [open, setOpen] = useState(false);
const [view, setView] = useState('day');

return (
<>
<WheelPicker items={['S', 'M', 'L']} value={size} onChange={setSize} />
<TimePicker value={time} onChange={setTime} minuteInterval={5} />
<DateTimePicker value={time} onChange={setTime} />
<HorizontalList items={[{ label: 'Day', value: 'day' }, { label: 'Week', value: 'week' }]} value={view} onChange={setView} />
<DatePicker value={date} onChange={setDate} minDate={new Date()} />
<DatePicker mode="range" value={range} onChange={setRange} />
<SelectPicker label="Country" options={[{ label: 'Israel', value: 'IL' }]} value={country} onChange={setCountry} />
<DatePickerSheet visible={open} onClose={() => setOpen(false)} mode="range" value={range} onConfirm={setRange} />
{/* In forms: a field that opens the sheet and shows the value, no open state needed */}
<DatePickerField label="Stay" mode="range" value={range} onConfirm={setRange} placeholder="Add dates" />
<TimePickerField label="Time" value={time} onConfirm={setTime} />
</>
);
}

// Optional, once at the root: brand colors, and one design on every platform instead of the native one per OS
export const App = () => (
<PickersProvider theme={{ colors: { primary: '#FF5A5F' } }} design="ios">
<Examples />
</PickersProvider>
);