Skip to main content
The ExpandableCalendar component provides an interactive calendar that can expand from a week view to a full month view, with smooth animations and gesture support.
The ExpandableCalendar should be wrapped with CalendarProvider to work properly.

Basic usage

import { CalendarProvider, ExpandableCalendar } from 'react-native-calendars';

<CalendarProvider date="2023-05-16">
  <ExpandableCalendar
    firstDay={1}
    markedDates={{
      '2023-05-16': {marked: true}
    }}
  />
</CalendarProvider>

Props

ExpandableCalendar extends all CalendarList props.

Position and behavior

initialPosition
'open' | 'closed'
default:"'closed'"
The initial position of the calendar. Use the exported Positions enum.
import { ExpandableCalendar } from 'react-native-calendars';

<ExpandableCalendar
  initialPosition={ExpandableCalendar.positions.OPEN}
/>
disablePan
boolean
Disable the pan gesture and prevent opening/closing of the calendar. The initialPosition will persist.
closeOnDayPress
boolean
default:"true"
Whether to close the calendar when a day is pressed.

Gesture thresholds

openThreshold
number
default:"30"
A threshold (in pixels) for opening the calendar with the pan gesture.
closeThreshold
number
default:"30"
A threshold (in pixels) for closing the calendar with the pan gesture.

Display options

hideKnob
boolean
Whether to hide the knob. Automatically hidden when numberOfDays > 1.
allowShadow
boolean
default:"true"
Whether to have shadow/elevation for the calendar.
disableWeekScroll
boolean
Whether to disable the week scroll in closed position.

Arrow customization

leftArrowImageSource
ImageSourcePropType
Source for the left arrow image.
leftArrowImageSource={require('./custom-left-arrow.png')}
rightArrowImageSource
ImageSourcePropType
Source for the right arrow image.
rightArrowImageSource={require('./custom-right-arrow.png')}

Event handlers

onCalendarToggled
(isOpen: boolean) => void
Callback that fires when the calendar is opened or closed.
onCalendarToggled={(isOpen) => {
  console.log('Calendar is now', isOpen ? 'open' : 'closed');
}}
onDayPress
(date: DateData) => void
Handler which gets executed on day press.
onVisibleMonthsChange
(months: DateData[]) => void
Handler which gets executed when visible months change.

CalendarList props

Since ExpandableCalendar extends CalendarList, it also supports:
horizontal
boolean
default:"true"
Whether to render the calendar list horizontally.
calendarStyle
ViewStyle
Style for the calendar.
theme
Theme
Theme object for styling the calendar.
firstDay
number
default:"0"
First day of the week (0 = Sunday, 1 = Monday).
markedDates
MarkedDates
Collection of dates that need to be marked.
hideArrows
boolean
Hide month navigation arrows.
renderArrow
(direction: 'left' | 'right') => ReactNode
Replace default arrows with custom ones.
onPressArrowLeft
(method: () => void, month?: XDate) => void
Handler for left arrow press.
onPressArrowRight
(method: () => void, month?: XDate) => void
Handler for right arrow press.

Accessibility

testID
string
Test identifier for automated testing.

Positions enum

The component exports a positions enum with the following values:
  • ExpandableCalendar.positions.OPEN - Calendar is fully expanded
  • ExpandableCalendar.positions.CLOSED - Calendar is collapsed to week view

Examples

Basic expandable calendar with CalendarProvider

import { CalendarProvider, ExpandableCalendar } from 'react-native-calendars';
import { useState } from 'react';

function MyExpandableCalendar() {
  const [selected, setSelected] = useState('');

  return (
    <CalendarProvider date={selected || '2023-05-16'}>
      <ExpandableCalendar
        firstDay={1}
        markedDates={{
          [selected]: {selected: true, selectedColor: 'blue'}
        }}
        onDayPress={(day) => setSelected(day.dateString)}
      />
    </CalendarProvider>
  );
}

Expandable calendar with custom theme

<CalendarProvider date="2023-05-16">
  <ExpandableCalendar
    theme={{
      backgroundColor: '#ffffff',
      calendarBackground: '#ffffff',
      selectedDayBackgroundColor: '#00adf5',
      selectedDayTextColor: '#ffffff',
      todayTextColor: '#00adf5',
      dotColor: '#00adf5',
      arrowColor: '#00adf5'
    }}
    firstDay={1}
    markedDates={{
      '2023-05-16': {marked: true, dotColor: 'red'},
      '2023-05-17': {marked: true, dotColor: 'blue'}
    }}
  />
</CalendarProvider>

Calendar starting in open position

<CalendarProvider date="2023-05-16">
  <ExpandableCalendar
    initialPosition={ExpandableCalendar.positions.OPEN}
    onCalendarToggled={(isOpen) => {
      console.log('Calendar toggled:', isOpen);
    }}
  />
</CalendarProvider>

Disabled pan gesture

<CalendarProvider date="2023-05-16">
  <ExpandableCalendar
    disablePan
    initialPosition={ExpandableCalendar.positions.OPEN}
    closeOnDayPress={false}
  />
</CalendarProvider>

Custom arrows and thresholds

<CalendarProvider date="2023-05-16">
  <ExpandableCalendar
    leftArrowImageSource={require('./custom-left.png')}
    rightArrowImageSource={require('./custom-right.png')}
    openThreshold={50}
    closeThreshold={50}
    renderArrow={(direction) => (
      <Text style={{fontSize: 20}}>
        {direction === 'left' ? '◀' : '▶'}
      </Text>
    )}
  />
</CalendarProvider>

With week scroll disabled

<CalendarProvider date="2023-05-16">
  <ExpandableCalendar
    disableWeekScroll
    allowShadow={false}
    hideKnob={true}
  />
</CalendarProvider>

Complete example with AgendaList

import {
  CalendarProvider,
  ExpandableCalendar,
  AgendaList
} from 'react-native-calendars';

function CompleteAgenda() {
  const [selected, setSelected] = useState('2023-05-16');
  const [items, setItems] = useState({
    '2023-05-16': [{name: 'Meeting'}],
    '2023-05-17': [{name: 'Lunch'}]
  });

  return (
    <CalendarProvider date={selected}>
      <ExpandableCalendar
        firstDay={1}
        markedDates={{
          [selected]: {selected: true}
        }}
        onDayPress={(day) => setSelected(day.dateString)}
      />
      <AgendaList
        sections={items}
        renderItem={(item) => (
          <View style={{padding: 20, backgroundColor: 'white'}}>
            <Text>{item.name}</Text>
          </View>
        )}
      />
    </CalendarProvider>
  );
}

Notes

Always wrap ExpandableCalendar with CalendarProvider. The component relies on the context provided by CalendarProvider to function properly.
The knob is automatically hidden when using numberOfDays > 1 in the CalendarProvider.
When using horizontal mode, the calendar will automatically handle month transitions and week scrolling.

Build docs developers (and LLMs) love