Skip to main content
The Agenda component combines a CalendarList with a reservation list, providing an interactive calendar view with expandable/collapsible agenda items.

Basic usage

import { Agenda } from 'react-native-calendars';

<Agenda
  items={{
    '2023-05-22': [{name: 'item 1 - any js object'}],
    '2023-05-23': [{name: 'item 2 - any js object'}]
  }}
  renderItem={(item) => <Text>{item.name}</Text>}
/>

Props

Agenda extends both CalendarList and ReservationList props.

Data configuration

items
AgendaSchedule
The list of items to display in the agenda. If you want to render an item as an empty date, the value must be an empty array []. If no value exists for a date key, it’s considered not yet loaded.
{
  '2023-05-22': [{name: 'item 1', height: 80, day: '2023-05-22'}],
  '2023-05-23': [],  // Empty day
  '2023-05-24': [{name: 'item 2', height: 80, day: '2023-05-24'}]
}
selected
string
Initially selected day in YYYY-MM-DD format.

Loading and data management

loadItemsForMonth
(date: DateData) => void
Callback that gets called when items for a certain month should be loaded (month became visible).
loadItemsForMonth={(month) => {
  console.log('Loading items for', month);
  // Load items for this month
}}
refreshing
boolean
Set this to true while waiting for new data from a refresh.
onRefresh
() => void
If provided, a standard RefreshControl will be added for pull-to-refresh functionality.
refreshControl
JSX.Element
A RefreshControl component for custom pull-to-refresh functionality.

Event handlers

onDayPress
(date: DateData) => void
Handler which gets executed on day press.
onDayChange
(date: DateData) => void
Callback that gets called when the selected day changes while scrolling the agenda list.
onDayChange={(day) => {
  console.log('Day changed to:', day.dateString);
}}
onCalendarToggled
(enabled: boolean) => void
Callback that fires when the calendar is opened or closed.
onCalendarToggled={(isOpen) => {
  console.log('Calendar is', isOpen ? 'open' : 'closed');
}}

Scroll handlers

onScroll
(yOffset: number) => void
Called on scroll event with the current y offset.
onScrollBeginDrag
(event: NativeSyntheticEvent<NativeScrollEvent>) => void
Called when the user begins dragging the agenda list.
onScrollEndDrag
(event: NativeSyntheticEvent<NativeScrollEvent>) => void
Called when the user stops dragging the agenda list.
onMomentumScrollBegin
(event: NativeSyntheticEvent<NativeScrollEvent>) => void
Called when momentum scroll starts.
onMomentumScrollEnd
(event: NativeSyntheticEvent<NativeScrollEvent>) => void
Called when momentum scroll stops.

Rendering customization

renderItem
(reservation: AgendaEntry, isFirst: boolean) => JSX.Element
Specify how each agenda item should be rendered.
renderItem={(item, isFirst) => (
  <View style={{padding: 10}}>
    <Text>{item.name}</Text>
    <Text>{item.height}</Text>
  </View>
)}
renderDay
(date?: XDate, item?: AgendaEntry) => JSX.Element
Specify how each date should be rendered. Date can be undefined if the item is not the first in that day.
renderDay={(day) => (
  <View>
    <Text>{day.getDay()}</Text>
    <Text>{day.getMonth()}</Text>
  </View>
)}
renderEmptyDate
(date?: XDate) => JSX.Element
Specify how empty date content with no items should be rendered.
renderEmptyDate={() => (
  <View style={{padding: 20}}>
    <Text>No events</Text>
  </View>
)}
renderEmptyData
() => JSX.Element
Specify what should be rendered instead of ActivityIndicator when loading.
renderKnob
() => JSX.Element
Specify how the agenda knob should look like.
renderKnob={() => (
  <View style={{width: 40, height: 4, backgroundColor: 'gray'}} />
)}
renderList
(listProps: ReservationListProps) => JSX.Element
Override the inner list with a custom implemented component.

Display options

