react-infinite-calendar
Version:
Infinite scrolling date-picker built with React, with localization, themes, keyboard support, and more.
215 lines (187 loc) • 7.77 kB
JavaScript
var _class, _temp;
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, getMonthsForYear } from '../utils';
import format from 'date-fns/format';
import isAfter from 'date-fns/is_after';
import isBefore from 'date-fns/is_before';
import isSameMonth from 'date-fns/is_same_month';
var styles = {
'root': 'Cal__Years__root',
'list': 'Cal__Years__list',
'center': 'Cal__Years__center',
'year': 'Cal__Years__year',
'withMonths': 'Cal__Years__withMonths',
'currentMonth': 'Cal__Years__currentMonth',
'selected': 'Cal__Years__selected',
'disabled': 'Cal__Years__disabled',
'active': 'Cal__Years__active',
'currentYear': 'Cal__Years__currentYear',
'first': 'Cal__Years__first',
'last': 'Cal__Years__last'
};
var SPACING = 40;
var Years = (_temp = _class = function (_Component) {
_inherits(Years, _Component);
function Years() {
_classCallCheck(this, Years);
return _possibleConstructorReturn(this, _Component.apply(this, arguments));
}
Years.prototype.handleClick = function handleClick(date, e) {
var _props = this.props,
hideOnSelect = _props.hideOnSelect,
onSelect = _props.onSelect,
setDisplay = _props.setDisplay,
scrollToDate = _props.scrollToDate;
onSelect(date, e, function (date) {
return scrollToDate(date);
});
if (hideOnSelect) {
window.requestAnimationFrame(function () {
return setDisplay('days');
});
}
};
Years.prototype.renderMonths = function renderMonths(year) {
var _this2 = this;
var _props2 = this.props,
locale = _props2.locale.locale,
selected = _props2.selected,
theme = _props2.theme,
today = _props2.today,
min = _props2.min,
max = _props2.max,
minDate = _props2.minDate,
maxDate = _props2.maxDate;
var months = getMonthsForYear(year, selected.getDate());
return React.createElement(
'ol',
null,
months.map(function (date, index) {
var _classNames;
var isSelected = isSameMonth(date, selected);
var isCurrentMonth = isSameMonth(date, today);
var isDisabled = isBefore(date, min) || isBefore(date, minDate) || isAfter(date, max) || isAfter(date, maxDate);
var style = Object.assign({}, isSelected && {
backgroundColor: typeof theme.selectionColor === 'function' ? theme.selectionColor(date) : theme.selectionColor
}, isCurrentMonth && {
borderColor: theme.todayColor
});
return React.createElement(
'li',
{
key: index,
onClick: function onClick(e) {
e.stopPropagation();
if (!isDisabled) {
_this2.handleClick(date, e);
}
},
className: classNames(styles.month, (_classNames = {}, _classNames[styles.selected] = isSelected, _classNames[styles.currentMonth] = isCurrentMonth, _classNames[styles.disabled] = isDisabled, _classNames)),
style: style,
title: 'Set date to ' + format(date, 'MMMM Do, YYYY')
},
format(date, 'MMM', { locale: locale })
);
})
);
};
Years.prototype.render = function render() {
var _this3 = this;
var _props3 = this.props,
height = _props3.height,
selected = _props3.selected,
showMonths = _props3.showMonths,
theme = _props3.theme,
today = _props3.today,
width = _props3.width;
var currentYear = today.getFullYear();
var years = this.props.years.slice(0, this.props.years.length);
var selectedYearIndex = years.indexOf(selected.getFullYear());
var rowHeight = showMonths ? 110 : 50;
var heights = years.map(function (val, index) {
return index === 0 || index === years.length - 1 ? rowHeight + SPACING : rowHeight;
});
var containerHeight = years.length * rowHeight < height + 50 ? years.length * rowHeight : height + 50;
return React.createElement(
'div',
{
className: styles.root,
style: { color: theme.selectionColor, height: height + 50 }
},
React.createElement(VirtualList, {
ref: 'List',
className: styles.list,
width: width,
height: containerHeight,
itemCount: years.length,
estimatedItemSize: rowHeight,
itemSize: function itemSize(index) {
return heights[index];
},
scrollToIndex: selectedYearIndex !== -1 ? selectedYearIndex : null,
scrollToAlignment: 'center',
renderItem: function renderItem(_ref) {
var _classNames2;
var index = _ref.index,
style = _ref.style;
var year = years[index];
var isActive = index === selectedYearIndex;
return React.createElement(
'div',
{
key: index,
className: classNames(styles.year, (_classNames2 = {}, _classNames2[styles.active] = !showMonths && isActive, _classNames2[styles.currentYear] = !showMonths && year === currentYear, _classNames2[styles.withMonths] = showMonths, _classNames2[styles.first] = index === 0, _classNames2[styles.last] = index === years.length - 1, _classNames2)),
onClick: function onClick() {
return _this3.handleClick(new Date(selected).setYear(year));
},
title: 'Set year to ' + year,
'data-year': year,
style: Object.assign({}, style, {
color: typeof theme.selectionColor === 'function' ? theme.selectionColor(new Date(year, 0, 1)) : theme.selectionColor
})
},
React.createElement(
'label',
null,
React.createElement(
'span',
{
style: !showMonths && year === currentYear ? { borderColor: theme.todayColor } : null
},
year
)
),
showMonths && _this3.renderMonths(year)
);
}
})
);
};
return Years;
}(Component), _class.defaultProps = {
onSelect: emptyFn,
showMonths: true
}, _temp);
export { Years as default };
process.env.NODE_ENV !== "production" ? Years.propTypes = {
height: PropTypes.number,
hideOnSelect: PropTypes.bool,
locale: PropTypes.object,
max: PropTypes.object,
maxDate: PropTypes.object,
min: PropTypes.object,
minDate: PropTypes.object,
onSelect: PropTypes.func,
scrollToDate: PropTypes.func,
selectedYear: PropTypes.number,
setDisplay: PropTypes.func,
theme: PropTypes.object,
width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
years: PropTypes.array
} : void 0;