Skip to content

Commit

Permalink
Merge pull request #34 from onefinestay/efficiency-refactors
Browse files Browse the repository at this point in the history
Efficiency refactors
  • Loading branch information
jkimbo committed May 12, 2015
2 parents e8dd8dd + e10b48f commit 75eb5b6
Show file tree
Hide file tree
Showing 22 changed files with 710 additions and 503 deletions.
219 changes: 174 additions & 45 deletions dist/DateRangePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@ var _reactAddons = require('react/addons');

var _reactAddons2 = _interopRequireDefault(_reactAddons);

var _moment = require('moment');
var _momentRange = require('moment-range');

var _moment2 = _interopRequireDefault(_moment);
var _momentRange2 = _interopRequireDefault(_momentRange);

var _immutable = require('immutable');

var _immutable2 = _interopRequireDefault(_immutable);

var _calendar = require('calendar');

var _calendar2 = _interopRequireDefault(_calendar);

var _utilsBemMixin = require('./utils/BemMixin');

var _utilsBemMixin2 = _interopRequireDefault(_utilsBemMixin);
Expand All @@ -38,11 +42,15 @@ var _PaginationArrow = require('./PaginationArrow');

var _PaginationArrow2 = _interopRequireDefault(_PaginationArrow);

var _utilsIsMomentRange = require('./utils/isMomentRange');

var _utilsIsMomentRange2 = _interopRequireDefault(_utilsIsMomentRange);

'use strict';

var PureRenderMixin = _reactAddons2['default'].addons.PureRenderMixin;
var absoluteMinimum = _moment2['default'](new Date(-8640000000000000 / 2)).startOf('day');
var absoluteMaximum = _moment2['default'](new Date(8640000000000000 / 2)).startOf('day');
var absoluteMinimum = _momentRange2['default'](new Date(-8640000000000000 / 2)).startOf('day');
var absoluteMaximum = _momentRange2['default'](new Date(8640000000000000 / 2)).startOf('day');

_reactAddons2['default'].initializeTouchEvents(true);

