diff --git a/src/Scroller.js b/src/Scroller.js index 998dff7..797ba7e 100644 --- a/src/Scroller.js +++ b/src/Scroller.js @@ -8,7 +8,11 @@ import React, { Component } from "react"; import { View } from "react-native"; import PropTypes from "prop-types"; -import { RecyclerListView, DataProvider, LayoutProvider } from "recyclerlistview"; +import { + RecyclerListView, + DataProvider, + LayoutProvider, +} from "recyclerlistview"; import moment from "moment"; export default class CalendarScroller extends Component { @@ -25,8 +29,8 @@ export default class CalendarScroller extends Component { onWeekScrollStart: PropTypes.func, onWeekScrollEnd: PropTypes.func, externalScrollView: PropTypes.func, - pagingEnabled: PropTypes.bool - } + pagingEnabled: PropTypes.bool, + }; static defaultProps = { data: [], @@ -38,12 +42,13 @@ export default class CalendarScroller extends Component { this.timeoutResetPositionId = null; - this.updateLayout = renderDayParams => { - const itemHeight = renderDayParams.height; - const itemWidth = renderDayParams.width + renderDayParams.marginHorizontal * 2; + this.updateLayout = (renderDayParams) => { + const itemHeight = 100; + const itemWidth = + renderDayParams.width + renderDayParams.marginHorizontal * 2; const layoutProvider = new LayoutProvider( - index => 0, // only 1 view type + (index) => 0, // only 1 view type (type, dim) => { dim.width = itemWidth; dim.height = itemHeight; @@ -51,19 +56,19 @@ export default class CalendarScroller extends Component { ); return { layoutProvider, itemHeight, itemWidth }; - } + }; this.dataProvider = new DataProvider((r1, r2) => { return r1 !== r2; }); - this.updateDaysData = data => { + this.updateDaysData = (data) => { return { data, numDays: data.length, dataProvider: this.dataProvider.cloneWithRows(data), - } - } + }; + }; this.state = { ...this.updateLayout(props.renderDayParams), @@ -83,12 +88,11 @@ export default class CalendarScroller extends Component { let newState = {}; let updateState = false; - const { - width, - height, - selectedDate - } = this.props.renderDayParams; - if (width !== prevProps.renderDayParams.width || height !== prevProps.renderDayParams.height) { + const { width, height, selectedDate } = this.props.renderDayParams; + if ( + width !== prevProps.renderDayParams.width || + height !== prevProps.renderDayParams.height + ) { updateState = true; newState = this.updateLayout(this.props.renderDayParams); } @@ -99,7 +103,7 @@ export default class CalendarScroller extends Component { if (this.props.data !== prevProps.data) { updateState = true; - newState = {...newState, ...this.updateDaysData(this.props.data)}; + newState = { ...newState, ...this.updateDaysData(this.props.data) }; } if (updateState) { @@ -112,27 +116,30 @@ export default class CalendarScroller extends Component { if (this.state.visibleStartIndex === 0) { return; } - const newIndex = Math.max(this.state.visibleStartIndex - this.state.numVisibleItems, 0); + const newIndex = Math.max( + this.state.visibleStartIndex - this.state.numVisibleItems, + 0 + ); this.rlv.scrollToIndex(newIndex, true); - } + }; // Scroll right, guarding against end index. scrollRight = () => { const newIndex = this.state.visibleStartIndex + this.state.numVisibleItems; - if (newIndex >= (this.state.numDays - 1)) { + if (newIndex >= this.state.numDays - 1) { this.rlv.scrollToEnd(true); // scroll to the very end, including padding return; } this.rlv.scrollToIndex(newIndex, true); - } + }; // Scroll to given date, and check against min and max date if available. scrollToDate = (date) => { - let targetDate = moment(date).subtract(Math.round(this.state.numVisibleItems / 2) - 1, "days"); - const { - minDate, - maxDate, - } = this.props; + let targetDate = moment(date).subtract( + Math.round(this.state.numVisibleItems / 2) - 1, + "days" + ); + const { minDate, maxDate } = this.props; // Falls back to min or max date when the given date exceeds the available dates if (minDate && targetDate.isBefore(minDate, "day")) { @@ -147,30 +154,31 @@ export default class CalendarScroller extends Component { break; } } - } + }; // Shift dates when end of list is reached. shiftDaysForward = (visibleStartDate = this.state.visibleStartDate) => { const prevVisStart = visibleStartDate.clone(); - const newStartDate = prevVisStart.clone().subtract(Math.floor(this.state.numDays / 3), "days"); + const newStartDate = prevVisStart + .clone() + .subtract(Math.floor(this.state.numDays / 3), "days"); this.updateDays(prevVisStart, newStartDate); - } + }; // Shift dates when beginning of list is reached. shiftDaysBackward = (visibleStartDate) => { const prevVisStart = visibleStartDate.clone(); - const newStartDate = prevVisStart.clone().subtract(Math.floor(this.state.numDays * 2/3), "days"); + const newStartDate = prevVisStart + .clone() + .subtract(Math.floor((this.state.numDays * 2) / 3), "days"); this.updateDays(prevVisStart, newStartDate); - } + }; updateDays = (prevVisStart, newStartDate) => { if (this.shifting) { return; } - const { - minDate, - maxDate, - } = this.props; + const { minDate, maxDate } = this.props; const data = []; let _newStartDate = newStartDate; if (minDate && newStartDate.isBefore(minDate, "day")) { @@ -181,7 +189,7 @@ export default class CalendarScroller extends Component { if (maxDate && date.isAfter(maxDate, "day")) { break; } - data.push({date}); + data.push({ date }); } // Prevent reducing range when the minDate - maxDate range is small. if (data.length < this.props.maxSimultaneousDays) { @@ -207,7 +215,7 @@ export default class CalendarScroller extends Component { data, dataProvider: this.dataProvider.cloneWithRows(data), }); - } + }; // Track which dates are visible. onVisibleIndicesChanged = (all, now, notNow) => { @@ -219,23 +227,29 @@ export default class CalendarScroller extends Component { visibleEndDate: _visEndDate, } = this.state; const visibleStartIndex = all[0]; - const visibleStartDate = data[visibleStartIndex] ? data[visibleStartIndex].date : moment(); - const visibleEndIndex = Math.min(visibleStartIndex + numVisibleItems - 1, data.length - 1); - const visibleEndDate = data[visibleEndIndex] ? data[visibleEndIndex].date : moment(); + const visibleStartDate = data[visibleStartIndex] + ? data[visibleStartIndex].date + : moment(); + const visibleEndIndex = Math.min( + visibleStartIndex + numVisibleItems - 1, + data.length - 1 + ); + const visibleEndDate = data[visibleEndIndex] + ? data[visibleEndIndex].date + : moment(); - const { - updateMonthYear, - onWeekChanged, - } = this.props; + const { updateMonthYear, onWeekChanged } = this.props; // Fire month/year update on both week and month changes. This is // necessary for the header and onWeekChanged updates. - if (!_visStartDate || !_visEndDate || - !visibleStartDate.isSame(_visStartDate, "week") || - !visibleEndDate.isSame(_visEndDate, "week") || - !visibleStartDate.isSame(_visStartDate, "month") || - !visibleEndDate.isSame(_visEndDate, "month") ) - { + if ( + !_visStartDate || + !_visEndDate || + !visibleStartDate.isSame(_visStartDate, "week") || + !visibleEndDate.isSame(_visEndDate, "week") || + !visibleStartDate.isSame(_visStartDate, "month") || + !visibleEndDate.isSame(_visEndDate, "month") + ) { const visStart = visibleStartDate && visibleStartDate.clone(); const visEnd = visibleEndDate && visibleEndDate.clone(); onWeekChanged && onWeekChanged(visStart, visEnd); @@ -262,33 +276,30 @@ export default class CalendarScroller extends Component { visibleEndDate, visibleStartIndex, }); - } + }; onScrollStart = (event) => { - const {onWeekScrollStart} = this.props; - const {prevStartDate, prevEndDate} = this.state; + const { onWeekScrollStart } = this.props; + const { prevStartDate, prevEndDate } = this.state; if (onWeekScrollStart && prevStartDate && prevEndDate) { onWeekScrollStart(prevStartDate.clone(), prevEndDate.clone()); } - } + }; onScrollEnd = () => { - const {onWeekScrollEnd} = this.props; - const {visibleStartDate, visibleEndDate, prevEndDate} = this.state; + const { onWeekScrollEnd } = this.props; + const { visibleStartDate, visibleEndDate, prevEndDate } = this.state; if (onWeekScrollEnd && visibleStartDate && visibleEndDate) { if (!visibleEndDate.isSame(prevEndDate, "day")) { onWeekScrollEnd(visibleStartDate.clone(), visibleEndDate.clone()); } } - } + }; onScrollBeginDrag = () => { - const { - onWeekScrollStart, - onWeekScrollEnd, - } = this.props; + const { onWeekScrollStart, onWeekScrollEnd } = this.props; // Prev dates required only if scroll callbacks are defined if (!onWeekScrollStart && !onWeekScrollEnd) { return; @@ -300,37 +311,51 @@ export default class CalendarScroller extends Component { visibleStartIndex, visibleEndIndex, } = this.state; - const prevStartDate = visibleStartDate ? visibleStartDate - : (data[visibleStartIndex] ? data[visibleStartIndex].date : moment()); - const prevEndDate = visibleEndDate ? visibleEndDate - : (data[visibleEndIndex] ? data[visibleEndIndex].date : moment()); + const prevStartDate = visibleStartDate + ? visibleStartDate + : data[visibleStartIndex] + ? data[visibleStartIndex].date + : moment(); + const prevEndDate = visibleEndDate + ? visibleEndDate + : data[visibleEndIndex] + ? data[visibleEndIndex].date + : moment(); this.setState({ prevStartDate, prevEndDate, }); - } + }; - onLayout = event => { + onLayout = (event) => { let width = event.nativeEvent.layout.width; this.setState({ numVisibleItems: Math.round(width / this.state.itemWidth), }); - } + }; rowRenderer = (type, data, i, extState) => { - return this.props.renderDay && this.props.renderDay({...data, ...extState}); - } + return ( + this.props.renderDay && this.props.renderDay({ ...data, ...extState }) + ); + }; render() { - if (!this.state.data || this.state.numDays === 0 || !this.state.itemHeight) { + if ( + !this.state.data || + this.state.numDays === 0 || + !this.state.itemHeight + ) { return null; } - const pagingProps = this.props.pagingEnabled ? { - decelerationRate: 0, - snapToInterval: this.state.itemWidth * this.state.numVisibleItems - } : {}; + const pagingProps = this.props.pagingEnabled + ? { + decelerationRate: 0, + snapToInterval: this.state.itemWidth * this.state.numVisibleItems, + } + : {}; return ( this.rlv = rlv} + ref={(rlv) => (this.rlv = rlv)} layoutProvider={this.state.layoutProvider} dataProvider={this.state.dataProvider} rowRenderer={this.rowRenderer} @@ -353,7 +378,7 @@ export default class CalendarScroller extends Component { onMomentumScrollBegin: this.onScrollStart, onMomentumScrollEnd: this.onScrollEnd, onScrollBeginDrag: this.onScrollBeginDrag, - ...pagingProps + ...pagingProps, }} />