react-date-picker
Version:
A carefully crafted date picker for React
681 lines (526 loc) • 20.6 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getInitialState = exports.isValidActiveDate = exports.isDateInMinMax = exports.prepareDate = exports.prepareDateProps = exports.prepareMinMax = exports.prepareViewDate = exports.prepareActiveDate = exports.onKeyDown = exports.navigate = exports.gotoViewDate = exports.confirm = exports.select = exports.onActiveDateChange = exports.onViewDateChange = exports.onChange = undefined;
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; };
var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactClass = require('react-class');
var _reactClass2 = _interopRequireDefault(_reactClass);
var _objectAssign = require('object-assign');
var _objectAssign2 = _interopRequireDefault(_objectAssign);
var _reactFlex = require('react-flex');
var _moment = require('moment');
var _moment2 = _interopRequireDefault(_moment);
var _times = require('./utils/times');
var _times2 = _interopRequireDefault(_times);
var _toMoment2 = require('./toMoment');
var _toMoment3 = _interopRequireDefault(_toMoment2);
var _join = require('./join');
var _join2 = _interopRequireDefault(_join);
var _bemFactory = require('./bemFactory');
var _bemFactory2 = _interopRequireDefault(_bemFactory);
var _onKeyDown = require('./MonthView/onKeyDown');
var _onKeyDown2 = _interopRequireDefault(_onKeyDown);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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; }
var bem = (0, _bemFactory2.default)('react-date-picker__decade-view');
var ARROWS = {
prev: _react2.default.createElement(
'svg',
{ height: '24', viewBox: '0 0 24 24', width: '24' },
_react2.default.createElement('path', { d: 'M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z' }),
_react2.default.createElement('path', { d: 'M0 0h24v24H0z', fill: 'none' })
),
next: _react2.default.createElement(
'svg',
{ height: '24', viewBox: '0 0 24 24', width: '24' },
_react2.default.createElement('path', { d: 'M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z' }),
_react2.default.createElement('path', { d: 'M0 0h24v24H0z', fill: 'none' })
)
};
var getDecadeStartYear = function getDecadeStartYear(mom) {
var year = mom.get('year');
return year - year % 10;
};
var getDecadeEndYear = function getDecadeEndYear(mom) {
return getDecadeStartYear(mom) + 9;
};
var NAV_KEYS = {
ArrowUp: function ArrowUp(mom) {
return mom.add(-5, 'year');
},
ArrowDown: function ArrowDown(mom) {
return mom.add(5, 'year');
},
ArrowLeft: function ArrowLeft(mom) {
return mom.add(-1, 'year');
},
ArrowRight: function ArrowRight(mom) {
return mom.add(1, 'year');
},
Home: function Home(mom) {
return mom.set('year', getDecadeStartYear(mom));
},
End: function End(mom) {
return mom.set('year', getDecadeEndYear(mom));
},
PageUp: function PageUp(mom) {
return mom.add(-10, 'year');
},
PageDown: function PageDown(mom) {
return mom.add(10, 'year');
}
};
var isDateInMinMax = function isDateInMinMax(timestamp, props) {
if (props.minDate && timestamp < props.minDate) {
return false;
}
if (props.maxDate && timestamp > props.maxDate) {
return false;
}
return true;
};
var isValidActiveDate = function isValidActiveDate(timestamp, props) {
if (!props) {
throw new Error('props is mandatory in isValidActiveDate');
}
return isDateInMinMax(timestamp, props);
};
var _select = function _select(_ref, event) {
var dateMoment = _ref.dateMoment;
var timestamp = _ref.timestamp;
if (this.props.select) {
return this.props.select({ dateMoment: dateMoment, timestamp: timestamp }, event);
}
if (!timestamp) {
timestamp = +dateMoment;
}
this.gotoViewDate({ dateMoment: dateMoment, timestamp: timestamp });
this.onChange({ dateMoment: dateMoment, timestamp: timestamp }, event);
return undefined;
};
var _confirm = function _confirm(date, event) {
event.preventDefault();
if (this.props.confirm) {
return this.props.confirm(date, event);
}
var dateMoment = this.toMoment(date);
var timestamp = +dateMoment;
this.select({ dateMoment: dateMoment, timestamp: timestamp }, event);
if (this.props.onConfirm) {
this.props.onConfirm({ dateMoment: dateMoment, timestamp: timestamp });
}
return undefined;
};
var _onActiveDateChange = function _onActiveDateChange(_ref2) {
var dateMoment = _ref2.dateMoment;
var timestamp = _ref2.timestamp;
if (!isValidActiveDate(timestamp, this.p)) {
return;
}
if (this.props.activeDate === undefined) {
this.setState({
activeDate: timestamp
});
}
if (this.props.onActiveDateChange) {
var dateString = this.format(dateMoment);
this.props.onActiveDateChange(dateString, { dateMoment: dateMoment, timestamp: timestamp, dateString: dateString });
}
};
var _onViewDateChange = function _onViewDateChange(_ref3) {
var dateMoment = _ref3.dateMoment;
var timestamp = _ref3.timestamp;
if (dateMoment && timestamp === undefined) {
timestamp = +dateMoment;
}
if (this.props.constrainViewDate && !isDateInMinMax(timestamp, this.p)) {
return;
}
if (this.props.viewDate === undefined) {
this.setState({
viewDate: timestamp
});
}
if (this.props.onViewDateChange) {
var dateString = this.format(dateMoment);
this.props.onViewDateChange(dateString, { dateMoment: dateMoment, dateString: dateString, timestamp: timestamp });
}
};
var _onChange = function _onChange(_ref4, event) {
var dateMoment = _ref4.dateMoment;
var timestamp = _ref4.timestamp;
if (this.props.date === undefined) {
this.setState({
date: timestamp
});
}
if (this.props.onChange) {
var dateString = this.format(dateMoment);
this.props.onChange(dateString, { dateMoment: dateMoment, timestamp: timestamp, dateString: dateString }, event);
}
};
var _navigate = function _navigate(direction, event) {
var _this = this;
var props = this.p;
var getNavigationDate = function getNavigationDate(dir, date, dateFormat) {
var mom = _moment2.default.isMoment(date) ? date : _this.toMoment(date, dateFormat);
if (typeof dir == 'function') {
return dir(mom);
}
return mom;
};
if (props.navigate) {
return props.navigate(direction, event, getNavigationDate);
}
event.preventDefault();
if (props.activeDate) {
var nextMoment = getNavigationDate(direction, props.activeDate);
this.gotoViewDate({ dateMoment: nextMoment });
}
return undefined;
};
var _gotoViewDate = function _gotoViewDate(_ref5) {
var dateMoment = _ref5.dateMoment;
var timestamp = _ref5.timestamp;
if (!timestamp) {
timestamp = dateMoment == null ? null : +dateMoment;
}
this.onViewDateChange({ dateMoment: dateMoment, timestamp: timestamp });
this.onActiveDateChange({ dateMoment: dateMoment, timestamp: timestamp });
};
var prepareDate = function prepareDate(props, state) {
return props.date === undefined ? state.date : props.date;
};
var prepareViewDate = function prepareViewDate(props, state) {
var viewDate = props.viewDate === undefined ? state.viewDate : props.viewDate;
if (!viewDate && props.date) {
return props.date;
}
return viewDate;
};
var prepareActiveDate = function prepareActiveDate(props, state) {
var activeDate = props.activeDate === undefined ? state.activeDate || prepareDate(props, state) : props.activeDate;
return activeDate;
};
var prepareMinMax = function prepareMinMax(props) {
var minDate = props.minDate;
var maxDate = props.maxDate;
var result = {};
if (minDate != null) {
result.minDateMoment = (0, _toMoment3.default)(props.minDate, props).startOf(props.adjustMinDateStartOf);
result.minDate = +result.minDateMoment;
}
if (maxDate != null) {
result.maxDateMoment = (0, _toMoment3.default)(props.maxDate, props).endOf(props.adjustMaxDateStartOf);
result.maxDate = +result.maxDateMoment;
}
return result;
};
var prepareDateProps = function prepareDateProps(props, state) {
var result = {};
(0, _objectAssign2.default)(result, prepareMinMax(props));
result.date = prepareDate(props, state);
result.viewDate = prepareViewDate(props, state);
var activeDate = prepareActiveDate(props, state);
if (result.date != null) {
result.moment = (0, _toMoment3.default)(result.date, props);
if (props.adjustDateStartOf) {
result.moment.startOf(props.adjustDateStartOf);
}
result.timestamp = +result.moment;
}
if (activeDate) {
result.activeMoment = (0, _toMoment3.default)(activeDate, props);
if (props.adjustDateStartOf) {
result.activeMoment.startOf(props.adjustDateStartOf);
}
result.activeDate = +result.activeMoment;
}
var viewMoment = (0, _toMoment3.default)(result.viewDate, props);
if (props.constrainViewDate && result.minDate != null && viewMoment.isBefore(result.minDate)) {
result.minConstrained = true;
viewMoment = (0, _toMoment3.default)(result.minDate, props);
}
if (props.constrainViewDate && result.maxDate != null && viewMoment.isAfter(result.maxDate)) {
result.maxConstrained = true;
viewMoment = (0, _toMoment3.default)(result.maxDate, props);
}
if (props.adjustDateStartOf) {
viewMoment.startOf(props.adjustDateStartOf);
}
result.viewMoment = viewMoment;
return result;
};
var getInitialState = function getInitialState(props) {
return {
date: props.defaultDate,
activeDate: props.defaultActiveDate,
viewDate: props.defaultViewDate
};
};
var DecadeView = function (_Component) {
_inherits(DecadeView, _Component);
function DecadeView(props) {
_classCallCheck(this, DecadeView);
var _this2 = _possibleConstructorReturn(this, Object.getPrototypeOf(DecadeView).call(this, props));
_this2.state = getInitialState(props);
return _this2;
}
_createClass(DecadeView, [{
key: 'getYearsInDecade',
value: function getYearsInDecade(value) {
var _this3 = this;
var year = getDecadeStartYear(this.toMoment(value));
var start = this.toMoment('' + year, 'YYYY').startOf('year');
return (0, _times2.default)(10).map(function (i) {
return _this3.toMoment(start).add(i, 'year');
});
}
}, {
key: 'toMoment',
value: function toMoment(date, format) {
return (0, _toMoment3.default)(date, format, this.props);
}
}, {
key: 'render',
value: function render() {
var props = this.p = (0, _objectAssign2.default)({}, this.props);
if (props.onlyCompareYear) {
// props.adjustDateStartOf = null
}
var dateProps = prepareDateProps(props, this.state);
(0, _objectAssign2.default)(props, dateProps);
var yearsInView = this.getYearsInDecade(props.viewMoment);
var className = (0, _join2.default)(props.className, bem(), props.theme && bem(null, 'theme-' + props.theme));
var children = this.renderYears(props, yearsInView);
var align = 'stretch';
var column = true;
if (props.navigation) {
column = false;
align = 'center';
children = [this.renderNav(-1), _react2.default.createElement(_reactFlex.Flex, { inline: true, flex: true, column: true, alignItems: 'stretch', children: children }), this.renderNav(1)];
}
var flexProps = (0, _objectAssign2.default)({}, this.props);
delete flexProps.activeDate;
delete flexProps.adjustDateStartOf;
delete flexProps.adjustMaxDateStartOf;
delete flexProps.adjustMinDateStartOf;
delete flexProps.arrows;
delete flexProps.cleanup;
delete flexProps.constrainViewDate;
delete flexProps.date;
delete flexProps.dateFormat;
delete flexProps.isDecadeView;
delete flexProps.maxDate;
delete flexProps.minDate;
delete flexProps.navigation;
delete flexProps.navKeys;
delete flexProps.onActiveDateChange;
delete flexProps.onConfirm;
delete flexProps.onlyCompareYear;
delete flexProps.onViewDateChange;
delete flexProps.perRow;
delete flexProps.theme;
delete flexProps.viewDate;
delete flexProps.yearFormat;
if (typeof props.cleanup == 'function') {
props.cleanup(flexProps);
}
return _react2.default.createElement(_reactFlex.Flex, _extends({
inline: true,
column: column,
alignItems: align,
tabIndex: 0
}, flexProps, {
onKeyDown: this.onKeyDown,
className: className,
children: children
}));
}
}, {
key: 'renderNav',
value: function renderNav(dir) {
var _this4 = this;
var props = this.p;
var name = dir == -1 ? 'prev' : 'next';
var navMoment = this.toMoment(props.viewMoment).add(dir * 10, 'year');
var disabled = dir == -1 ? props.minDateMoment && getDecadeEndYear(navMoment) < getDecadeEndYear(props.minDateMoment) : props.maxDateMoment && getDecadeEndYear(navMoment) > getDecadeEndYear(props.maxDateMoment);
var className = (0, _join2.default)(bem('arrow'), bem('arrow--' + name), disabled && bem('arrow--disabled'));
var arrow = props.arrows[name] || ARROWS[name];
var arrowProps = {
className: className,
onClick: !disabled ? function () {
return _this4.onViewDateChange({ dateMoment: navMoment });
} : null,
children: arrow,
disabled: disabled
};
if (props.renderNavigation) {
return props.renderNavigation(arrowProps, props);
}
return _react2.default.createElement('div', arrowProps);
}
}, {
key: 'renderYears',
value: function renderYears(props, years) {
var nodes = years.map(this.renderYear);
var perRow = props.perRow;
var buckets = (0, _times2.default)(Math.ceil(nodes.length / perRow)).map(function (i) {
return nodes.slice(i * perRow, (i + 1) * perRow);
});
return buckets.map(function (bucket, i) {
return _react2.default.createElement(
_reactFlex.Flex,
{
alignItems: 'center',
flex: true,
row: true,
inline: true,
key: 'row_' + i,
className: 'dp-row'
},
bucket
);
});
}
}, {
key: 'renderYear',
value: function renderYear(dateMoment) {
var props = this.p;
var yearText = this.format(dateMoment);
var timestamp = +dateMoment;
var isActiveDate = props.onlyCompareYear && props.activeMoment ? dateMoment.get('year') == props.activeMoment.get('year') : timestamp === props.activeDate;
var isValue = props.onlyCompareYear && props.moment ? dateMoment.get('year') == props.moment.get('year') : timestamp === props.timestamp;
var className = (0, _join2.default)(bem('year'), isActiveDate && bem('year', 'active'), isValue && bem('year', 'value'), props.minDate != null && timestamp < props.minDate && bem('year', 'disabled'), props.maxDate != null && timestamp > props.maxDate && bem('year', 'disabled'));
var onClick = this.handleClick.bind(this, {
dateMoment: dateMoment,
timestamp: timestamp
});
return _react2.default.createElement(
_reactFlex.Item,
{
key: yearText,
className: className,
onClick: onClick
},
yearText
);
}
}, {
key: 'format',
value: function format(mom, _format) {
_format = _format || this.props.yearFormat;
return mom.format(_format);
}
}, {
key: 'handleClick',
value: function handleClick(_ref6, event) {
var timestamp = _ref6.timestamp;
var dateMoment = _ref6.dateMoment;
event.target.value = timestamp;
var props = this.p;
if (props.minDate && timestamp < props.minDate) {
return;
}
if (props.maxDate && timestamp > props.maxDate) {
return;
}
this.select({ dateMoment: dateMoment, timestamp: timestamp }, event);
}
}, {
key: 'onKeyDown',
value: function onKeyDown(event) {
return _onKeyDown2.default.call(this, event);
}
}, {
key: 'confirm',
value: function confirm(date, event) {
return _confirm.call(this, date, event);
}
}, {
key: 'navigate',
value: function navigate(direction, event) {
return _navigate.call(this, direction, event);
}
}, {
key: 'select',
value: function select(_ref7, event) {
var dateMoment = _ref7.dateMoment;
var timestamp = _ref7.timestamp;
return _select.call(this, { dateMoment: dateMoment, timestamp: timestamp }, event);
}
}, {
key: 'onViewDateChange',
value: function onViewDateChange(_ref8) {
var dateMoment = _ref8.dateMoment;
var timestamp = _ref8.timestamp;
return _onViewDateChange.call(this, { dateMoment: dateMoment, timestamp: timestamp });
}
}, {
key: 'gotoViewDate',
value: function gotoViewDate(_ref9) {
var dateMoment = _ref9.dateMoment;
var timestamp = _ref9.timestamp;
return _gotoViewDate.call(this, { dateMoment: dateMoment, timestamp: timestamp });
}
}, {
key: 'onActiveDateChange',
value: function onActiveDateChange(_ref10) {
var dateMoment = _ref10.dateMoment;
var timestamp = _ref10.timestamp;
return _onActiveDateChange.call(this, { dateMoment: dateMoment, timestamp: timestamp });
}
}, {
key: 'onChange',
value: function onChange(_ref11, event) {
var dateMoment = _ref11.dateMoment;
var timestamp = _ref11.timestamp;
return _onChange.call(this, { dateMoment: dateMoment, timestamp: timestamp }, event);
}
}, {
key: 'focus',
value: function focus() {
(0, _reactDom.findDOMNode)(this).focus();
}
}]);
return DecadeView;
}(_reactClass2.default);
exports.default = DecadeView;
DecadeView.defaultProps = {
isDecadeView: true,
arrows: {},
navigation: true,
constrainViewDate: true,
navKeys: NAV_KEYS,
theme: 'default',
yearFormat: 'YYYY',
dateFormat: 'YYYY-MM-DD',
perRow: 5,
onlyCompareYear: true,
adjustDateStartOf: 'year',
adjustMinDateStartOf: 'year',
adjustMaxDateStartOf: 'year'
};
exports.onChange = _onChange;
exports.onViewDateChange = _onViewDateChange;
exports.onActiveDateChange = _onActiveDateChange;
exports.select = _select;
exports.confirm = _confirm;
exports.gotoViewDate = _gotoViewDate;
exports.navigate = _navigate;
exports.onKeyDown = _onKeyDown2.default;
exports.prepareActiveDate = prepareActiveDate;
exports.prepareViewDate = prepareViewDate;
exports.prepareMinMax = prepareMinMax;
exports.prepareDateProps = prepareDateProps;
exports.prepareDate = prepareDate;
exports.isDateInMinMax = isDateInMinMax;
exports.isValidActiveDate = isValidActiveDate;
exports.getInitialState = getInitialState;