Expand Down Expand Up @@ -82,9 +90,9 @@ var DateRangePicker = _reactAddons2['default'].createClass({

if (!val) {
return null;
} else if (_moment2['default'].isMoment(val)) {
} else if (_momentRange2['default'].isMoment(val)) {
return null;
} else if (val.start && val.end && _moment2['default'].isMoment(val.start) && _moment2['default'].isMoment(val.end)) {
} else if (val.start && val.end && _momentRange2['default'].isMoment(val.start) && _momentRange2['default'].isMoment(val.end)) {
return null;
}
return new Error('Value must be a moment or a moment range');
Expand Down Expand Up @@ -123,9 +131,12 @@ var DateRangePicker = _reactAddons2['default'].createClass({
},

componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
var nextDateStates = this.getDateStates(nextProps);
var nextEnabledRange = this.getEnabledRange(nextProps);

this.setState({
dateStates: this.getDateStates(nextProps),
enabledRange: this.getEnabledRange(nextProps)
dateStates: this.state.dateStates && _immutable2['default'].is(this.state.dateStates, nextDateStates) ? this.state.dateStates : nextDateStates,
enabledRange: this.state.enabledRange && _immutable2['default'].is(this.state.enabledRange, nextEnabledRange) ? this.state.enabledRange : nextEnabledRange
});
},

Expand Down Expand Up @@ -170,10 +181,10 @@ var DateRangePicker = _reactAddons2['default'].createClass({
},

getEnabledRange: function getEnabledRange(props) {
var min = props.minimumDate ? _moment2['default'](props.minimumDate).startOf('day') : absoluteMinimum;
var max = props.maximumDate ? _moment2['default'](props.maximumDate).startOf('day') : absoluteMaximum;
var min = props.minimumDate ? _momentRange2['default'](props.minimumDate).startOf('day') : absoluteMinimum;
var max = props.maximumDate ? _momentRange2['default'](props.maximumDate).startOf('day') : absoluteMaximum;

return _moment2['default']().range(min, max);
return _momentRange2['default']().range(min, max);
},

getDateStates: function getDateStates(props) {
Expand All @@ -184,7 +195,7 @@ var DateRangePicker = _reactAddons2['default'].createClass({
var actualStates = [];
var minDate = absoluteMinimum;
var maxDate = absoluteMaximum;
var dateCursor = _moment2['default'](minDate).startOf('day');
var dateCursor = _momentRange2['default'](minDate).startOf('day');

var defs = _immutable2['default'].fromJS(stateDefinitions);

Expand All @@ -196,7 +207,7 @@ var DateRangePicker = _reactAddons2['default'].createClass({
if (!dateCursor.isSame(start)) {
actualStates.push({
state: defaultState,
range: _moment2['default']().range(dateCursor, start)
range: _momentRange2['default']().range(dateCursor, start)
});
}
actualStates.push(s);
Expand All @@ -205,7 +216,7 @@ var DateRangePicker = _reactAddons2['default'].createClass({

actualStates.push({
state: defaultState,
range: _moment2['default']().range(dateCursor, maxDate)
range: _momentRange2['default']().range(dateCursor, maxDate)
});

// sanitize date states
Expand All @@ -220,8 +231,124 @@ var DateRangePicker = _reactAddons2['default'].createClass({
});
},

onSelect: function onSelect(date) {
this.props.onSelect(_moment2['default'](date));
isDateDisabled: function isDateDisabled(date) {
return !this.state.enabledRange.contains(date);
},

isDateSelectable: function isDateSelectable(date) {
return this.dateRangesForDate(date).some(function (r) {
return r.get('selectable');
});
},

nonSelectableStateRanges: function nonSelectableStateRanges() {
return this.state.dateStates.filter(function (d) {
return !d.get('selectable');
});
},

dateRangesForDate: function dateRangesForDate(date) {
return this.state.dateStates.filter(function (d) {
return d.get('range').contains(date);
});
},

sanitizeRange: function sanitizeRange(range, forwards) {
/* Truncates the provided range at the first intersection
* with a non-selectable state. Using forwards to determine
* which direction to work
*/
var blockedRanges = this.nonSelectableStateRanges().map(function (r) {
return r.get('range');
});
var intersect = undefined;

if (forwards) {
intersect = blockedRanges.find(function (r) {
return range.intersect(r);
});
if (intersect) {
return _momentRange2['default']().range(range.start, intersect.start);
}
} else {
intersect = blockedRanges.findLast(function (r) {
return range.intersect(r);
});

if (intersect) {
return _momentRange2['default']().range(intersect.end, range.end);
}
}

if (range.start.isBefore(this.state.enabledRange.start)) {
return _momentRange2['default']().range(this.state.enabledRange.start, range.end);
}

if (range.end.isAfter(this.state.enabledRange.end)) {
return _momentRange2['default']().range(range.start, this.state.enabledRange.end);
}

return range;
},

highlightRange: function highlightRange(range) {
this.setState({
highlightedRange: range,
highlightedDate: null
});
if (typeof this.props.onHighlightRange === 'function') {
this.props.onHighlightRange(range, this.statesForRange(range));
}
},

onUnHighlightDate: function onUnHighlightDate(date) {
this.setState({
highlightedDate: null
});
},

onSelectDate: function onSelectDate(date) {
var selectionType = this.props.selectionType;
var selectedStartDate = this.state.selectedStartDate;

if (selectionType === 'range') {
if (selectedStartDate) {
this.completeRangeSelection();
} else if (!this.isDateDisabled(date) && this.isDateSelectable(date)) {
this.startRangeSelection(date);
}
} else {
if (!this.isDateDisabled(date) && this.isDateSelectable(date)) {
this.completeSelection();
}
}
},

onHighlightDate: function onHighlightDate(date) {
var selectionType = this.props.selectionType;
var selectedStartDate = this.state.selectedStartDate;

var datePair = undefined;
var range = undefined;
var forwards = undefined;

if (selectionType === 'range') {
if (selectedStartDate) {
datePair = _immutable2['default'].List.of(selectedStartDate, date).sortBy(function (d) {
return d.unix();
});
range = _momentRange2['default']().range(datePair.get(0), datePair.get(1));
forwards = range.start.unix() === selectedStartDate.unix();
range = this.sanitizeRange(range, forwards);
this.highlightRange(range);
} else if (!this.isDateDisabled(date) && this.isDateSelectable(date)) {
this.highlightDate(date);
}
} else {
if (!this.isDateDisabled(date) && this.isDateSelectable(date)) {
this.highlightDate(date);
}
}
},

startRangeSelection: function startRangeSelection(date) {
Expand All @@ -230,7 +357,7 @@ var DateRangePicker = _reactAddons2['default'].createClass({
selectedStartDate: date
});
if (typeof this.props.onSelectStart === 'function') {
this.props.onSelectStart(_moment2['default'](date));
this.props.onSelectStart(_momentRange2['default'](date));
}
},

Expand Down Expand Up @@ -277,7 +404,7 @@ var DateRangePicker = _reactAddons2['default'].createClass({
}
},

onHighlightDate: function onHighlightDate(date) {
highlightDate: function highlightDate(date) {
this.setState({
highlightedDate: date
});
Expand All @@ -286,24 +413,8 @@ var DateRangePicker = _reactAddons2['default'].createClass({
}
},

onHighlightRange: function onHighlightRange(range) {
this.setState({
highlightedRange: range,
highlightedDate: null
});
if (typeof this.props.onHighlightRange === 'function') {
this.props.onHighlightRange(range, this.statesForRange(range));
}
},

onUnHighlightDate: function onUnHighlightDate() {
this.setState({
highlightedDate: null
});
},

getMonthDate: function getMonthDate() {
return _moment2['default'](new Date(this.state.year, this.state.month, 1));
return _momentRange2['default'](new Date(this.state.year, this.state.month, 1));
},

canMoveBack: function canMoveBack() {
Expand Down Expand Up @@ -363,11 +474,11 @@ var DateRangePicker = _reactAddons2['default'].createClass({
var enabledRange = _state.enabledRange;
var month = _state.month;

if (_moment2['default']({ years: year, months: month, date: 1 }).unix() < enabledRange.start.unix()) {
if (_momentRange2['default']({ years: year, months: month, date: 1 }).unix() < enabledRange.start.unix()) {
month = enabledRange.start.month();
}

if (_moment2['default']({ years: year, months: month + 1, date: 1 }).unix() > enabledRange.end.unix()) {
if (_momentRange2['default']({ years: year, months: month + 1, date: 1 }).unix() > enabledRange.end.unix()) {
month = enabledRange.end.month();
}

Expand Down Expand Up @@ -398,7 +509,6 @@ var DateRangePicker = _reactAddons2['default'].createClass({
var highlightedDate = _state2.highlightedDate;
var highlightedRange = _state2.highlightedRange;
var highlightStartDate = _state2.highlightStartDate;
var selectedStartDate = _state2.selectedStartDate;

var monthDate = this.getMonthDate();
var year = monthDate.year();
Expand All @@ -408,6 +518,30 @@ var DateRangePicker = _reactAddons2['default'].createClass({

monthDate.add(index, 'months');

var cal = new _calendar2['default'].Calendar(firstOfWeek);
var monthDates = _immutable2['default'].fromJS(cal.monthDates(monthDate.year(), monthDate.month()));
var monthStart = monthDates.first().first();
var monthEnd = monthDates.last().last();
var monthRange = _momentRange2['default']().range(monthStart, monthEnd);

if (_momentRange2['default'].isMoment(value)) {
if (!monthRange.contains(value)) {
value = null;
}
} else if (_utilsIsMomentRange2['default'](value)) {
if (!monthRange.overlaps(value)) {
value = null;
}
}

if (!_momentRange2['default'].isMoment(highlightedDate) || !monthRange.contains(highlightedDate)) {
highlightedDate = null;
}

if (!_utilsIsMomentRange2['default'](highlightedRange) || !monthRange.overlaps(highlightedRange)) {
highlightedRange = null;
}

props = {
bemBlock: bemBlock,
bemNamespace: bemNamespace,
Expand All @@ -417,23 +551,18 @@ var DateRangePicker = _reactAddons2['default'].createClass({
hideSelection: hideSelection,
highlightedDate: highlightedDate,
highlightedRange: highlightedRange,
highlightStartDate: highlightStartDate,
index: index,
key: key,
selectedStartDate: selectedStartDate,
selectionType: selectionType,
value: value,
maxIndex: numberOfCalendars - 1,
firstOfMonth: monthDate,
onMonthChange: this.changeMonth,
onYearChange: this.changeYear,
onHighlightRange: this.onHighlightRange,
onSelectDate: this.onSelectDate,
onHighlightDate: this.onHighlightDate,
onUnHighlightDate: this.onUnHighlightDate,
onSelect: this.onSelect,
startRangeSelection: this.startRangeSelection,
completeSelection: this.completeSelection,
completeRangeSelection: this.completeRangeSelection,
dateRangesForDate: this.dateRangesForDate,
dateComponent: _calendarCalendarDate2['default']
};

Expand Down
Loading

0 comments on commit 75eb5b6

Please sign in to comment.