react-native-calendars

by wix

React Native Calendar Components 🗓️ 📆

6.0K Stars 1.9K Forks Last release: over 2 years ago (v1.17.0) MIT License 1.2K Commits 461 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

LOOKING FOR A MAINTAINER We love this project, but currently we don’t have enough time to work on it. So we are looking for a maintainer. If you have enough time and knowledge and want to become one - please let us know ([email protected], [email protected], [email protected])


React Native Calendars 🗓️ 📆

Version Build Status

This module includes various customizable React-Native calendar components.

The package is both Android and iOS compatible.

Try it out

You can run example module by performing these steps:

$ git clone [email protected]:wix/react-native-calendars.git
$ npm install
$ react-native run-ios

You can check example screens source code in example module screens

This project is compatible with Expo/CRNA (without ejecting), and the examples have been published on Expo

Installation

$ npm install --save react-native-calendars

The solution is implemented in JavaScript so no native module linking is required.

Usage

import {
Calendar, CalendarList, Agenda
} from 'react-native-calendars';

All parameters for components are optional. By default the month of current local date will be displayed.

Event handler callbacks are called with

calendar objects
like this:
{
  day: 1,      // day of month (1-31)
  month: 1,    // month of year (1-12)
  year: 2017,  // year
  timestamp,   // UTC timestamp representing 00:00 AM of this date
  dateString: '2016-05-13' // date formatted as 'YYYY-MM-DD' string
}

Parameters that require date types accept

YYYY-MM-DD
formated
date-strings
, JavaScript date objects,
calendar objects
and
UTC timestamps
.

Calendars can be localized by adding custom locales to

LocaleConfig
object:
import {LocaleConfig} from 'react-native-calendars';

LocaleConfig.locales['fr'] = { monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre'], monthNamesShort: ['Janv.','Févr.','Mars','Avril','Mai','Juin','Juil.','Août','Sept.','Oct.','Nov.','Déc.'], dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], dayNamesShort: ['Dim.','Lun.','Mar.','Mer.','Jeu.','Ven.','Sam.'], today: 'Aujourd'hui' }; LocaleConfig.defaultLocale = 'fr';

Calendar

Basic parameters

 {console.log('selected day', day)}}
  // Handler which gets executed on day long press. Default = undefined
  onDayLongPress={(day) => {console.log('selected day', day)}}
  // Month format in calendar title. Formatting values: http://arshaw.com/xdate/#Formatting
  monthFormat={'yyyy MM'}
  // Handler which gets executed when visible month changes in calendar. Default = undefined
  onMonthChange={(month) => {console.log('month changed', month)}}
  // Hide month navigation arrows. Default = false
  hideArrows={true}
  // Replace default arrows with custom ones (direction can be 'left' or 'right')
  renderArrow={(direction) => ()}
  // Do not show days of other months in month page. Default = false
  hideExtraDays={true}
  // If hideArrows=false and hideExtraDays=false do not switch month when tapping on greyed out
  // day from another month that is visible in calendar page. Default = false
  disableMonthChange={true}
  // If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday.
  firstDay={1}
  // Hide day names. Default = false
  hideDayNames={true}
  // Show week numbers to the left. Default = false
  showWeekNumbers={true}
  // Handler which gets executed when press arrow icon left. It receive a callback can go back month
  onPressArrowLeft={subtractMonth => subtractMonth()}
  // Handler which gets executed when press arrow icon right. It receive a callback can go next month
  onPressArrowRight={addMonth => addMonth()}
  // Disable left arrow. Default = false
  disableArrowLeft={true}
  // Disable right arrow. Default = false
  disableArrowRight={true}
  // Disable all touch events for disabled days. can be override with disableTouchEvent in markedDates
  disableAllTouchEventsForDisabledDays={true}
  // Replace default month and year title with custom one. the function receive a date as parameter.
  renderHeader={(date) => {/*Return JSX*/}}
  // Enable the option to swipe between months. Default = false
  enableSwipeMonths={true}
/>

Date marking

Disclaimer: Make sure that

markedDates
param is immutable. If you change
markedDates
object content but the reference to it does not change calendar update will not be triggered.

Dot marking


You can customize a dot color for each day independently.

Multi-Dot marking

Use

markingType={'multi-dot'}
if you want to display more than one dot. Both the
 and 
 support multiple dots by using 
dots
array in
markedDates
prop. The property
color
is mandatory while
key
and
selectedColor
are optional. If key is omitted then the array index is used as key. If
selectedColor
is omitted then
color
will be used for selected dates.
const vacation = {key:'vacation', color: 'red', selectedDotColor: 'blue'};
const massage = {key:'massage', color: 'blue', selectedDotColor: 'blue'};
const workout = {key:'workout', color: 'green'};

Period marking


Multi-period marking

CAUTION: This marking is only fully supported by the

 component because it expands its height. Usage with 
 might lead to overflow issues.

Custom marking allows you to customize each marker with custom styles.


NEW! While we still don't support multi marking type, we add the possibility to combine between

period
and
simple
.
javascript

Keep in mind that different marking types are not compatible. You can use just one marking style for a calendar.

