@appannie/react-infinite-calendar
Version:
Infinite scrolling date-picker built with React, with localization, themes, keyboard support, and more.
216 lines (195 loc) • 9.37 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var React = require('react');
var VirtualList = require('react-tiny-virtual-list');
var classNames = require('classnames');
var index = require('../utils/index.js');
var dateFnV2 = require('../utils/dateFnV2.js');
var Years$1 = require('./Years.scss.js');
var parse = require('../utils/parse.js');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var _objectSpread__default = /*#__PURE__*/_interopDefaultLegacy(_objectSpread);
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var VirtualList__default = /*#__PURE__*/_interopDefaultLegacy(VirtualList);
var classNames__default = /*#__PURE__*/_interopDefaultLegacy(classNames);
var SPACING = 0;
var isDateDisabled = function isDateDisabled(_ref) {
var date = _ref.date,
min = _ref.min,
minDate = _ref.minDate,
max = _ref.max,
maxDate = _ref.maxDate;
return dateFnV2.isBefore(date, dateFnV2.startOfMonth(min)) || dateFnV2.isBefore(date, dateFnV2.startOfMonth(minDate)) || dateFnV2.isAfter(date, max) || dateFnV2.isAfter(date, maxDate);
};
var allowToSwitchYear = function allowToSwitchYear(_ref2) {
var selected = _ref2.selected,
year = _ref2.year,
min = _ref2.min,
minDate = _ref2.minDate,
max = _ref2.max,
maxDate = _ref2.maxDate;
if (index.isRange(selected)) {
return false;
}
return !isDateDisabled({
date: new Date(selected).setYear(year),
min: min,
minDate: minDate,
max: max,
maxDate: maxDate
});
};
var getSelected = function getSelected(selected) {
if (index.isRange(selected)) {
return {
start: dateFnV2.startOfMonth(selected.start),
end: dateFnV2.endOfMonth(selected.end)
};
} // remove time
return {
start: parse.parseDate(dateFnV2.format(selected, 'yyyy-MM-dd')),
end: parse.parseDate(dateFnV2.format(selected, 'yyyy-MM-dd'))
};
};
var Years = function Years(_ref3) {
var height = _ref3.height,
hideOnSelect = _ref3.hideOnSelect,
locale = _ref3.locale,
max = _ref3.max,
maxDate = _ref3.maxDate,
min = _ref3.min,
minDate = _ref3.minDate,
scrollToDate = _ref3.scrollToDate,
today = _ref3.today,
setDisplay = _ref3.setDisplay,
theme = _ref3.theme,
handlers = _ref3.handlers,
width = _ref3.width,
_ref3$onSelect = _ref3.onSelect,
onSelect = _ref3$onSelect === void 0 ? index.emptyFn : _ref3$onSelect,
_ref3$showMonths = _ref3.showMonths,
showMonths = _ref3$showMonths === void 0 ? true : _ref3$showMonths,
selected = _ref3.selected,
years = _ref3.years;
var selectedYearIndex = React.useMemo(function () {
var yearsSliced = years.slice(0, years.length);
return yearsSliced.indexOf(getSelected(selected).start.getFullYear());
}, [selected, years]);
var handleClick = React.useCallback(function (date, e) {
onSelect(date, e, function (date) {
return scrollToDate(date);
});
if (hideOnSelect) {
window.requestAnimationFrame(function () {
return setDisplay('days');
});
}
}, [hideOnSelect, onSelect, scrollToDate, setDisplay]);
var renderMonths = React.useCallback(function (year) {
var months = index.getMonthsForYear(year, getSelected(selected).start.getDate());
return /*#__PURE__*/React__default['default'].createElement("ol", null, months.map(function (date, index$1) {
var _classNames;
var isSelected = dateFnV2.isWithinRange(date, getSelected(selected).start, getSelected(selected).end);
var isCurrentMonth = dateFnV2.isSameMonth(date, today);
var isDisabled = isDateDisabled({
date: date,
min: min,
minDate: minDate,
max: max,
maxDate: maxDate
});
var style = Object.assign({}, isSelected && {
backgroundColor: typeof theme.selectionColor === 'function' ? theme.selectionColor(date) : theme.selectionColor
}, isCurrentMonth && {
borderColor: theme.todayColor
});
var isStart = dateFnV2.isSameMonth(date, selected.start);
var isEnd = dateFnV2.isSameMonth(date, selected.end);
return /*#__PURE__*/React__default['default'].createElement("li", Object.assign({
key: index$1,
onClick: function onClick(e) {
e.stopPropagation();
if (!isDisabled) {
handleClick(date, e);
}
},
className: classNames__default['default'](Years$1['default'].month, (_classNames = {}, _defineProperty__default['default'](_classNames, Years$1['default'].selected, isSelected), _defineProperty__default['default'](_classNames, Years$1['default'].currentMonth, isCurrentMonth), _defineProperty__default['default'](_classNames, Years$1['default'].disabled, isDisabled), _defineProperty__default['default'](_classNames, Years$1['default'].range, !(isStart && isEnd)), _defineProperty__default['default'](_classNames, Years$1['default'].start, isStart), _defineProperty__default['default'](_classNames, Years$1['default'].betweenRange, dateFnV2.isWithinRange(date, selected.start, selected.end) && !isStart && !isEnd), _defineProperty__default['default'](_classNames, Years$1['default'].end, isEnd), _classNames)),
style: style,
title: index.isRange(selected) ? '' : "Set date to ".concat(dateFnV2.format(date, 'MMMM do, yyyy')),
"data-month": "".concat(dateFnV2.format(date, 'yyyy-MM-dd'))
}, handlers), /*#__PURE__*/React__default['default'].createElement("div", {
className: Years$1['default'].selection,
"data-month": "".concat(dateFnV2.format(date, 'yyyy-MM-dd'))
}, dateFnV2.format(date, 'MMM', {
locale: locale === null || locale === void 0 ? void 0 : locale.locale
})));
}));
}, [handleClick, handlers, locale, max, maxDate, min, minDate, selected, theme, today]);
var currentYear = today.getFullYear();
var yearsSliced = years.slice(0, years.length);
var rowHeight = showMonths ? 80 : 40;
var heights = yearsSliced.map(function (val, index) {
return index === 0 || index === yearsSliced.length - 1 ? rowHeight + SPACING : rowHeight;
});
var isYearLess = yearsSliced.length * rowHeight < height + 40;
var containerHeight = isYearLess ? yearsSliced.length * rowHeight + 2 * SPACING : height + 40;
var scrollOffset = 0;
if (!isYearLess && selectedYearIndex !== -1) {
var top = heights.slice(0, selectedYearIndex).reduce(function (acc, val) {
return acc + val;
}, 0);
scrollOffset = top - containerHeight / 2 + 40;
}
return /*#__PURE__*/React__default['default'].createElement("div", {
className: Years$1['default'].root,
style: {
color: theme.selectionColor,
height: height + 40
}
}, /*#__PURE__*/React__default['default'].createElement(VirtualList__default['default'], {
className: Years$1['default'].list,
width: width,
height: containerHeight,
itemCount: yearsSliced.length,
estimatedItemSize: rowHeight,
itemSize: function itemSize(index) {
return heights[index];
},
scrollOffset: scrollOffset,
renderItem: function renderItem(_ref4) {
var _classNames2;
var index = _ref4.index,
style = _ref4.style;
var year = yearsSliced[index];
var isActive = index === selectedYearIndex;
var shouldAllowToSwitchYear = allowToSwitchYear({
selected: selected,
year: year,
min: min,
minDate: minDate,
max: max,
maxDate: maxDate
});
return /*#__PURE__*/React__default['default'].createElement("div", {
key: index,
className: classNames__default['default'](Years$1['default'].year, (_classNames2 = {}, _defineProperty__default['default'](_classNames2, Years$1['default'].active, !showMonths && isActive), _defineProperty__default['default'](_classNames2, Years$1['default'].currentYear, !showMonths && year === currentYear), _defineProperty__default['default'](_classNames2, Years$1['default'].withMonths, showMonths), _defineProperty__default['default'](_classNames2, Years$1['default'].first, index === 0), _defineProperty__default['default'](_classNames2, Years$1['default'].last, index === yearsSliced.length - 1), _classNames2)),
onClick: function onClick(e) {
return shouldAllowToSwitchYear && handleClick(new Date(year, 0, 1), e);
},
title: shouldAllowToSwitchYear ? "Set year to ".concat(year) : '',
"data-year": year,
style: _objectSpread__default['default'](_objectSpread__default['default']({}, style), {
color: typeof theme.selectionColor === 'function' ? theme.selectionColor(new Date(year, 0, 1)) : theme.selectionColor
})
}, /*#__PURE__*/React__default['default'].createElement("label", null, /*#__PURE__*/React__default['default'].createElement("span", {
style: !showMonths && year === currentYear ? {
borderColor: theme.todayColor
} : null
}, year)), showMonths && renderMonths(year));
}
}));
};
exports.default = Years;