react-conventions
Version:
An open source set of React components that implement Ambassador's Design and UX patterns.
408 lines (335 loc) • 13.3 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _moment = require('moment');
var _moment2 = _interopRequireDefault(_moment);
var _SelectField = require('../SelectField/SelectField');
var _SelectField2 = _interopRequireDefault(_SelectField);
var _style = require('./style.scss');
var _style2 = _interopRequireDefault(_style);
var _OptClass = require('../internal/OptClass');
var _OptClass2 = _interopRequireDefault(_OptClass);
var _DateHelper = require('./DateHelper');
var _DateHelper2 = _interopRequireDefault(_DateHelper);
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; }
/**
* The DatePicker component.
*/
var DatePicker = function (_React$Component) {
_inherits(DatePicker, _React$Component);
function DatePicker(props) {
_classCallCheck(this, DatePicker);
var _this = _possibleConstructorReturn(this, (DatePicker.__proto__ || Object.getPrototypeOf(DatePicker)).call(this, props));
_this._dateHelper = _this.props.dateHelper ? _this.props.dateHelper : _DateHelper2.default;
_this.state = {
year: {
min: 0,
value: 0,
max: 0,
options: []
},
month: {
min: 0,
value: 0,
max: 0,
options: []
},
day: {
min: 0,
value: 0,
max: 0,
options: []
},
value: ''
};
_this._initDate = function (date, format) {
var dateObj = {
year: {
min: 0,
value: 0,
max: 0,
options: []
},
month: {
min: 0,
value: 0,
max: 0,
options: []
},
day: {
min: 0,
value: 0,
max: 0,
options: []
},
value: ''
};
var mDate = date === undefined ? _moment2.default.utc() : _moment2.default.utc(date, format);
// selected date values
dateObj.year.value = _this._dateHelper.getYear(mDate);
dateObj.month.value = _this._dateHelper.getMonth(mDate);
dateObj.day.value = _this._dateHelper.getDate(mDate);
dateObj.value = mDate.format(format);
// min & max values
dateObj.year.min = _this._getMinOrMax(_this.props.min, 'year');
dateObj.year.max = _this._getMinOrMax(_this.props.max, 'year');
dateObj.month.min = _this._getMinOrMax(_this.props.min, 'month');
dateObj.month.max = _this._getMinOrMax(_this.props.max, 'month');
dateObj.day.min = _this._getMinOrMax(_this.props.min, 'day');
dateObj.day.max = _this._getMinOrMax(_this.props.max, 'day');
// options
dateObj.year.options = _this._getYears(dateObj.year.min, dateObj.year.max);
dateObj.month.options = _this._getMonths(dateObj);
dateObj.day.options = _this._getDays(dateObj);
_this.setState(dateObj);
};
_this._getMinOrMax = function (minOrMax, type) {
var momentDate = void 0;
var value = void 0;
if (minOrMax[type] === 'current') {
momentDate = _moment2.default.utc();
} else if (minOrMax[type].indexOf('+') !== -1) {
momentDate = _moment2.default.utc().add(Math.abs(minOrMax[type]), type);
} else if (minOrMax[type].indexOf('-') !== -1) {
momentDate = _moment2.default.utc().subtract(Math.abs(minOrMax[type]), type);
} else {
value = minOrMax[type];
}
if (momentDate) {
switch (type) {
case 'year':
value = _this._dateHelper.getYear(momentDate);
break;
case 'month':
value = _this._dateHelper.getMonth(momentDate);
break;
case 'day':
value = _this._dateHelper.getDate(momentDate);
break;
}
}
return parseInt(value);
};
_this._getYears = function (min, max) {
var yearOptions = [];
for (var i = min; i <= max; i++) {
yearOptions.push({ value: i.toString() });
}
return yearOptions;
};
_this._getMonths = function (dateObj) {
var monthOptions = [];
var checkMin = dateObj.year.value === dateObj.year.min;
var checkMax = dateObj.year.value === dateObj.year.max;
var start = checkMin ? dateObj.month.min : 0;
var end = checkMax ? dateObj.month.max + 1 : 12;
for (var i = start; i < end; i++) {
monthOptions.push({ value: i.toString(), display: _moment2.default.utc(i + 1, 'MM').format('MMM') });
}
// if selected month is greater than max month, change it to max month
if (checkMax && dateObj.month.value > dateObj.month.max) {
dateObj.month.value = dateObj.month.max;
}
// if selected month is lower than min month, change it to min month
if (checkMin && dateObj.month.value < dateObj.month.min) {
dateObj.month.value = dateObj.month.min;
}
return monthOptions;
};
_this._getDays = function (dateObj) {
var dayOptions = [];
var checkMin = dateObj.year.value === dateObj.year.min && dateObj.month.value === dateObj.month.min;
var checkMax = dateObj.year.value === dateObj.year.max && dateObj.month.value === dateObj.month.max;
var daysInMonth = _moment2.default.utc(dateObj.year.value + '-' + (dateObj.month.value + 1), 'YYYY-M').daysInMonth();
var start = checkMin ? dateObj.day.min : 1;
var end = checkMax ? dateObj.day.max : daysInMonth;
for (var i = start; i <= end; i++) {
dayOptions.push({ value: i.toString() });
}
// if selected day is greater than max day in a month, change it to max day in a month
if (dateObj.day.value > daysInMonth) {
dateObj.day.value = daysInMonth;
}
// if selected day is greater than max day, change it to max day
if (checkMax && dateObj.day.value > dateObj.day.max) {
dateObj.day.value = dateObj.day.max;
}
// if selected day is lower than min day, change it to min day
if (checkMin && dateObj.day.value < dateObj.day.min) {
dateObj.day.value = dateObj.day.min;
}
dateObj.value = _this._getValue(dateObj, _this.props.format);
return dayOptions;
};
_this._getValue = function (state, format) {
return _moment2.default.utc().year(state.year.value).month(state.month.value).date(state.day.value).format(format);
};
_this.handleChangeYear = function (event) {
var state = _this.state;
state.year.value = parseInt(event.target.value);
state.value = _this._getValue(state, _this.props.format);
state.month.options = _this._getMonths(state);
state.day.options = _this._getDays(state);
_this.setState({
year: state.year,
month: state.month,
day: state.day,
value: state.value
}, function () {
_this.callback(state.value);
});
};
_this.handleChangeMonth = function (event) {
var state = _this.state;
state.month.value = parseInt(event.target.value);
state.value = _this._getValue(state, _this.props.format);
state.day.options = _this._getDays(state);
_this.setState({
month: state.month,
day: state.day,
value: state.value
}, function () {
_this.callback(state.value);
});
};
_this.handleChangeDay = function (event) {
var state = _this.state;
state.day.value = parseInt(event.target.value);
state.value = _this._getValue(state, _this.props.format);
_this.setState({
day: state.day,
value: state.value
}, function () {
_this.callback(state.value);
});
};
_this.callback = function (value) {
if (typeof _this.props.changeCallback === 'function') {
_this.props.changeCallback({
target: {
name: _this.props.name,
value: value
}
});
}
};
_this.componentWillMount = function () {
_this._initDate(_this.props.value, _this.props.format);
};
_this.componentWillReceiveProps = function (nextProps) {
if (nextProps.value !== _this.props.value) {
_this._initDate(nextProps.value, _this.props.format);
}
};
return _this;
}
/**
*
* @param {Object} minOrMax Example: { month: '-0', day: '-0', year: '-10' } | { month: 'current', day: 'current', year: 'current' }
* @param {String} type String. Options: ['year', 'month', 'day']
* @returns {Number} Calculated min or max value for given type
* @private
*/
/**
*
* @param {Integer} min First year
* @param {Integer} max Last year
* @returns {Array} Array of objects, ex. [{ value: '2010' }, (...), { value: '2020' }]
* @private
*/
/**
*
* @param {Object} dateObj State object
* @returns {Array} Array of objects, ex. [{ value: '0', display: 'Jan' }, (...), { value: '11', display: 'Dec' }]
* @private
*/
/**
*
* @param {Object} dateObj State object
* @returns {Array} Array of objects, ex. [{ value: '1' }, (...), { value: '31' }]
* @private
*/
/**
*
* @param {Object} state State object
* @param {String} format String with a valid moment.js format, ex. 'YYYY-MM-DD'
* @returns {String} Date string according to passed format, ex. '2016-09-04'
* @private
*/
_createClass(DatePicker, [{
key: 'render',
value: function render() {
var inlineSmallScreen = this.props.inlineSmallScreen ? _style2.default['inline-small-screen'] : null;
var componentClass = (0, _OptClass2.default)(_style2.default, ['datepicker-component', inlineSmallScreen], this.props.optClass);
return _react2.default.createElement(
'div',
{ className: componentClass },
_react2.default.createElement(_SelectField2.default, {
options: this.state.month.options,
valueProp: 'value',
displayProp: 'display',
value: this.state.month.value.toString(),
changeCallback: this.handleChangeMonth
}),
_react2.default.createElement(_SelectField2.default, {
options: this.state.day.options,
valueProp: 'value',
displayProp: 'value',
value: this.state.day.value.toString(),
changeCallback: this.handleChangeDay
}),
_react2.default.createElement(_SelectField2.default, {
options: this.state.year.options,
valueProp: 'value',
displayProp: 'value',
value: this.state.year.value.toString(),
changeCallback: this.handleChangeYear
})
);
}
}]);
return DatePicker;
}(_react2.default.Component);
DatePicker.defaultProps = {
min: { month: '-0', day: '-0', year: '-10' },
max: { month: '+0', day: '+0', year: '+10' },
format: 'YYYY-MM-DD'
};
DatePicker.propTypes = {
/**
* Max date - object with month, day, year.
*/
max: _react2.default.PropTypes.object,
/**
* Min date - object with month, day, year.
*/
min: _react2.default.PropTypes.object,
/**
* Date string.
*/
value: _react2.default.PropTypes.string,
/**
* Date format - any valid Moment.js format string.
*/
format: _react2.default.PropTypes.string,
/**
* A callback function to be called when the value changes.
*/
changeCallback: _react2.default.PropTypes.func,
/**
* Optional CSS class(es) to be used for local styles (string or array of strings)
*/
optClass: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.array, _react2.default.PropTypes.string]),
/**
* If true, will display the inputs inline on smaller screens (default 100% width)
*/
inlineSmallScreen: _react2.default.PropTypes.bool
};
exports.default = DatePicker;