Displaying data loading indicator

The loading indicator next to the month name will be displayed if

 has 
displayLoadingIndicator
prop and the
markedDates
collection does not have a value for every day of the month in question. When you load data for days, just set
[]
or special marking value to all days in
markedDates
collection.

Customizing look & feel


Customize days titles with disabled styling


Advanced styling

If you want to have complete control over the calendar styles you can do it by overriding default

style.js
files. For example, if you want to override
 style first you have to find stylesheet id for this file:

https://github.com/wix/react-native-calendars/blob/master/src/calendar/header/style.js#L4

In this case it is

stylesheet.calendar.header
. Next you can add overriding stylesheet to your theme with this id.

https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendars.js#L56

theme={{
  arrowColor: 'white',
  'stylesheet.calendar.header': {
    week: {
      marginTop: 5,
      flexDirection: 'row',
      justifyContent: 'space-between'
    }
  }
}}

Disclaimer: Issues that arise because something breaks after using stylesheet override will not be supported. Use this option at your own risk.

Overriding day component

If you need custom functionality not supported by current day component implementations you can pass your own custom day component to the calendar.

 {
    return (
      
        
          {date.day}
        
      
    );
  }}
/>

The

dayComponent
prop has to receive a RN component or a function that receive props. The
dayComponent
will receive such props:
  • state - disabled if the day should be disabled (this is decided by base calendar component).
  • marking -
    markedDates
    value for this day.
  • date - the date object representing this day.

Tip: Don't forget to implement

shouldComponentUpdate()
for your custom day component to make the calendar perform better

If you implement an awesome day component please make a PR so that other people could use it :)

CalendarList

 is scrollable semi-infinite calendar composed of 
 components. Currently it is possible to scroll 4 years back and 4 years to the future. All parameters that are available for 
 are also available for this component. There are also some additional params that can be used:
 {console.log('now these months are visible', months);}}
  // Max amount of months allowed to scroll to the past. Default = 50
  pastScrollRange={50}
  // Max amount of months allowed to scroll to the future. Default = 50
  futureScrollRange={50}
  // Enable or disable scrolling of calendar list
  scrollEnabled={true}
  // Enable or disable vertical scroll indicator. Default = false
  showScrollIndicator={true}
  ...calendarParams
/>

Horizontal CalendarList

You can also make the

CalendarList
scroll horizontally. To do that you need to pass specific props to the
CalendarList
:

Agenda

An advanced

Agenda
component that can display interactive listings for calendar day items.
 {console.log('trigger items loading')}}
  // Callback that fires when the calendar is opened or closed
  onCalendarToggled={(calendarOpened) => {console.log(calendarOpened)}}
  // Callback that gets called on day press
  onDayPress={(day)=>{console.log('day pressed')}}
  // Callback that gets called when day changes while scrolling agenda list
  onDayChange={(day)=>{console.log('day changed')}}
  // Initially selected day
  selected={'2012-05-16'}
  // Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined
  minDate={'2012-05-10'}
  // Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined
  maxDate={'2012-05-30'}
  // Max amount of months allowed to scroll to the past. Default = 50
  pastScrollRange={50}
  // Max amount of months allowed to scroll to the future. Default = 50
  futureScrollRange={50}
  // Specify how each item should be rendered in agenda
  renderItem={(item, firstItemInDay) => {return ();}}
  // Specify how each date should be rendered. day can be undefined if the item is not first in that day.
  renderDay={(day, item) => {return ();}}
  // Specify how empty date content with no items should be rendered
  renderEmptyDate={() => {return ();}}
  // Specify how agenda knob should look like
  renderKnob={() => {return ();}}
  // Specify what should be rendered instead of ActivityIndicator
  renderEmptyData = {() => {return ();}}
  // Specify your item comparison function for increased performance
  rowHasChanged={(r1, r2) => {return r1.text !== r2.text}}
  // Hide knob button. Default = false
  hideKnob={true}
  // By default, agenda dates are marked if they have at least one item, but you can override this if needed
  markedDates={{
    '2012-05-16': {selected: true, marked: true},
    '2012-05-17': {marked: true},
    '2012-05-18': {disabled: true}
  }}
  // If disabledByDefault={true} dates flagged as not disabled will be enabled. Default = false
  disabledByDefault={true}
  // If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the refreshing prop correctly.
  onRefresh={() => console.log('refreshing...')}
  // Set this true while waiting for new data from a refresh
  refreshing={false}
  // Add a custom RefreshControl component, used to provide pull-to-refresh functionality for the ScrollView.
  refreshControl={null}
  // Agenda theme
  theme={{
    ...calendarTheme,
    agendaDayTextColor: 'yellow',
    agendaDayNumColor: 'green',
    agendaTodayColor: 'red',
    agendaKnobColor: 'blue'
  }}
  // Agenda container style
  style={{}}
/>

Authors

See also the list of contributors who participated in this project.

Contributing

Pull requests are most welcome! Please

npm run test
and
npm run lint
before push. Don't forget to add a title and a description that explain the issue you're trying to solve and your suggested solution. Screenshots and gifs are very helpful.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.