UNPKG

react-infinite-calendar

Version:

Infinite scrolling date-picker built with React, with localization, themes, keyboard support, and more.

239 lines (203 loc) 9.09 kB
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } import React, { Component } from 'react'; import PropTypes from 'prop-types'; import VirtualList from 'react-tiny-virtual-list'; import classNames from 'classnames'; import { emptyFn, getMonth, getWeek, getWeeksInMonth, animate } from '../utils'; import parse from 'date-fns/parse'; import startOfMonth from 'date-fns/start_of_month'; import Month from '../Month'; var styles = { 'root': 'Cal__MonthList__root', 'scrolling': 'Cal__MonthList__scrolling' }; var AVERAGE_ROWS_PER_MONTH = 5; var MonthList = function (_Component) { _inherits(MonthList, _Component); function MonthList() { var _temp, _this, _ret; _classCallCheck(this, MonthList); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = _possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.state = { scrollTop: _this.getDateOffset(_this.props.scrollDate) }, _this.cache = {}, _this.memoize = function (param) { if (!this.cache[param]) { var weekStartsOn = this.props.locale.weekStartsOn; var _param$split = param.split(':'), year = _param$split[0], month = _param$split[1]; var result = getMonth(year, month, weekStartsOn); this.cache[param] = result; } return this.cache[param]; }, _this.monthHeights = [], _this._getRef = function (instance) { _this.VirtualList = instance; }, _this.getMonthHeight = function (index) { if (!_this.monthHeights[index]) { var _this$props = _this.props, weekStartsOn = _this$props.locale.weekStartsOn, months = _this$props.months, rowHeight = _this$props.rowHeight; var _months$index = months[index], month = _months$index.month, year = _months$index.year; var weeks = getWeeksInMonth(month, year, weekStartsOn, index === months.length - 1); var height = weeks * rowHeight; _this.monthHeights[index] = height; } return _this.monthHeights[index]; }, _this.scrollToDate = function (date) { for (var _len2 = arguments.length, rest = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { rest[_key2 - 2] = arguments[_key2]; } var _this2; var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var offsetTop = _this.getDateOffset(date); (_this2 = _this).scrollTo.apply(_this2, [offsetTop + offset].concat(rest)); }, _this.scrollTo = function () { var scrollTop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var shouldAnimate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var onScrollEnd = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : emptyFn; var onComplete = function onComplete() { return setTimeout(function () { _this.scrollEl.style.overflowY = 'auto'; onScrollEnd(); }); }; // Interrupt iOS Momentum scroll _this.scrollEl.style.overflowY = 'hidden'; if (shouldAnimate) { /* eslint-disable sort-keys */ animate({ fromValue: _this.scrollEl.scrollTop, toValue: scrollTop, onUpdate: function onUpdate(scrollTop, callback) { return _this.setState({ scrollTop: scrollTop }, callback); }, onComplete: onComplete }); } else { window.requestAnimationFrame(function () { _this.scrollEl.scrollTop = scrollTop; onComplete(); }); } }, _this.renderMonth = function (_ref) { var index = _ref.index, style = _ref.style; var _this$props2 = _this.props, DayComponent = _this$props2.DayComponent, disabledDates = _this$props2.disabledDates, disabledDays = _this$props2.disabledDays, locale = _this$props2.locale, maxDate = _this$props2.maxDate, minDate = _this$props2.minDate, months = _this$props2.months, passThrough = _this$props2.passThrough, rowHeight = _this$props2.rowHeight, selected = _this$props2.selected, showOverlay = _this$props2.showOverlay, theme = _this$props2.theme, today = _this$props2.today; var _months$index2 = months[index], month = _months$index2.month, year = _months$index2.year; var key = year + ':' + month; var _this$memoize = _this.memoize(key), date = _this$memoize.date, rows = _this$memoize.rows; return React.createElement(Month, _extends({ key: key, selected: selected, DayComponent: DayComponent, monthDate: date, disabledDates: disabledDates, disabledDays: disabledDays, maxDate: maxDate, minDate: minDate, rows: rows, rowHeight: rowHeight, isScrolling: false, showOverlay: showOverlay, today: today, theme: theme, style: style, locale: locale, passThrough: passThrough }, passThrough.Month)); }, _temp), _possibleConstructorReturn(_this, _ret); } MonthList.prototype.componentDidMount = function componentDidMount() { this.scrollEl = this.VirtualList.rootNode; }; MonthList.prototype.componentWillReceiveProps = function componentWillReceiveProps(_ref2) { var scrollDate = _ref2.scrollDate; if (scrollDate !== this.props.scrollDate) { this.setState({ scrollTop: this.getDateOffset(scrollDate) }); } }; MonthList.prototype.getDateOffset = function getDateOffset(date) { var _props = this.props, min = _props.min, rowHeight = _props.rowHeight, weekStartsOn = _props.locale.weekStartsOn, height = _props.height; var weeks = getWeek(startOfMonth(min), parse(date), weekStartsOn); return weeks * rowHeight - (height - rowHeight / 2) / 2; }; MonthList.prototype.render = function render() { var _classNames; var _props2 = this.props, height = _props2.height, isScrolling = _props2.isScrolling, onScroll = _props2.onScroll, overscanMonthCount = _props2.overscanMonthCount, months = _props2.months, rowHeight = _props2.rowHeight, width = _props2.width; var scrollTop = this.state.scrollTop; return React.createElement(VirtualList, { ref: this._getRef, width: width, height: height, itemCount: months.length, itemSize: this.getMonthHeight, estimatedItemSize: rowHeight * AVERAGE_ROWS_PER_MONTH, renderItem: this.renderMonth, onScroll: onScroll, scrollOffset: scrollTop, className: classNames(styles.root, (_classNames = {}, _classNames[styles.scrolling] = isScrolling, _classNames)), style: { lineHeight: rowHeight + 'px' }, overscanCount: overscanMonthCount }); }; return MonthList; }(Component); export { MonthList as default }; process.env.NODE_ENV !== "production" ? MonthList.propTypes = { disabledDates: PropTypes.arrayOf(PropTypes.string), disabledDays: PropTypes.arrayOf(PropTypes.number), height: PropTypes.number, isScrolling: PropTypes.bool, locale: PropTypes.object, maxDate: PropTypes.instanceOf(Date), min: PropTypes.instanceOf(Date), minDate: PropTypes.instanceOf(Date), months: PropTypes.arrayOf(PropTypes.object), onDaySelect: PropTypes.func, onScroll: PropTypes.func, overscanMonthCount: PropTypes.number, rowHeight: PropTypes.number, selectedDate: PropTypes.instanceOf(Date), showOverlay: PropTypes.bool, theme: PropTypes.object, today: PropTypes.instanceOf(Date), width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) } : void 0;