Skip to main content
Version: v0.30.x

ExpandableCalendar

ExpandableCalendar is the date picker at the top of schedule, booking and habit screens: one week of days that opens into the whole month as you drag it down, following your finger, or when you tap the handle under it, and folds back into a week as you drag it up. The week you open from stays in place as the rest of the month slides out around it, and the month folds into the week of the day you pick.

It's a WeekStrip and the Calendar's month in one, so it takes the same markedDates, minDate, maxDate, isDateDisabled, renderDay and styles, and follows the design: a grabber under the days on iOS, as a sheet has, and a chevron in Material and on the web.

It picks a day; it doesn't draw events. Show the picked day's events under it, as in the schedule below.

import { ExpandableCalendar } from '@elik56a/react-native-pickers';
Loading…
<ExpandableCalendar value={day} onChange={setDay} />

Try the props​

Platform
firstDayOfWeek
weekdayFormat
<ExpandableCalendar
value={day}
onChange={setDay}
firstDayOfWeek={0}
weekdayFormat="short"
/>

A schedule screen​

Pass the days that have something on them as markedDates, and list the picked day's items under the calendar. onWeekChange and onMonthChange tell you which days are shown, to load them.

Loading…
<View>
  <ExpandableCalendar value={day} onChange={setDay} markedDates={MARKS} />
  <View style={{ padding: 16, gap: 8 }}>
    {classes.length ? classes.map((item) => <Text key={item}>{item}</Text>) : <Text>Nothing booked</Text>}
  </View>
</View>

To add an event, open a form with a DateTimePickerField or a TimeRangePickerField.

Open and folded​

The calendar starts as a week, or as the month with defaultExpanded. To open or fold it from your own button, control it with expanded and onExpandedChange:

const [expanded, setExpanded] = useState(false);

<ExpandableCalendar value={day} onChange={setDay} expanded={expanded} onExpandedChange={setExpanded} />
<Button title={expanded ? 'Week' : 'Month'} onPress={() => setExpanded(!expanded)} />
  • Opening shows the month of the selected day when it's in the week shown, else the month most of the week falls in.

  • Folding shows the week of the selected day when it's in the month shown, else today's week, else the month's first week.

  • The arrows and a swipe left or right page by month while open and by week while folded.

  • Dragging moves the month with your finger. Let go past a short way, or with a flick, and it carries on; otherwise it springs back.

enableSwipe={false} turns off the drag and the swipes, leaving the arrows and the handle.

Props​

PropTypeDefaultDescription
valueDate | nullβ€”Selected day (controlled).
defaultValueDate | nullβ€”Initial day when uncontrolled.
onChange(date: Date) => voidβ€”Fires when a day is tapped.
expandedbooleanβ€”Showing the whole month (controlled).
defaultExpandedbooleanfalseInitial state when uncontrolled.
onExpandedChange(expanded: boolean) => voidβ€”Fires when the user opens or folds the month.
initialDateDatethe selected day or todayA day in the week and month shown first.
onWeekChange(weekStart: Date) => voidβ€”Fires with the first day of the week after paging while folded.
onMonthChange(month: Date) => voidβ€”Fires with the first of the month after paging while open.
firstDayOfWeek0–6from locale, else 00 = Sunday.
localestringdeviceWeekday and month names.
minDate / maxDateDateβ€”Days outside are disabled, and paging stops at them.
isDateDisabled(date: Date) => booleanβ€”Disable a day.
markedDatesRecord<string, MarkedDate>β€”Dots, labels or disabled days, keyed by YYYY-MM-DD.
showHeaderbooleantrueShow the month title and the arrows.
formatTitle(month: Date, locale?: string) => stringthe month shownTitle text.
showWeekdaysbooleantrueShow the weekday names.
weekdayFormat'short' | 'narrow'from the designWeekday names: Mon or M.
enableSwipebooleantrueSwipe left or right to page, and drag down to open and up to fold.
renderDay(state: DayState, theme: PickerTheme) => ReactNodeβ€”Fully custom day cell, as on the calendar.
renderArrow(direction, disabled) => ReactNodeβ€”Custom arrows.
dayHeightnumber44Day cell height.
styleStyleProp<ViewStyle>β€”Container style.
stylesSlotStyles<CalendarSlot>β€”The calendar slots, plus expandHandle.
themeDeepPartial<PickerTheme>β€”Theme override.
design'ios' | 'material' | 'web'from PickersProviderThe look to follow, over the provider's: iOS, Material or web.
testIDstringβ€”Test ID.

Accessibility​

The handle is a button named "Show month" or "Show week", with its expanded state. Days read as on the calendar, such as "Wednesday, October 14, 2026", and the arrows as "Previous" and "Next".