UNPKG

20.2 kBMarkdownView Raw
1**LOOKING FOR A MAINTAINER**
2We 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 (levv@wix.com, inbalti@wix.com, ethans@wix.com)
3
4---
5
6
7# React Native Calendars 🗓️ 📆
8[![Version](https://img.shields.io/npm/v/react-native-calendars.svg)](https://www.npmjs.com/package/react-native-calendars)
9[![Build Status](https://travis-ci.org/wix/react-native-calendars.svg?branch=master)](https://travis-ci.org/wix/react-native-calendars)
10
11This module includes various customizable **React-Native** calendar components.
12
13The package is both **Android** and **iOS** compatible.
14
15## Try it out
16
17You can run example module by performing these steps:
18
19```
20$ git clone git@github.com:wix/react-native-calendars.git
21$ npm install
22$ react-native run-ios
23```
24
25You can check example screens source code in [example module screens](https://github.com/wix-private/wix-react-native-calendar/tree/master/example/src/screens)
26
27This project is compatible with Expo/CRNA (without ejecting), and the examples have been [published on Expo](https://expo.io/@community/react-native-calendars-example)
28
29## Installation
30
31```
32$ npm install --save react-native-calendars
33```
34
35The solution is implemented in JavaScript so no native module linking is required.
36
37## Usage
38
39`import {`[Calendar](#calendar), [CalendarList](#calendarlist), [Agenda](#agenda)`} from 'react-native-calendars';`
40
41All parameters for components are optional. By default the month of current local date will be displayed.
42
43Event handler callbacks are called with `calendar objects` like this:
44
45```javasctipt
46{
47 day: 1, // day of month (1-31)
48 month: 1, // month of year (1-12)
49 year: 2017, // year
50 timestamp, // UTC timestamp representing 00:00 AM of this date
51 dateString: '2016-05-13' // date formatted as 'YYYY-MM-DD' string
52}
53```
54
55Parameters that require date types accept `YYYY-MM-DD` formated `date-strings`, JavaScript date objects, `calendar objects` and `UTC timestamps`.
56
57Calendars can be localized by adding custom locales to `LocaleConfig` object:
58
59```javascript
60import {LocaleConfig} from 'react-native-calendars';
61
62LocaleConfig.locales['fr'] = {
63 monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre'],
64 monthNamesShort: ['Janv.','Févr.','Mars','Avril','Mai','Juin','Juil.','Août','Sept.','Oct.','Nov.','Déc.'],
65 dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'],
66 dayNamesShort: ['Dim.','Lun.','Mar.','Mer.','Jeu.','Ven.','Sam.'],
67 today: 'Aujourd\'hui'
68};
69LocaleConfig.defaultLocale = 'fr';
70```
71
72### Calendar
73
74<kbd>
75 <img src="https://github.com/wix-private/wix-react-native-calendar/blob/master/demo/calendar.gif?raw=true">
76</kbd>
77
78#### Basic parameters
79
80```javascript
81<Calendar
82 // Initially visible month. Default = Date()
83 current={'2012-03-01'}
84 // Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined
85 minDate={'2012-05-10'}
86 // Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined
87 maxDate={'2012-05-30'}
88 // Handler which gets executed on day press. Default = undefined
89 onDayPress={(day) => {console.log('selected day', day)}}
90 // Handler which gets executed on day long press. Default = undefined
91 onDayLongPress={(day) => {console.log('selected day', day)}}
92 // Month format in calendar title. Formatting values: http://arshaw.com/xdate/#Formatting
93 monthFormat={'yyyy MM'}
94 // Handler which gets executed when visible month changes in calendar. Default = undefined
95 onMonthChange={(month) => {console.log('month changed', month)}}
96 // Hide month navigation arrows. Default = false
97 hideArrows={true}
98 // Replace default arrows with custom ones (direction can be 'left' or 'right')
99 renderArrow={(direction) => (<Arrow/>)}
100 // Do not show days of other months in month page. Default = false
101 hideExtraDays={true}
102 // If hideArrows=false and hideExtraDays=false do not switch month when tapping on greyed out
103 // day from another month that is visible in calendar page. Default = false
104 disableMonthChange={true}
105 // If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday.
106 firstDay={1}
107 // Hide day names. Default = false
108 hideDayNames={true}
109 // Show week numbers to the left. Default = false
110 showWeekNumbers={true}
111 // Handler which gets executed when press arrow icon left. It receive a callback can go back month
112 onPressArrowLeft={subtractMonth => subtractMonth()}
113 // Handler which gets executed when press arrow icon right. It receive a callback can go next month
114 onPressArrowRight={addMonth => addMonth()}
115 // Disable left arrow. Default = false
116 disableArrowLeft={true}
117 // Disable right arrow. Default = false
118 disableArrowRight={true}
119 // Disable all touch events for disabled days. can be override with disableTouchEvent in markedDates
120 disableAllTouchEventsForDisabledDays={true}
121 // Replace default month and year title with custom one. the function receive a date as parameter.
122 renderHeader={(date) => {/*Return JSX*/}}
123 // Enable the option to swipe between months. Default = false
124 enableSwipeMonths={true}
125/>
126```
127
128#### Date marking
129
130**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.
131
132Dot marking
133
134<kbd>
135 <img height=50 src="https://github.com/wix-private/wix-react-native-calendar/blob/master/demo/marking1.png?raw=true">
136</kbd>
137<p></p>
138
139```javascript
140<Calendar
141 // Collection of dates that have to be marked. Default = {}
142 markedDates={{
143 '2012-05-16': {selected: true, marked: true, selectedColor: 'blue'},
144 '2012-05-17': {marked: true},
145 '2012-05-18': {marked: true, dotColor: 'red', activeOpacity: 0},
146 '2012-05-19': {disabled: true, disableTouchEvent: true}
147 }}
148/>
149```
150
151You can customize a dot color for each day independently.
152
153Multi-Dot marking
154
155<kbd>
156 <img height=50 src="https://github.com/wix-private/wix-react-native-calendar/blob/master/demo/marking4.png?raw=true">
157</kbd>
158<p></p>
159
160Use `markingType={'multi-dot'}` if you want to display more than one dot. Both the `<Calendar/>` and `<CalendarList/>` support multiple dots by using `dots` array in `markedDates` prop.
161The 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.
162
163```javascript
164const vacation = {key:'vacation', color: 'red', selectedDotColor: 'blue'};
165const massage = {key:'massage', color: 'blue', selectedDotColor: 'blue'};
166const workout = {key:'workout', color: 'green'};
167
168<Calendar
169 markedDates={{
170 '2017-10-25': {dots: [vacation, massage, workout], selected: true, selectedColor: 'red'},
171 '2017-10-26': {dots: [massage, workout], disabled: true}
172 }}
173 markingType={'multi-dot'}
174/>
175```
176
177Period marking
178
179<kbd>
180 <img height=50 src="https://github.com/wix-private/wix-react-native-calendar/blob/master/demo/marking2.png?raw=true">
181</kbd>
182
183<kbd>
184 <img height=50 src="https://github.com/wix-private/wix-react-native-calendar/blob/master/demo/marking3.png?raw=true">
185</kbd>
186<p></p>
187
188```javascript
189<Calendar
190 // Collection of dates that have to be colored in a special way. Default = {}
191 markedDates={{
192 '2012-05-20': {textColor: 'green'},
193 '2012-05-22': {startingDay: true, color: 'green'},
194 '2012-05-23': {selected: true, endingDay: true, color: 'green', textColor: 'gray'},
195 '2012-05-04': {disabled: true, startingDay: true, color: 'green', endingDay: true}
196 }}
197 // Date marking style [simple/period/multi-dot/custom]. Default = 'simple'
198 markingType={'period'}
199/>
200```
201
202Multi-period marking
203
204<kbd>
205 <img height=50 src="https://github.com/wix-private/wix-react-native-calendar/blob/master/demo/marking6.png?raw=true">
206</kbd>
207<p></p>
208
209**CAUTION**: This marking is only fully supported by the `<Calendar/>` component because it expands its height. Usage with `<CalendarList/>` might lead to overflow issues.
210
211```javascript
212<Calendar
213 markedDates={{
214 '2017-12-14': {
215 periods: [
216 {startingDay: false, endingDay: true, color: '#5f9ea0'},
217 {startingDay: false, endingDay: true, color: '#ffa500'},
218 {startingDay: true, endingDay: false, color: '#f0e68c'}
219 ]
220 },
221 '2017-12-15': {
222 periods: [
223 {startingDay: true, endingDay: false, color: '#ffa500'},
224 {color: 'transparent'},
225 {startingDay: false, endingDay: false, color: '#f0e68c'}
226 ]
227 }
228 }}
229 // Date marking style [simple/period/multi-dot/custom]. Default = 'simple'
230 markingType='multi-period'
231/>
232```
233
234Custom marking allows you to customize each marker with custom styles.
235
236<kbd>
237 <img height=50 src="https://github.com/wix-private/wix-react-native-calendar/blob/master/demo/custom.png?raw=true">
238</kbd>
239<p></p>
240
241```javascript
242<Calendar
243 // Date marking style [simple/period/multi-dot/single]. Default = 'simple'
244 markingType={'custom'}
245 markedDates={{
246 '2018-03-28': {
247 customStyles: {
248 container: {
249 backgroundColor: 'green'
250 },
251 text: {
252 color: 'black',
253 fontWeight: 'bold'
254 }
255 }
256 },
257 '2018-03-29': {
258 customStyles: {
259 container: {
260 backgroundColor: 'white',
261 elevation: 2
262 },
263 text: {
264 color: 'blue'
265 }
266 }
267 }
268 }}
269/>
270```
271
272**NEW!** While we still don't support multi marking type, we add the possibility to combine between `period` and `simple`.
273```javascript
274<Calendar
275 markingType={'period'}
276 markedDates={{
277 '2012-05-15': {marked: true, dotColor: '#50cebb'},
278 '2012-05-16': {marked: true, dotColor: '#50cebb'},
279 '2012-05-21': {startingDay: true, color: '#50cebb', textColor: 'white'},
280 '2012-05-22': {color: '#70d7c7', textColor: 'white'},
281 '2012-05-23': {color: '#70d7c7', textColor: 'white', marked: true, dotColor: 'white'},
282 '2012-05-24': {color: '#70d7c7', textColor: 'white'},
283 '2012-05-25': {endingDay: true, color: '#50cebb', textColor: 'white'},
284 }}
285/>
286```
287<kbd>
288 <img height=350 src="https://github.com/wix-private/wix-react-native-calendar/blob/master/demo/multi-marking.png?raw=true">
289</kbd>
290<p></p>
291
292Keep in mind that different marking types are not compatible. You can use just one marking style for a calendar.
293
294#### Displaying data loading indicator
295
296<kbd>
297 <img height=50 src="https://github.com/wix-private/wix-react-native-calendar/blob/master/demo/loader.png?raw=true">
298</kbd>
299<p></p>
300
301The loading indicator next to the month name will be displayed if `<Calendar/>` 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.
302
303#### Customizing look & feel
304
305```javascript
306<Calendar
307 // Specify style for calendar container element. Default = {}
308 style={{
309 borderWidth: 1,
310 borderColor: 'gray',
311 height: 350
312 }}
313 // Specify theme properties to override specific styles for calendar parts. Default = {}
314 theme={{
315 backgroundColor: '#ffffff',
316 calendarBackground: '#ffffff',
317 textSectionTitleColor: '#b6c1cd',
318 textSectionTitleDisabledColor: '#d9e1e8',
319 selectedDayBackgroundColor: '#00adf5',
320 selectedDayTextColor: '#ffffff',
321 todayTextColor: '#00adf5',
322 dayTextColor: '#2d4150',
323 textDisabledColor: '#d9e1e8',
324 dotColor: '#00adf5',
325 selectedDotColor: '#ffffff',
326 arrowColor: 'orange',
327 disabledArrowColor: '#d9e1e8',
328 monthTextColor: 'blue',
329 indicatorColor: 'blue',
330 textDayFontFamily: 'monospace',
331 textMonthFontFamily: 'monospace',
332 textDayHeaderFontFamily: 'monospace',
333 textDayFontWeight: '300',
334 textMonthFontWeight: 'bold',
335 textDayHeaderFontWeight: '300',
336 textDayFontSize: 16,
337 textMonthFontSize: 16,
338 textDayHeaderFontSize: 16
339 }}
340/>
341```
342#### Customize days titles with disabled styling
343```javascript
344<Calendar
345 theme={{
346 textSectionTitleDisabledColor: '#d9e1e8'
347 }}
348 disabledDaysIndexes={[0, 6]}
349 markedDates={{
350 ...this.getDisabledDates('2012-05-01', '2012-05-30', [0, 6])
351 }}
352/>
353```
354
355#### Advanced styling
356
357If 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 `<CalendarHeader/>` style first you have to find stylesheet id for this file:
358
359https://github.com/wix/react-native-calendars/blob/master/src/calendar/header/style.js#L4
360
361In this case it is `stylesheet.calendar.header`. Next you can add overriding stylesheet to your theme with this id.
362
363https://github.com/wix/react-native-calendars/blob/master/example/src/screens/calendars.js#L56
364
365```javascript
366theme={{
367 arrowColor: 'white',
368 'stylesheet.calendar.header': {
369 week: {
370 marginTop: 5,
371 flexDirection: 'row',
372 justifyContent: 'space-between'
373 }
374 }
375}}
376```
377
378**Disclaimer**: Issues that arise because something breaks after using stylesheet override will not be supported. Use this option at your own risk.
379
380#### Overriding day component
381
382If you need custom functionality not supported by current day component implementations you can pass your own custom day component to the calendar.
383
384```javascript
385<Calendar
386 style={[styles.calendar, {height: 300}]}
387 dayComponent={({date, state}) => {
388 return (
389 <View>
390 <Text style={{textAlign: 'center', color: state === 'disabled' ? 'gray' : 'black'}}>
391 {date.day}
392 </Text>
393 </View>
394 );
395 }}
396/>
397```
398
399The `dayComponent` prop has to receive a RN component or a function that receive props. The `dayComponent` will receive such props:
400
401* state - disabled if the day should be disabled (this is decided by base calendar component).
402* marking - `markedDates` value for this day.
403* date - the date object representing this day.
404
405**Tip**: Don't forget to implement `shouldComponentUpdate()` for your custom day component to make the calendar perform better
406
407If you implement an awesome day component please make a PR so that other people could use it :)
408
409### CalendarList
410
411<kbd>
412 <img src="https://github.com/wix-private/wix-react-native-calendar/blob/master/demo/calendar-list.gif?raw=true">
413</kbd>
414<p></p>
415
416`<CalendarList/>` is scrollable semi-infinite calendar composed of `<Calendar/>` components. Currently it is possible to scroll 4 years back and 4 years to the future. All parameters that are available for `<Calendar/>` are also available for this component. There are also some additional params that can be used:
417
418```javascript
419<CalendarList
420 // Callback which gets executed when visible months change in scroll view. Default = undefined
421 onVisibleMonthsChange={(months) => {console.log('now these months are visible', months);}}
422 // Max amount of months allowed to scroll to the past. Default = 50
423 pastScrollRange={50}
424 // Max amount of months allowed to scroll to the future. Default = 50
425 futureScrollRange={50}
426 // Enable or disable scrolling of calendar list
427 scrollEnabled={true}
428 // Enable or disable vertical scroll indicator. Default = false
429 showScrollIndicator={true}
430 ...calendarParams
431/>
432```
433
434#### Horizontal CalendarList
435
436<kbd>
437 <img src="https://github.com/wix-private/wix-react-native-calendar/blob/master/demo/horizontal-calendar-list.gif?raw=true">
438</kbd>
439<p></p>
440
441You can also make the `CalendarList` scroll horizontally. To do that you need to pass specific props to the `CalendarList`:
442
443```javascript
444<CalendarList
445 // Enable horizontal scrolling, default = false
446 horizontal={true}
447 // Enable paging on horizontal, default = false
448 pagingEnabled={true}
449 // Set custom calendarWidth.
450 calendarWidth={320}
451 ...calendarListParams
452 ...calendarParams
453/>
454```
455
456### Agenda
457<kbd>
458 <img src="https://github.com/wix-private/wix-react-native-calendar/blob/master/demo/agenda.gif?raw=true">
459</kbd>
460<p></p>
461
462An advanced `Agenda` component that can display interactive listings for calendar day items.
463
464```javascript
465<Agenda
466 // The list of items that have to be displayed in agenda. If you want to render item as empty date
467 // the value of date key has to be an empty array []. If there exists no value for date key it is
468 // considered that the date in question is not yet loaded
469 items={{
470 '2012-05-22': [{name: 'item 1 - any js object'}],
471 '2012-05-23': [{name: 'item 2 - any js object', height: 80}],
472 '2012-05-24': [],
473 '2012-05-25': [{name: 'item 3 - any js object'}, {name: 'any js object'}]
474 }}
475 // Callback that gets called when items for a certain month should be loaded (month became visible)
476 loadItemsForMonth={(month) => {console.log('trigger items loading')}}
477 // Callback that fires when the calendar is opened or closed
478 onCalendarToggled={(calendarOpened) => {console.log(calendarOpened)}}
479 // Callback that gets called on day press
480 onDayPress={(day)=>{console.log('day pressed')}}
481 // Callback that gets called when day changes while scrolling agenda list
482 onDayChange={(day)=>{console.log('day changed')}}
483 // Initially selected day
484 selected={'2012-05-16'}
485 // Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined
486 minDate={'2012-05-10'}
487 // Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined
488 maxDate={'2012-05-30'}
489 // Max amount of months allowed to scroll to the past. Default = 50
490 pastScrollRange={50}
491 // Max amount of months allowed to scroll to the future. Default = 50
492 futureScrollRange={50}
493 // Specify how each item should be rendered in agenda
494 renderItem={(item, firstItemInDay) => {return (<View />);}}
495 // Specify how each date should be rendered. day can be undefined if the item is not first in that day.
496 renderDay={(day, item) => {return (<View />);}}
497 // Specify how empty date content with no items should be rendered
498 renderEmptyDate={() => {return (<View />);}}
499 // Specify how agenda knob should look like
500 renderKnob={() => {return (<View />);}}
501 // Specify what should be rendered instead of ActivityIndicator
502 renderEmptyData = {() => {return (<View />);}}
503 // Specify your item comparison function for increased performance
504 rowHasChanged={(r1, r2) => {return r1.text !== r2.text}}
505 // Hide knob button. Default = false
506 hideKnob={true}
507 // By default, agenda dates are marked if they have at least one item, but you can override this if needed
508 markedDates={{
509 '2012-05-16': {selected: true, marked: true},
510 '2012-05-17': {marked: true},
511 '2012-05-18': {disabled: true}
512 }}
513 // If disabledByDefault={true} dates flagged as not disabled will be enabled. Default = false
514 disabledByDefault={true}
515 // If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the refreshing prop correctly.
516 onRefresh={() => console.log('refreshing...')}
517 // Set this true while waiting for new data from a refresh
518 refreshing={false}
519 // Add a custom RefreshControl component, used to provide pull-to-refresh functionality for the ScrollView.
520 refreshControl={null}
521 // Agenda theme
522 theme={{
523 ...calendarTheme,
524 agendaDayTextColor: 'yellow',
525 agendaDayNumColor: 'green',
526 agendaTodayColor: 'red',
527 agendaKnobColor: 'blue'
528 }}
529 // Agenda container style
530 style={{}}
531/>
532```
533
534## Authors
535
536* [Tautvilas Mecinskas](https://github.com/tautvilas/) - Initial code - [@tautvilas](https://twitter.com/Tautvilas)
537* Katrin Zotchev - Initial design - [@katrin_zot](https://twitter.com/katrin_zot)
538
539See also the list of [contributors](https://github.com/wix/react-native-calendar-components/contributors) who participated in this project.
540
541## Contributing
542
543Pull requests are most welcome!
544Please `npm run test` and `npm run lint` before push.
545Don'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.
\No newline at end of file