From 849dec81dab9be2d424457bc6129db00a3ba05ba Mon Sep 17 00:00:00 2001 From: varunon9 Date: Sun, 24 Feb 2019 14:38:17 +0530 Subject: [PATCH 1/8] feature: support for horizontal calendar --- src/calendar/index.js | 16 ++++++++++++++-- src/interface.js | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/calendar/index.js b/src/calendar/index.js index c11c0ea4a..617ca31d1 100644 --- a/src/calendar/index.js +++ b/src/calendar/index.js @@ -1,7 +1,8 @@ import React, {Component} from 'react'; import { View, - ViewPropTypes + ViewPropTypes, + ScrollView } from 'react-native'; import PropTypes from 'prop-types'; @@ -186,6 +187,7 @@ class Calendar extends Component { onLongPress={this.longPressDay} date={xdateToData(day)} marking={this.getDateMarking(day)} + horizontal={this.props.horizontal} > {date} @@ -282,8 +284,18 @@ class Calendar extends Component { onPressArrowLeft={this.props.onPressArrowLeft} onPressArrowRight={this.props.onPressArrowRight} headerData={this.props.headerData} + horizontal={this.props.horizontal} /> - {weeks} + { + this.props.horizontal ? + + {weeks} + + : {weeks} + } ); } } diff --git a/src/interface.js b/src/interface.js index d4b8513ad..525b8c4ab 100644 --- a/src/interface.js +++ b/src/interface.js @@ -13,6 +13,7 @@ function xdateToData(xdate) { year: xdate.getFullYear(), month: xdate.getMonth() + 1, day: xdate.getDate(), + weekDay: xdate.getDay(), timestamp: XDate(dateString, true).getTime(), dateString: dateString }; From 47be60c5c8bed7ab6e74851153a350106999ba2f Mon Sep 17 00:00:00 2001 From: varunon9 Date: Sun, 24 Feb 2019 19:18:45 +0530 Subject: [PATCH 2/8] feature: horizontal calendar- added list and grid view click handler --- src/calendar/index.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/calendar/index.js b/src/calendar/index.js index 617ca31d1..5fc672415 100644 --- a/src/calendar/index.js +++ b/src/calendar/index.js @@ -80,7 +80,11 @@ class Calendar extends Component { // Provide custom calendar header rendering component calendarHeaderComponent: PropTypes.any, // data which is passed to calendar header, useful only when implementing custom calendar header - headerData: PropTypes.object + headerData: PropTypes.object, + // Handler which gets executed when press list icon. It will set calendar to horizontal + onPressListView: PropTypes.func, + // Handler which gets executed when press grid icon. It will set calendar to grid + onPressGridView: PropTypes.func, }; constructor(props) { @@ -285,6 +289,8 @@ class Calendar extends Component { onPressArrowRight={this.props.onPressArrowRight} headerData={this.props.headerData} horizontal={this.props.horizontal} + onPressListView={this.props.onPressListView} + onPressGridView={this.props.onPressGridView} /> { this.props.horizontal ? From 7cf3f93022aee5c6a778050f648020f7e24de947 Mon Sep 17 00:00:00 2001 From: varunon9 Date: Sun, 24 Feb 2019 23:46:50 +0530 Subject: [PATCH 3/8] feature: horizontal calendar- auto horizontal calendar scroll to keep selected date visible --- src/calendar/index.js | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/calendar/index.js b/src/calendar/index.js index 5fc672415..f27acd421 100644 --- a/src/calendar/index.js +++ b/src/calendar/index.js @@ -2,7 +2,8 @@ import React, {Component} from 'react'; import { View, ViewPropTypes, - ScrollView + ScrollView, + Dimensions } from 'react-native'; import PropTypes from 'prop-types'; @@ -23,6 +24,9 @@ const viewPropTypes = ViewPropTypes || View.propTypes; const EmptyArray = []; +// horizontal calendar will be scrolled to (offset * viewport width) to keep selected date visible +let horizontalScrollViewOffset = 0; + class Calendar extends Component { static propTypes = { // Specify theme properties to override specific styles for calendar parts. Default = {} @@ -105,6 +109,8 @@ class Calendar extends Component { this.pressDay = this.pressDay.bind(this); this.longPressDay = this.longPressDay.bind(this); this.shouldComponentUpdate = shouldComponentUpdate; + + this.horizontalScrollViewRef = React.createRef(); } componentWillReceiveProps(nextProps) { @@ -116,6 +122,18 @@ class Calendar extends Component { } } + // scroll the horizontal calendar so that selected date is visible + componentDidUpdate() { + const horizontalScrollView = this.horizontalScrollViewRef.current; + if (horizontalScrollView) { + const windowWidth = Dimensions.get('window').width; + horizontalScrollView.scrollTo({ + x: horizontalScrollViewOffset * windowWidth, + animated: true + }); + } + } + updateMonth(day, doNotTriggerListeners) { if (day.toString('yyyy MM') === this.state.currentMonth.toString('yyyy MM')) { return; @@ -192,6 +210,7 @@ class Calendar extends Component { date={xdateToData(day)} marking={this.getDateMarking(day)} horizontal={this.props.horizontal} + current={this.props.current} > {date} @@ -238,6 +257,11 @@ class Calendar extends Component { const week = []; days.forEach((day, id2) => { week.push(this.renderDay(day, id2)); + + // if day is selected (aka current) day then corresponding week row id will be offset + if (day.getTime() === parseDate(this.props.current).getTime()) { + horizontalScrollViewOffset = id; + } }, this); if (this.props.showWeekNumbers) { @@ -297,6 +321,7 @@ class Calendar extends Component { {weeks} From 473a71cb17b5249290b9f10c07941da0b3c88adb Mon Sep 17 00:00:00 2001 From: varunon9 Date: Mon, 25 Feb 2019 01:54:58 +0530 Subject: [PATCH 4/8] feature: horizontal calendar- added horizontal prop-types --- README.md | 4 ++++ src/calendar/index.js | 12 +++++++++--- src/calendar/updater.js | 7 +++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2697be123..322d96490 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +A calendar built by customizing react-native-calendars to support grid as well as list view. + +Read the whole story here: https://medium.com/@varunon9/how-i-built-horizontal-as-well-as-grid-calendar-in-react-native-using-react-native-calendars-eb7a2edcc5db + # React Native Calendars ✨ 🗓️ 📆 [![Version](https://img.shields.io/npm/v/react-native-calendars.svg)](https://www.npmjs.com/package/react-native-calendars) diff --git a/src/calendar/index.js b/src/calendar/index.js index f27acd421..434f63793 100644 --- a/src/calendar/index.js +++ b/src/calendar/index.js @@ -89,6 +89,8 @@ class Calendar extends Component { onPressListView: PropTypes.func, // Handler which gets executed when press grid icon. It will set calendar to grid onPressGridView: PropTypes.func, + // to show horizontal calendar with scroll + horizontal: PropTypes.bool }; constructor(props) { @@ -101,7 +103,8 @@ class Calendar extends Component { currentMonth = XDate(); } this.state = { - currentMonth + currentMonth, + horizontal: props.horizontal }; this.updateMonth = this.updateMonth.bind(this); @@ -120,6 +123,9 @@ class Calendar extends Component { currentMonth: current.clone() }); } + this.setState({ + horizontal: nextProps.horizontal + }); } // scroll the horizontal calendar so that selected date is visible @@ -317,9 +323,9 @@ class Calendar extends Component { onPressGridView={this.props.onPressGridView} /> { - this.props.horizontal ? + this.state.horizontal ? diff --git a/src/calendar/updater.js b/src/calendar/updater.js index 366881ec9..e939fc06b 100644 --- a/src/calendar/updater.js +++ b/src/calendar/updater.js @@ -46,6 +46,13 @@ export default function shouldComponentUpdate(nextProps, nextState) { field: 'current' }; } + + if (nextState.horizontal !== this.state.horizontal) { + shouldUpdate = { + update: true, + field: 'horizontal' + }; + } //console.log(shouldUpdate.field, shouldUpdate.update); return shouldUpdate.update; } From aab7b8434c4b329e107b0dc761d8c66b41288036 Mon Sep 17 00:00:00 2001 From: varunon9 Date: Sun, 17 Mar 2019 08:44:15 +0530 Subject: [PATCH 5/8] feature: horizontal calendar- support for blocking past dates, auto-scroll --- src/calendar/index.js | 76 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/src/calendar/index.js b/src/calendar/index.js index 434f63793..61e19ba07 100644 --- a/src/calendar/index.js +++ b/src/calendar/index.js @@ -90,7 +90,17 @@ class Calendar extends Component { // Handler which gets executed when press grid icon. It will set calendar to grid onPressGridView: PropTypes.func, // to show horizontal calendar with scroll - horizontal: PropTypes.bool + horizontal: PropTypes.bool, + // to automatically scroll horizontal calendar to keep selected date in view + autoHorizontalScroll: PropTypes.bool, + // to show days in horizontal calendar starting from today, if this is true- autoHorizontalScroll will not work + hidePastDatesInHorizontal: PropTypes.bool, + // offset to decide when to trigger onPressArrowRight in horizontal calendar, + // 0 means when rightmost day is reached, undefined means no auto onPressArrowRight triggering + horizontalEndReachedThreshold: PropTypes.number, + // offset to decide when to trigger onPressArrowLeft in horizontal calendar, + // 0 means when leftmost day is reached, undefined means no auto onPressArrowLeft triggering + horizontalStartReachedThreshold: PropTypes.number }; constructor(props) { @@ -112,7 +122,8 @@ class Calendar extends Component { this.pressDay = this.pressDay.bind(this); this.longPressDay = this.longPressDay.bind(this); this.shouldComponentUpdate = shouldComponentUpdate; - + this.onHorizontalCalendarScroll = + this.onHorizontalCalendarScroll.bind(this); this.horizontalScrollViewRef = React.createRef(); } @@ -131,7 +142,9 @@ class Calendar extends Component { // scroll the horizontal calendar so that selected date is visible componentDidUpdate() { const horizontalScrollView = this.horizontalScrollViewRef.current; - if (horizontalScrollView) { + if (horizontalScrollView + && this.props.autoHorizontalScroll + && !this.props.hidePastDatesInHorizontal) { const windowWidth = Dimensions.get('window').width; horizontalScrollView.scrollTo({ x: horizontalScrollViewOffset * windowWidth, @@ -224,6 +237,46 @@ class Calendar extends Component { ); } + onHorizontalCalendarScroll({ nativeEvent }) { + const { layoutMeasurement, contentOffset, contentSize } = nativeEvent; + const endReachedThreshold = this.props.horizontalEndReachedThreshold; + const startReachedThreshold = this.props.horizontalStartReachedThreshold; + const contentWidth = contentSize.width; + const travelledWidth = layoutMeasurement.width + contentOffset.x; + const horizontalScrollView = this.horizontalScrollViewRef.current; + let calendarUpdated = false; + + // going right + if (endReachedThreshold + && (travelledWidth + endReachedThreshold) > contentWidth) { + this.props.onPressArrowRight(this.state.currentMonth, this.addMonth); + calendarUpdated = true; + } + + // going left + if (contentOffset.x === startReachedThreshold) { + // don't auto select previous month when past dates are hidden + if (this.props.hidePastDatesInHorizontal) { + const selectedMonthTime = this.state.currentMonth.getTime(); + const tomorrowTime = new Date().setHours(0,0,0,0) + (24 * 3600 * 1000); + if (selectedMonthTime > tomorrowTime) { + calendarUpdated = true; + } + } else { + calendarUpdated = true; + } + if (calendarUpdated) { + this.props.onPressArrowLeft(this.state.currentMonth, this.addMonth); + } + } + + if (calendarUpdated && horizontalScrollView) { + horizontalScrollView.scrollTo({ + x: 50, animated: false + }); + } + } + getDayComponent() { if (this.props.dayComponent) { return this.props.dayComponent; @@ -261,13 +314,24 @@ class Calendar extends Component { renderWeek(days, id) { const week = []; + const nowTime = new Date().setHours(0,0,0,0); // ignoring hours, mins, secs, msecs days.forEach((day, id2) => { - week.push(this.renderDay(day, id2)); + const dayTime = day.getTime(); + + // don't show past days in horizontal calendar + if (this.state.horizontal && this.props.hidePastDatesInHorizontal) { + if (dayTime >= nowTime) { + week.push(this.renderDay(day, id2)); + } + } else { + week.push(this.renderDay(day, id2)); + } // if day is selected (aka current) day then corresponding week row id will be offset - if (day.getTime() === parseDate(this.props.current).getTime()) { + if (dayTime === parseDate(this.props.current).getTime()) { horizontalScrollViewOffset = id; } + }, this); if (this.props.showWeekNumbers) { @@ -327,6 +391,8 @@ class Calendar extends Component { {weeks} From 83341fa86962b00553963dcab277b3da0de5b021 Mon Sep 17 00:00:00 2001 From: varunon9 Date: Sun, 17 Mar 2019 09:20:18 +0530 Subject: [PATCH 6/8] feature: horizontal calendar- throttling onPressArrowRight --- src/calendar/index.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/calendar/index.js b/src/calendar/index.js index 61e19ba07..d04081301 100644 --- a/src/calendar/index.js +++ b/src/calendar/index.js @@ -27,6 +27,9 @@ const EmptyArray = []; // horizontal calendar will be scrolled to (offset * viewport width) to keep selected date visible let horizontalScrollViewOffset = 0; +// to throttle back-to-back triggering of onPressArrowRight in horizontal calendar +let onPressArrowRightTriggered = false; + class Calendar extends Component { static propTypes = { // Specify theme properties to override specific styles for calendar parts. Default = {} @@ -248,9 +251,14 @@ class Calendar extends Component { // going right if (endReachedThreshold - && (travelledWidth + endReachedThreshold) > contentWidth) { + && (travelledWidth + endReachedThreshold) > contentWidth + && !onPressArrowRightTriggered) { this.props.onPressArrowRight(this.state.currentMonth, this.addMonth); calendarUpdated = true; + onPressArrowRightTriggered = true; + setTimeout(() => { + onPressArrowRightTriggered = false; + }, 500); } // going left From 830cf88ac28b484c4890ba12b68153a167f6446e Mon Sep 17 00:00:00 2001 From: varunon9 Date: Tue, 19 Mar 2019 19:34:56 +0530 Subject: [PATCH 7/8] feature: horizontal calendar- added support for loader --- src/calendar/index.js | 94 ++++++++++++++++++++++++++++++++++--------- src/calendar/style.js | 5 +++ 2 files changed, 80 insertions(+), 19 deletions(-) diff --git a/src/calendar/index.js b/src/calendar/index.js index d04081301..aec211220 100644 --- a/src/calendar/index.js +++ b/src/calendar/index.js @@ -3,7 +3,9 @@ import { View, ViewPropTypes, ScrollView, - Dimensions + Dimensions, + ActivityIndicator, + Platform } from 'react-native'; import PropTypes from 'prop-types'; @@ -103,7 +105,11 @@ class Calendar extends Component { horizontalEndReachedThreshold: PropTypes.number, // offset to decide when to trigger onPressArrowLeft in horizontal calendar, // 0 means when leftmost day is reached, undefined means no auto onPressArrowLeft triggering - horizontalStartReachedThreshold: PropTypes.number + horizontalStartReachedThreshold: PropTypes.number, + // to show a loader + loading: PropTypes.bool, + // provide a custom loader component + LoaderComponent: PropTypes.any }; constructor(props) { @@ -126,7 +132,7 @@ class Calendar extends Component { this.longPressDay = this.longPressDay.bind(this); this.shouldComponentUpdate = shouldComponentUpdate; this.onHorizontalCalendarScroll = - this.onHorizontalCalendarScroll.bind(this); + this.onHorizontalCalendarScroll.bind(this); this.horizontalScrollViewRef = React.createRef(); } @@ -146,8 +152,8 @@ class Calendar extends Component { componentDidUpdate() { const horizontalScrollView = this.horizontalScrollViewRef.current; if (horizontalScrollView - && this.props.autoHorizontalScroll - && !this.props.hidePastDatesInHorizontal) { + && this.props.autoHorizontalScroll + && !this.props.hidePastDatesInHorizontal) { const windowWidth = Dimensions.get('window').width; horizontalScrollView.scrollTo({ x: horizontalScrollViewOffset * windowWidth, @@ -251,8 +257,8 @@ class Calendar extends Component { // going right if (endReachedThreshold - && (travelledWidth + endReachedThreshold) > contentWidth - && !onPressArrowRightTriggered) { + && (travelledWidth + endReachedThreshold) > contentWidth + && !onPressArrowRightTriggered) { this.props.onPressArrowRight(this.state.currentMonth, this.addMonth); calendarUpdated = true; onPressArrowRightTriggered = true; @@ -357,6 +363,65 @@ class Calendar extends Component { return CalendarHeader; } + showLoader() { + if (this.props.LoaderComponent) { + return ; + } else { + return ( + + + + ); + } + } + + showCalendar(weeks) { + const windowWidth = Dimensions.get('window').width; + if (this.state.horizontal) { + return ( + + {weeks} + { + this.props.loading ? + + { + this.showLoader() + } + + : null + } + + ); + } else { + return ( + + {weeks} + { + this.props.loading ? + + { + this.showLoader() + } + + : null + } + + ); + } + } + render() { const days = dateutils.page(this.state.currentMonth, this.props.firstDay); const weeks = []; @@ -368,7 +433,7 @@ class Calendar extends Component { if (current) { const lastMonthOfDay = current.clone().addMonths(1, true).setDate(1).addDays(-1).toString('yyyy-MM-dd'); if (this.props.displayLoadingIndicator && - !(this.props.markedDates && this.props.markedDates[lastMonthOfDay])) { + !(this.props.markedDates && this.props.markedDates[lastMonthOfDay])) { indicator = true; } } @@ -395,18 +460,9 @@ class Calendar extends Component { onPressGridView={this.props.onPressGridView} /> { - this.state.horizontal ? - - {weeks} - - : {weeks} + this.showCalendar(weeks) } + ); } } diff --git a/src/calendar/style.js b/src/calendar/style.js index 358f5b40a..2a2f1b991 100644 --- a/src/calendar/style.js +++ b/src/calendar/style.js @@ -20,6 +20,11 @@ export default function getStyle(theme={}) { flexDirection: 'row', justifyContent: 'space-around' }, + loaderContainer: { + width: '100%', + height: '100%', + position: 'absolute' + }, ...(theme[STYLESHEET_ID] || {}) }); } From 2fd8e4ddd3352c01efd8ca5cb77cafa03ad0c1c5 Mon Sep 17 00:00:00 2001 From: varunon9 Date: Tue, 19 Mar 2019 22:27:45 +0530 Subject: [PATCH 8/8] react-native-toggle-calendar v1.0.0 released --- README.md | 517 +++++------------------------------------- package.json | 15 +- src/interface.spec.js | 1 + 3 files changed, 72 insertions(+), 461 deletions(-) diff --git a/README.md b/README.md index 322d96490..dea30ef23 100644 --- a/README.md +++ b/README.md @@ -1,478 +1,83 @@ -A calendar built by customizing react-native-calendars to support grid as well as list view. +# React Native Toggle Calendar -Read the whole story here: https://medium.com/@varunon9/how-i-built-horizontal-as-well-as-grid-calendar-in-react-native-using-react-native-calendars-eb7a2edcc5db +Horizontal as well as Grid calendar built on top of [react-native-calendars](https://github.com/wix/react-native-calendars) -# React Native Calendars ✨ 🗓️ 📆 +### Demo -[![Version](https://img.shields.io/npm/v/react-native-calendars.svg)](https://www.npmjs.com/package/react-native-calendars) -[![Build Status](https://travis-ci.org/wix/react-native-calendars.svg?branch=master)](https://travis-ci.org/wix/react-native-calendars) + -This module includes various customizable react native calendar components. +### What's special -The package is both **Android** and **iOS** compatible. +`react-native-calendars` has no support for custom header and horizontal scrollable calendar. +This package provides these features along with some other properties like showing loader inside calendar. -## Try it out +### Usage -You can run example module by performing these steps: +1. Install this library `yarn add react-native-toggle-calendar` +2. Use in your component like- ``` -$ git clone git@github.com:wix/react-native-calendars.git -$ cd react-native-calendars/example -$ npm install -$ react-native run-ios -``` - -You can check example screens source code in [example module screens](https://github.com/wix-private/wix-react-native-calendar/tree/master/example/src/screens) - -This project is compatible with Expo/CRNA (without ejecting), and the examples have been [published on Expo](https://expo.io/@community/react-native-calendars-example) - -## Installation - -``` -$ npm install --save react-native-calendars -``` - -The solution is implemented in JavaScript so no native module linking is required. - -## Usage - -`import {` [Calendar](#calendar), [CalendarList](#calendarlist), [Agenda](#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: - -```javasctipt -{ - 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 datestrings, JavaScript date objects, `calendar objects` and UTC timestamps. - -Calendars can be localized by adding custom locales to `LocaleConfig` object: - -```javascript -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.'] -}; - -LocaleConfig.defaultLocale = 'fr'; -``` - -### Calendar - - - - - -#### Basic parameters - -```javascript - {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={substractMonth => substractMonth()} - // Handler which gets executed when press arrow icon left. It receive a callback can go next month - onPressArrowRight={addMonth => addMonth()} -/> -``` - -#### 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 - - - - - -```javascript - -``` - -You can customise 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 Calendar and CalendarList control support multiple dots by using 'dots' array in markedDates. 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. -```javascript -const vacation = {key:'vacation', color: 'red', selectedDotColor: 'blue'}; -const massage = {key:'massage', color: 'blue', selectedDotColor: 'blue'}; -const workout = {key:'workout', color: 'green'}; - - -``` - - -Period marking - - - - - - - - + import { Calendar } from 'react-native-toggle-calendar'; -```javascript - + ``` -Multi-period marking - - - +### Available props -CAUTION: This marking is only fully supported by the `` component because it expands its height. Usage with `` might lead to overflow issues. +All the props of https://github.com/wix/react-native-calendars are supported. Newly added ones are- -```javascript - ``` - -Custom marking allows you to customize each marker with custom styles. - - - - - -```javascript - -``` - -Keep in mind that different marking types are not compatible. You can use just one marking style for calendar. - -#### Displaying data loading indicator - - - - - -The loading indicator next to month name will be displayed if `` has `displayLoadingIndicator` property and `markedDays` 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 - -```javascript - -``` - -#### Advanced styling - -If you want to have complete control over calendar styles you can do it by overriding default style.js files. For example, if you want to override calendar header 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 - -```javascript -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. - -```javascript - { - return ({date.day}); - }} -/> -``` - -The dayComponent prop has to receive a RN component or function that receive props. The day component 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 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 paramters that are available for `` are also available for this component. There are also some additional params that can be used: - -```javascript - {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`: - -```javascript - -``` - -### Agenda - - - - -An advanced agenda component that can display interactive listings for calendar day items. - -```javascript - {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 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={{}} -/> + // Provide custom calendar header rendering component + calendarHeaderComponent: PropTypes.any, + // data which is passed to calendar header, useful only when implementing custom calendar header + headerData: PropTypes.object, + // Handler which gets executed when press list icon. It will set calendar to horizontal + onPressListView: PropTypes.func, + // Handler which gets executed when press grid icon. It will set calendar to grid + onPressGridView: PropTypes.func, + // to show horizontal calendar with scroll + horizontal: PropTypes.bool, + // to automatically scroll horizontal calendar to keep selected date in view + autoHorizontalScroll: PropTypes.bool, + // to show days in horizontal calendar starting from today, if this is true- autoHorizontalScroll will not work + hidePastDatesInHorizontal: PropTypes.bool, + // offset to decide when to trigger onPressArrowRight in horizontal calendar, + // 0 means when rightmost day is reached, undefined means no auto onPressArrowRight triggering + horizontalEndReachedThreshold: PropTypes.number, + // offset to decide when to trigger onPressArrowLeft in horizontal calendar, + // 0 means when leftmost day is reached, undefined means no auto onPressArrowLeft triggering + horizontalStartReachedThreshold: PropTypes.number, + // to show a loader + loading: PropTypes.bool, + // provide a custom loader component + LoaderComponent: PropTypes.any ``` -## Authors +### Sample Calendar Day and Header Components- -* [Tautvilas Mecinskas](https://github.com/tautvilas/) - Initial code - [@tautvilas](https://twitter.com/TautviIas) -* Katrin Zotchev - Initial design - [@katrin_zot](https://twitter.com/katrin_zot) +Check this gist: https://gist.github.com/varunon9/e204479219a55d86c4d8a985bae4e7f1 -See also the list of [contributors](https://github.com/wix/react-native-calendar-components/contributors) who participated in this project. +### Code changes from original package -## Contributing +Check this PR: https://github.com/varunon9/react-native-toggle-calendar/pull/1 -Pull requests are welcome. `npm run test` and `npm run lint` before push. +Blog: https://medium.com/@varunon9/how-i-built-horizontal-as-well-as-grid-calendar-in-react-native-using-react-native-calendars-eb7a2edcc5db \ No newline at end of file diff --git a/package.json b/package.json index 4a4cbdab5..5b4c4d7ba 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { - "name": "react-native-calendars", - "version": "1.22.0", + "name": "react-native-toggle-calendar", + "version": "1.0.0", "main": "src/index.js", - "description": "React Native Calendar Components", + "description": "Horizontal as well as Grid calendar built on top of react-native-calendars", "scripts": { "test": "jasmine src/*.spec.js && npm run lint", "lint": "eslint src/ example/src", @@ -10,12 +10,17 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/wix/react-native-calendars" + "url": "git+https://github.com/varunon9/react-native-toggle-calendar" }, "publishConfig": { "registry": "https://registry.npmjs.org/" }, - "author": "Wix.com", + "keywords": [ + "react-native-calendars", + "horizontal scrollable calendar", + "grid-list calendar" + ], + "author": "Varun Kumar ", "license": "MIT", "dependencies": { "lodash.get": "^4.4.2", diff --git a/src/interface.spec.js b/src/interface.spec.js index e0adc50b6..d3a24d6c6 100644 --- a/src/interface.spec.js +++ b/src/interface.spec.js @@ -60,6 +60,7 @@ describe('calendar interface', () => { year: 2016, month: 11, day: 22, + weekDay: 2, timestamp: 1479772800000, dateString: '2016-11-22' });