hideKnob
boolean
default:"false"
Hide the knob button that allows expanding/collapsing the calendar.
showClosingKnob
boolean
Whether the knob should always be visible (when hideKnob = false).
showOnlySelectedDayItems
boolean
default:"false"
Show items only for the selected date.

Data comparison

rowHasChanged
(a: AgendaEntry, b: AgendaEntry) => boolean
Specify your item comparison function for increased performance.
rowHasChanged={(r1, r2) => r1.name !== r2.name}
reservationsKeyExtractor
(item: DayAgenda, index: number) => string
Extractor for the underlying FlatList. Ensure this is unique per item to avoid scrolling issues.

Styling

theme
Theme
Specify theme properties to override specific styles.
{
  agendaDayTextColor: 'yellow',
  agendaDayNumColor: 'green',
  agendaTodayColor: 'red',
  agendaKnobColor: 'blue'
}
style
ViewStyle
Style for the agenda container.
testID
string
Test identifier for automated testing.

Examples

Basic agenda with items

import { Agenda } from 'react-native-calendars';
import { useState } from 'react';

function MyAgenda() {
  const [items, setItems] = useState({
    '2023-05-22': [{name: 'Meeting', height: 50}],
    '2023-05-23': [{name: 'Lunch', height: 50}],
    '2023-05-24': []
  });

  return (
    <Agenda
      items={items}
      loadItemsForMonth={(month) => {
        console.log('Load items for', month);
      }}
      renderItem={(item) => (
        <View style={{padding: 20, backgroundColor: 'white', margin: 10}}>
          <Text>{item.name}</Text>
        </View>
      )}
      renderEmptyDate={() => (
        <View style={{padding: 20}}>
          <Text>No events scheduled</Text>
        </View>
      )}
    />
  );
}

Agenda with custom theme

<Agenda
  items={items}
  theme={{
    agendaDayTextColor: '#7a7a7a',
    agendaDayNumColor: '#7a7a7a',
    agendaTodayColor: 'red',
    agendaKnobColor: '#00adf5',
    dotColor: '#00adf5',
    selectedDayBackgroundColor: '#00adf5',
    todayTextColor: '#00adf5'
  }}
  renderItem={(item) => (
    <View style={{backgroundColor: 'white', padding: 10, margin: 5}}>
      <Text>{item.name}</Text>
    </View>
  )}
/>

Agenda with pull-to-refresh

import { useState } from 'react';

function RefreshableAgenda() {
  const [items, setItems] = useState({});
  const [refreshing, setRefreshing] = useState(false);

  const loadItems = () => {
    setRefreshing(true);
    // Fetch new items...
    setTimeout(() => {
      setItems({
        '2023-05-22': [{name: 'Updated item'}]
      });
      setRefreshing(false);
    }, 1000);
  };

  return (
    <Agenda
      items={items}
      refreshing={refreshing}
      onRefresh={loadItems}
      renderItem={(item) => (
        <View style={{padding: 20}}>
          <Text>{item.name}</Text>
        </View>
      )}
    />
  );
}

Agenda with custom knob and day rendering

<Agenda
  items={items}
  renderKnob={() => (
    <View style={{
      width: 50,
      height: 5,
      borderRadius: 3,
      backgroundColor: '#00adf5',
      marginTop: 10
    }} />
  )}
  renderDay={(day, item) => (
    <View style={{padding: 10, backgroundColor: '#f0f0f0'}}>
      <Text style={{fontWeight: 'bold'}}>{day?.toString('ddd')}</Text>
      <Text>{day?.getDate()}</Text>
    </View>
  )}
  renderItem={(item) => (
    <View style={{padding: 20, backgroundColor: 'white'}}>
      <Text>{item.name}</Text>
    </View>
  )}
/>

Notes

The items object should use date strings in YYYY-MM-DD format as keys. Each item in the array should have a height property for proper list rendering.
The loadItemsForMonth callback is only called for months that don’t have items loaded yet. Make sure to populate the items object with data for the requested month.

Build docs developers (and LLMs) love