react-dates
Version:
A responsive and accessible date range picker component built with React
525 lines (447 loc) • 22.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _reactAddonsShallowCompare = _interopRequireDefault(require("react-addons-shallow-compare"));
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _reactMomentProptypes = _interopRequireDefault(require("react-moment-proptypes"));
var _airbnbPropTypes = require("airbnb-prop-types");
var _reactWithStyles = require("react-with-styles");
var _moment = _interopRequireDefault(require("moment"));
var _consolidatedEvents = require("consolidated-events");
var _defaultPhrases = require("../defaultPhrases");
var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes"));
var _CalendarMonth = _interopRequireDefault(require("./CalendarMonth"));
var _isTransitionEndSupported = _interopRequireDefault(require("../utils/isTransitionEndSupported"));
var _getTransformStyles = _interopRequireDefault(require("../utils/getTransformStyles"));
var _getCalendarMonthWidth = _interopRequireDefault(require("../utils/getCalendarMonthWidth"));
var _toISOMonthString = _interopRequireDefault(require("../utils/toISOMonthString"));
var _isPrevMonth = _interopRequireDefault(require("../utils/isPrevMonth"));
var _isNextMonth = _interopRequireDefault(require("../utils/isNextMonth"));
var _ModifiersShape = _interopRequireDefault(require("../shapes/ModifiersShape"));
var _ScrollableOrientationShape = _interopRequireDefault(require("../shapes/ScrollableOrientationShape"));
var _DayOfWeekShape = _interopRequireDefault(require("../shapes/DayOfWeekShape"));
var _constants = require("../constants");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _extends() { _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; }; return _extends.apply(this, arguments); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function () { function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); } return _getPrototypeOf; }(); return _getPrototypeOf(o); }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function () { function _setPrototypeOf(o, p) { o.__proto__ = p; return o; } return _setPrototypeOf; }(); return _setPrototypeOf(o, p); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread({}, _reactWithStyles.withStylesPropTypes, {
enableOutsideDays: _propTypes["default"].bool,
firstVisibleMonthIndex: _propTypes["default"].number,
horizontalMonthPadding: _airbnbPropTypes.nonNegativeInteger,
initialMonth: _reactMomentProptypes["default"].momentObj,
isAnimating: _propTypes["default"].bool,
numberOfMonths: _propTypes["default"].number,
modifiers: _propTypes["default"].objectOf(_propTypes["default"].objectOf(_ModifiersShape["default"])),
orientation: _ScrollableOrientationShape["default"],
onDayClick: _propTypes["default"].func,
onDayMouseEnter: _propTypes["default"].func,
onDayMouseLeave: _propTypes["default"].func,
onMonthTransitionEnd: _propTypes["default"].func,
onMonthChange: _propTypes["default"].func,
onYearChange: _propTypes["default"].func,
renderMonthText: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'),
renderCalendarDay: _propTypes["default"].func,
renderDayContents: _propTypes["default"].func,
translationValue: _propTypes["default"].number,
renderMonthElement: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'),
daySize: _airbnbPropTypes.nonNegativeInteger,
focusedDate: _reactMomentProptypes["default"].momentObj,
// indicates focusable day
isFocused: _propTypes["default"].bool,
// indicates whether or not to move focus to focusable day
firstDayOfWeek: _DayOfWeekShape["default"],
setMonthTitleHeight: _propTypes["default"].func,
isRTL: _propTypes["default"].bool,
transitionDuration: _airbnbPropTypes.nonNegativeInteger,
verticalBorderSpacing: _airbnbPropTypes.nonNegativeInteger,
// i18n
monthFormat: _propTypes["default"].string,
phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.CalendarDayPhrases)),
dayAriaLabelFormat: _propTypes["default"].string
})) : {};
var defaultProps = {
enableOutsideDays: false,
firstVisibleMonthIndex: 0,
horizontalMonthPadding: 13,
initialMonth: (0, _moment["default"])(),
isAnimating: false,
numberOfMonths: 1,
modifiers: {},
orientation: _constants.HORIZONTAL_ORIENTATION,
onDayClick: function () {
function onDayClick() {}
return onDayClick;
}(),
onDayMouseEnter: function () {
function onDayMouseEnter() {}
return onDayMouseEnter;
}(),
onDayMouseLeave: function () {
function onDayMouseLeave() {}
return onDayMouseLeave;
}(),
onMonthChange: function () {
function onMonthChange() {}
return onMonthChange;
}(),
onYearChange: function () {
function onYearChange() {}
return onYearChange;
}(),
onMonthTransitionEnd: function () {
function onMonthTransitionEnd() {}
return onMonthTransitionEnd;
}(),
renderMonthText: null,
renderCalendarDay: undefined,
renderDayContents: null,
translationValue: null,
renderMonthElement: null,
daySize: _constants.DAY_SIZE,
focusedDate: null,
isFocused: false,
firstDayOfWeek: null,
setMonthTitleHeight: null,
isRTL: false,
transitionDuration: 200,
verticalBorderSpacing: undefined,
// i18n
monthFormat: 'MMMM YYYY',
// english locale
phrases: _defaultPhrases.CalendarDayPhrases,
dayAriaLabelFormat: undefined
};
function getMonths(initialMonth, numberOfMonths, withoutTransitionMonths) {
var month = initialMonth.clone();
if (!withoutTransitionMonths) month = month.subtract(1, 'month');
var months = [];
for (var i = 0; i < (withoutTransitionMonths ? numberOfMonths : numberOfMonths + 2); i += 1) {
months.push(month);
month = month.clone().add(1, 'month');
}
return months;
}
var CalendarMonthGrid =
/*#__PURE__*/
function (_ref) {
_inherits(CalendarMonthGrid, _ref);
_createClass(CalendarMonthGrid, [{
key: !_react["default"].PureComponent && "shouldComponentUpdate",
value: function () {
function value(nextProps, nextState) {
return (0, _reactAddonsShallowCompare["default"])(this, nextProps, nextState);
}
return value;
}()
}]);
function CalendarMonthGrid(props) {
var _this;
_classCallCheck(this, CalendarMonthGrid);
_this = _possibleConstructorReturn(this, _getPrototypeOf(CalendarMonthGrid).call(this, props));
var withoutTransitionMonths = props.orientation === _constants.VERTICAL_SCROLLABLE;
_this.state = {
months: getMonths(props.initialMonth, props.numberOfMonths, withoutTransitionMonths)
};
_this.isTransitionEndSupported = (0, _isTransitionEndSupported["default"])();
_this.onTransitionEnd = _this.onTransitionEnd.bind(_assertThisInitialized(_assertThisInitialized(_this)));
_this.setContainerRef = _this.setContainerRef.bind(_assertThisInitialized(_assertThisInitialized(_this)));
_this.locale = _moment["default"].locale();
_this.onMonthSelect = _this.onMonthSelect.bind(_assertThisInitialized(_assertThisInitialized(_this)));
_this.onYearSelect = _this.onYearSelect.bind(_assertThisInitialized(_assertThisInitialized(_this)));
return _this;
}
_createClass(CalendarMonthGrid, [{
key: "componentDidMount",
value: function () {
function componentDidMount() {
this.removeEventListener = (0, _consolidatedEvents.addEventListener)(this.container, 'transitionend', this.onTransitionEnd);
}
return componentDidMount;
}()
}, {
key: "componentWillReceiveProps",
value: function () {
function componentWillReceiveProps(nextProps) {
var _this2 = this;
var initialMonth = nextProps.initialMonth,
numberOfMonths = nextProps.numberOfMonths,
orientation = nextProps.orientation;
var months = this.state.months;
var _this$props = this.props,
prevInitialMonth = _this$props.initialMonth,
prevNumberOfMonths = _this$props.numberOfMonths;
var hasMonthChanged = !prevInitialMonth.isSame(initialMonth, 'month');
var hasNumberOfMonthsChanged = prevNumberOfMonths !== numberOfMonths;
var newMonths = months;
if (hasMonthChanged && !hasNumberOfMonthsChanged) {
if ((0, _isNextMonth["default"])(prevInitialMonth, initialMonth)) {
newMonths = months.slice(1);
newMonths.push(months[months.length - 1].clone().add(1, 'month'));
} else if ((0, _isPrevMonth["default"])(prevInitialMonth, initialMonth)) {
newMonths = months.slice(0, months.length - 1);
newMonths.unshift(months[0].clone().subtract(1, 'month'));
} else {
var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE;
newMonths = getMonths(initialMonth, numberOfMonths, withoutTransitionMonths);
}
}
if (hasNumberOfMonthsChanged) {
var _withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE;
newMonths = getMonths(initialMonth, numberOfMonths, _withoutTransitionMonths);
}
var momentLocale = _moment["default"].locale();
if (this.locale !== momentLocale) {
this.locale = momentLocale;
newMonths = newMonths.map(function (m) {
return m.locale(_this2.locale);
});
}
this.setState({
months: newMonths
});
}
return componentWillReceiveProps;
}()
}, {
key: "componentDidUpdate",
value: function () {
function componentDidUpdate() {
var _this$props2 = this.props,
isAnimating = _this$props2.isAnimating,
transitionDuration = _this$props2.transitionDuration,
onMonthTransitionEnd = _this$props2.onMonthTransitionEnd; // For IE9, immediately call onMonthTransitionEnd instead of
// waiting for the animation to complete. Similarly, if transitionDuration
// is set to 0, also immediately invoke the onMonthTransitionEnd callback
if ((!this.isTransitionEndSupported || !transitionDuration) && isAnimating) {
onMonthTransitionEnd();
}
}
return componentDidUpdate;
}()
}, {
key: "componentWillUnmount",
value: function () {
function componentWillUnmount() {
if (this.removeEventListener) this.removeEventListener();
}
return componentWillUnmount;
}()
}, {
key: "onTransitionEnd",
value: function () {
function onTransitionEnd() {
var onMonthTransitionEnd = this.props.onMonthTransitionEnd;
onMonthTransitionEnd();
}
return onTransitionEnd;
}()
}, {
key: "onMonthSelect",
value: function () {
function onMonthSelect(currentMonth, newMonthVal) {
var newMonth = currentMonth.clone();
var _this$props3 = this.props,
onMonthChange = _this$props3.onMonthChange,
orientation = _this$props3.orientation;
var months = this.state.months;
var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE;
var initialMonthSubtraction = months.indexOf(currentMonth);
if (!withoutTransitionMonths) {
initialMonthSubtraction -= 1;
}
newMonth.set('month', newMonthVal).subtract(initialMonthSubtraction, 'months');
onMonthChange(newMonth);
}
return onMonthSelect;
}()
}, {
key: "onYearSelect",
value: function () {
function onYearSelect(currentMonth, newYearVal) {
var newMonth = currentMonth.clone();
var _this$props4 = this.props,
onYearChange = _this$props4.onYearChange,
orientation = _this$props4.orientation;
var months = this.state.months;
var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE;
var initialMonthSubtraction = months.indexOf(currentMonth);
if (!withoutTransitionMonths) {
initialMonthSubtraction -= 1;
}
newMonth.set('year', newYearVal).subtract(initialMonthSubtraction, 'months');
onYearChange(newMonth);
}
return onYearSelect;
}()
}, {
key: "setContainerRef",
value: function () {
function setContainerRef(ref) {
this.container = ref;
}
return setContainerRef;
}()
}, {
key: "render",
value: function () {
function render() {
var _this3 = this;
var _this$props5 = this.props,
enableOutsideDays = _this$props5.enableOutsideDays,
firstVisibleMonthIndex = _this$props5.firstVisibleMonthIndex,
horizontalMonthPadding = _this$props5.horizontalMonthPadding,
isAnimating = _this$props5.isAnimating,
modifiers = _this$props5.modifiers,
numberOfMonths = _this$props5.numberOfMonths,
monthFormat = _this$props5.monthFormat,
orientation = _this$props5.orientation,
translationValue = _this$props5.translationValue,
daySize = _this$props5.daySize,
onDayMouseEnter = _this$props5.onDayMouseEnter,
onDayMouseLeave = _this$props5.onDayMouseLeave,
onDayClick = _this$props5.onDayClick,
renderMonthText = _this$props5.renderMonthText,
renderCalendarDay = _this$props5.renderCalendarDay,
renderDayContents = _this$props5.renderDayContents,
renderMonthElement = _this$props5.renderMonthElement,
onMonthTransitionEnd = _this$props5.onMonthTransitionEnd,
firstDayOfWeek = _this$props5.firstDayOfWeek,
focusedDate = _this$props5.focusedDate,
isFocused = _this$props5.isFocused,
isRTL = _this$props5.isRTL,
styles = _this$props5.styles,
phrases = _this$props5.phrases,
dayAriaLabelFormat = _this$props5.dayAriaLabelFormat,
transitionDuration = _this$props5.transitionDuration,
verticalBorderSpacing = _this$props5.verticalBorderSpacing,
setMonthTitleHeight = _this$props5.setMonthTitleHeight;
var months = this.state.months;
var isVertical = orientation === _constants.VERTICAL_ORIENTATION;
var isVerticalScrollable = orientation === _constants.VERTICAL_SCROLLABLE;
var isHorizontal = orientation === _constants.HORIZONTAL_ORIENTATION;
var calendarMonthWidth = (0, _getCalendarMonthWidth["default"])(daySize, horizontalMonthPadding);
var width = isVertical || isVerticalScrollable ? calendarMonthWidth : (numberOfMonths + 2) * calendarMonthWidth;
var transformType = isVertical || isVerticalScrollable ? 'translateY' : 'translateX';
var transformValue = "".concat(transformType, "(").concat(translationValue, "px)");
return _react["default"].createElement("div", _extends({}, (0, _reactWithStyles.css)(styles.CalendarMonthGrid, isHorizontal && styles.CalendarMonthGrid__horizontal, isVertical && styles.CalendarMonthGrid__vertical, isVerticalScrollable && styles.CalendarMonthGrid__vertical_scrollable, isAnimating && styles.CalendarMonthGrid__animating, isAnimating && transitionDuration && {
transition: "transform ".concat(transitionDuration, "ms ease-in-out")
}, _objectSpread({}, (0, _getTransformStyles["default"])(transformValue), {
width: width
})), {
ref: this.setContainerRef,
onTransitionEnd: onMonthTransitionEnd
}), months.map(function (month, i) {
var isVisible = i >= firstVisibleMonthIndex && i < firstVisibleMonthIndex + numberOfMonths;
var hideForAnimation = i === 0 && !isVisible;
var showForAnimation = i === 0 && isAnimating && isVisible;
var monthString = (0, _toISOMonthString["default"])(month);
return _react["default"].createElement("div", _extends({
key: monthString
}, (0, _reactWithStyles.css)(isHorizontal && styles.CalendarMonthGrid_month__horizontal, hideForAnimation && styles.CalendarMonthGrid_month__hideForAnimation, showForAnimation && !isVertical && !isRTL && {
position: 'absolute',
left: -calendarMonthWidth
}, showForAnimation && !isVertical && isRTL && {
position: 'absolute',
right: 0
}, showForAnimation && isVertical && {
position: 'absolute',
top: -translationValue
}, !isVisible && !isAnimating && styles.CalendarMonthGrid_month__hidden)), _react["default"].createElement(_CalendarMonth["default"], {
month: month,
isVisible: isVisible,
enableOutsideDays: enableOutsideDays,
modifiers: modifiers[monthString],
monthFormat: monthFormat,
orientation: orientation,
onDayMouseEnter: onDayMouseEnter,
onDayMouseLeave: onDayMouseLeave,
onDayClick: onDayClick,
onMonthSelect: _this3.onMonthSelect,
onYearSelect: _this3.onYearSelect,
renderMonthText: renderMonthText,
renderCalendarDay: renderCalendarDay,
renderDayContents: renderDayContents,
renderMonthElement: renderMonthElement,
firstDayOfWeek: firstDayOfWeek,
daySize: daySize,
focusedDate: isVisible ? focusedDate : null,
isFocused: isFocused,
phrases: phrases,
setMonthTitleHeight: setMonthTitleHeight,
dayAriaLabelFormat: dayAriaLabelFormat,
verticalBorderSpacing: verticalBorderSpacing,
horizontalMonthPadding: horizontalMonthPadding
}));
}));
}
return render;
}()
}]);
return CalendarMonthGrid;
}(_react["default"].PureComponent || _react["default"].Component);
CalendarMonthGrid.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {};
CalendarMonthGrid.defaultProps = defaultProps;
var _default = (0, _reactWithStyles.withStyles)(function (_ref2) {
var _ref2$reactDates = _ref2.reactDates,
color = _ref2$reactDates.color,
noScrollBarOnVerticalScrollable = _ref2$reactDates.noScrollBarOnVerticalScrollable,
spacing = _ref2$reactDates.spacing,
zIndex = _ref2$reactDates.zIndex;
return {
CalendarMonthGrid: {
background: color.background,
textAlign: 'left',
zIndex: zIndex
},
CalendarMonthGrid__animating: {
zIndex: zIndex + 1
},
CalendarMonthGrid__horizontal: {
position: 'absolute',
left: spacing.dayPickerHorizontalPadding
},
CalendarMonthGrid__vertical: {
margin: '0 auto'
},
CalendarMonthGrid__vertical_scrollable: _objectSpread({
margin: '0 auto',
overflowY: 'scroll'
}, noScrollBarOnVerticalScrollable && {
'-webkitOverflowScrolling': 'touch',
'::-webkit-scrollbar': {
'-webkit-appearance': 'none',
display: 'none'
}
}),
CalendarMonthGrid_month__horizontal: {
display: 'inline-block',
verticalAlign: 'top',
minHeight: '100%'
},
CalendarMonthGrid_month__hideForAnimation: {
position: 'absolute',
zIndex: zIndex - 1,
opacity: 0,
pointerEvents: 'none'
},
CalendarMonthGrid_month__hidden: {
visibility: 'hidden'
}
};
}, {
pureComponent: typeof _react["default"].PureComponent !== 'undefined'
})(CalendarMonthGrid);
exports["default"] = _default;