UNPKG

react-date-picker

Version:

A carefully crafted date picker for React

525 lines (418 loc) 15.4 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); 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 _lodash = require('lodash.throttle'); var _lodash2 = _interopRequireDefault(_lodash); var _objectAssign = require('object-assign'); var _objectAssign2 = _interopRequireDefault(_objectAssign); var _TimeInput = require('../TimeInput'); var _toMoment2 = require('../toMoment'); var _toMoment3 = _interopRequireDefault(_toMoment2); var _parseFormat2 = require('./parseFormat'); var _parseFormat3 = _interopRequireDefault(_parseFormat2); var _forwardTime = require('../utils/forwardTime'); var _forwardTime2 = _interopRequireDefault(_forwardTime); 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 emptyFn = function emptyFn() {}; var BACKWARDS = { Backspace: 1, ArrowUp: 1, ArrowDown: 1, PageUp: 1, PageDown: 1 }; var DateFormatInput = function (_Component) { _inherits(DateFormatInput, _Component); function DateFormatInput(props) { _classCallCheck(this, DateFormatInput); var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DateFormatInput).call(this, props)); var _parseFormat = (0, _parseFormat3.default)(props.dateFormat); var positions = _parseFormat.positions; var matches = _parseFormat.matches; var defaultValue = props.defaultValue || Date.now(); var delay = props.changeDelay; _this.throttleSetValue = delay == -1 ? _this.setValue : (0, _lodash2.default)(_this.setValue, delay); var _this$getMinMax = _this.getMinMax(props); var minDate = _this$getMinMax.minDate; var maxDate = _this$getMinMax.maxDate; _this.state = { positions: positions, matches: matches, propsValue: props.value !== undefined, value: defaultValue, minDate: minDate, maxDate: maxDate }; return _this; } _createClass(DateFormatInput, [{ key: 'getMinMax', value: function getMinMax(props) { props = props || this.props; var minDate = null; if (props.minDate) { minDate = this.toMoment(props.minDate, props); } var maxDate = null; if (props.maxDate) { maxDate = this.toMoment(props.maxDate, props); } return { minDate: minDate, maxDate: maxDate }; } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { var _getMinMax = this.getMinMax(nextProps); var minDate = _getMinMax.minDate; var maxDate = _getMinMax.maxDate; this.setState({ minDate: minDate, maxDate: maxDate }); } }, { key: 'componentDidUpdate', value: function componentDidUpdate() { if (this.props.value !== undefined && this.caretPos && this.isFocused()) { this.setCaretPosition(this.caretPos); } } }, { key: 'toMoment', value: function toMoment(value, props) { props = props || this.props; return (0, _toMoment3.default)(value, { locale: props.locale, dateFormat: props.dateFormat || this.props.dateFormat }); } }, { key: 'render', value: function render() { var props = this.props; var value = this.state.propsValue ? props.value : this.state.value; var displayValue = this.displayValue = this.toMoment(value).format(props.dateFormat); var inputProps = (0, _objectAssign2.default)({}, props); delete inputProps.changeDelay; delete inputProps.date; delete inputProps.dateFormat; delete inputProps.isDateInput; delete inputProps.maxDate; delete inputProps.minDate; delete inputProps.stopPropagation; delete inputProps.updateOnWheel; if (typeof props.cleanup == 'function') { props.cleanup(inputProps); } return _react2.default.createElement('input', _extends({}, inputProps, { defaultValue: undefined, onFocus: this.onFocus, onBlur: this.onBlur, value: displayValue, onKeyDown: this.onKeyDown, onWheel: this.onWheel, onChange: this.onChange })); } }, { key: 'focus', value: function focus() { (0, _reactDom.findDOMNode)(this).focus(); } }, { key: 'onFocus', value: function onFocus(event) { if (this.props.onFocus) { this.props.onFocus(event); } this.setState({ focused: true }); } }, { key: 'onBlur', value: function onBlur(event) { if (this.props.onBlur) { this.props.onBlur(event); } this.setState({ focused: false }); } }, { key: 'isFocused', value: function isFocused() { return this.state.focused; } }, { key: 'onChange', value: function onChange(event) { event.stopPropagation(); } }, { key: 'onDirection', value: function onDirection(dir) { var event = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; this.onKeyDown({ key: dir > 0 ? 'ArrowUp' : 'ArrowDown', type: event.type || 'unknown', stopPropagation: typeof event.stopPropagation == 'function' ? function () { return event.stopPropagation(); } : emptyFn, preventDefault: typeof event.preventDefault == 'function' ? function () { return event.preventDefault(); } : emptyFn }); } }, { key: 'onWheel', value: function onWheel(event) { if (this.props.updateOnWheel && this.isFocused()) { this.onDirection(-event.deltaY, event); // this.onKeyDown({ // key: event.deltaY < 0 ? 'ArrowUp' : 'ArrowDown', // type: event.type, // stopPropagation: () => event.stopPropagation(), // preventDefault: () => event.preventDefault() // }) } if (this.props.onWheel) { this.props.onWheel(event); } } }, { key: 'onKeyDown', value: function onKeyDown(event) { var _this2 = this; var props = this.props; var key = event.key; var type = event.type; var which = event.which; if (key !== 'Unidentified' && which && which >= 65 && which <= 90) { key = ' '; } if (key != ' ' && key * 1 == key) { key = 'Unidentified'; } if (props.stopPropagation) { event.stopPropagation(); } var range = this.getSelectedRange(); var selectedValue = this.getSelectedValue(range); var value = this.displayValue; var _state = this.state; var positions = _state.positions; var matches = _state.matches; var valueStr = '' + value; var currentPosition = positions[range.start]; if (typeof currentPosition == 'string') { currentPosition = positions[range.start + (key in BACKWARDS ? -1 : 1)]; } if (!currentPosition) { currentPosition = positions[range.start - 1]; } if (props.onKeyDown && type == 'keydown') { if (props.onKeyDown(event, currentPosition) === false) { this.caretPos = range; return; } } var keyName = key; if (key == 'ArrowUp' || key == 'ArrowDown') { keyName = 'Arrow'; } var handlerName = 'handle' + keyName; var preventDefault = void 0; var newValue = void 0; var newCaretPos = void 0; if (currentPosition && currentPosition[handlerName]) { var returnValue = currentPosition[handlerName](currentPosition, { range: range, selectedValue: selectedValue, value: value, positions: positions, currentValue: valueStr.substring(currentPosition.start, currentPosition.end + 1), matches: matches, event: event, key: key, input: this.getInput(), setCaretPosition: function setCaretPosition() { return _this2.setCaretPosition.apply(_this2, arguments); } }); this.caretPos = range; if (returnValue && returnValue.value !== undefined) { newValue = valueStr.substring(0, currentPosition.start) + returnValue.value + valueStr.substring(currentPosition.end + 1); newCaretPos = returnValue.caretPos || range; if (newCaretPos === true) { newCaretPos = { start: currentPosition.start, end: currentPosition.end + 1 }; } preventDefault = returnValue.preventDefault !== false; } } if (preventDefault || key == 'Backspace' || key == 'Delete' || key == ' ') { if (!preventDefault) { this.setCaretPosition(this.caretPos = { start: range.start + (key == 'Backspace' ? -1 : 1) }); } preventDefault = true; } var config = { currentPosition: currentPosition, preventDefault: preventDefault, event: event, value: newValue, stop: false }; if (this.props.afterKeyDown && type == 'keydown') { this.props.afterKeyDown(config); } if (!config.stop && newCaretPos !== undefined) { var updateCaretPos = function updateCaretPos() { return _this2.setCaretPosition(newCaretPos); }; this.caretPos = newCaretPos; this.setStateValue(newValue, updateCaretPos, { key: key, oldValue: valueStr, currentPosition: currentPosition }); } if (config.preventDefault) { event.preventDefault(); } } }, { key: 'getInput', value: function getInput() { return (0, _reactDom.findDOMNode)(this); } }, { key: 'setCaretPosition', value: function setCaretPosition(pos) { var dom = this.getInput(); if (dom) { (0, _TimeInput.setCaretPosition)(dom, pos); } } }, { key: 'format', value: function format(mom, _format) { return mom.format(_format || this.props.dateFormat); } }, { key: 'setStateValue', value: function setStateValue(value, callback, _ref) { var key = _ref.key; var oldValue = _ref.oldValue; var currentPosition = _ref.currentPosition; var dateMoment = this.toMoment(value); if (!dateMoment.isValid()) { var dir = key == 'ArrowUp' || key == 'PageUp' ? 1 : -1; if (currentPosition.format == 'MM') { // updating the month dateMoment = this.toMoment(oldValue).add(dir, 'month'); } else { // updating the day dateMoment = dir > 0 ? // we've gone with +1 beyond max, so reset to 1 this.toMoment(oldValue).date(1) : // we've gone with -1 beyond max, so reset to max of month this.toMoment(oldValue).endOf('month'); } if (!dateMoment.isValid()) { return; } value = this.format(dateMoment); } var _state2 = this.state; var minDate = _state2.minDate; var maxDate = _state2.maxDate; if (minDate && dateMoment.isBefore(minDate)) { var clone = this.toMoment(dateMoment); // try with time dateMoment = (0, _forwardTime2.default)(clone, this.toMoment(minDate)); if (dateMoment.isBefore(minDate)) { // try without time dateMoment = this.toMoment(minDate); } value = this.format(dateMoment); } if (maxDate && dateMoment.isAfter(maxDate)) { var _clone = this.toMoment(dateMoment); dateMoment = (0, _forwardTime2.default)(_clone, this.toMoment(maxDate)); if (dateMoment.isAfter(maxDate)) { dateMoment = this.toMoment(maxDate); } value = this.format(dateMoment); } this.setState({ value: value, propsValue: false }, typeof callback == 'function' && callback); // if (this.props.value !== undefined) { if (this.props.onChange) { this.throttleSetValue(value, dateMoment); } } }, { key: 'setValue', value: function setValue(value, dateMoment) { if (this.props.value === undefined) { this.setState({ value: value, propsValue: false }); } else { this.setState({ propsValue: true, value: undefined }); } if (this.props.onChange) { this.props.onChange(value, { dateMoment: dateMoment || this.toMoment(value) }); } } }, { key: 'getSelectedRange', value: function getSelectedRange() { var dom = this.getInput(); return { start: (0, _TimeInput.getSelectionStart)(dom), end: (0, _TimeInput.getSelectionEnd)(dom) }; } }, { key: 'getSelectedValue', value: function getSelectedValue(range) { range = range || this.getSelectedRange(); var value = this.displayValue; return value.substring(range.start, range.end); } }]); return DateFormatInput; }(_reactClass2.default); exports.default = DateFormatInput; DateFormatInput.defaultProps = { isDateInput: true, stopPropagation: true, updateOnWheel: true, changeDelay: 100 }; DateFormatInput.propTypes = { dateFormat: _react.PropTypes.string.isRequired, value: function value(props, propName) { if (props[propName] !== undefined) { // console.warn('Due to performance considerations, TimeInput will only be uncontrolled.') } } };