material-date-range-picker
Version:
React components, that implements material design pickers for material-ui v1
598 lines (496 loc) • 19.6 kB
JavaScript
import _taggedTemplateLiteralLoose from '@babel/runtime/helpers/esm/taggedTemplateLiteralLoose';
import styled from 'styled-components';
import Divider from '@material-ui/core/Divider';
import Typography from '@material-ui/core/Typography';
import { withTheme } from '@material-ui/core/styles';
import { fade } from '@material-ui/core/styles/colorManipulator';
import React, { Fragment, PureComponent } from 'react';
import { isSameMonth, isWithinRange, isSameDay, isToday, getYear, addYears, format, isThisYear, isSameYear, getMonth, addMonths, isThisMonth, isAfter, isBefore } from 'date-fns';
import _inheritsLoose from '@babel/runtime/helpers/esm/inheritsLoose';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import NavigateNext from '@material-ui/icons/NavigateNext';
import NavigateBefore from '@material-ui/icons/NavigateBefore';
import ArrowDropDown from '@material-ui/icons/ArrowDropDown';
import ArrowDropUp from '@material-ui/icons/ArrowDropUp';
import ClearAll from '@material-ui/icons/ClearAll';
import Card from '@material-ui/core/Card';
import _objectWithoutPropertiesLoose from '@babel/runtime/helpers/esm/objectWithoutPropertiesLoose';
import _extends from '@babel/runtime/helpers/esm/extends';
import PropTypes from 'prop-types';
import Downshift from 'downshift';
import TextField from '@material-ui/core/TextField';
import Kalendaryo from 'kalendaryo';
function _templateObject6() {
var data = _taggedTemplateLiteralLoose(["\n && {\n * {\n color: ", ";\n }\n }\n"]);
_templateObject6 = function _templateObject6() {
return data;
};
return data;
}
function _templateObject5() {
var data = _taggedTemplateLiteralLoose(["\n border-radius: ", ";\n border-color: ", ";\n box-sizing: border-box;\n cursor: pointer;\n background: ", ";\n && {\n * {\n color: ", ";\n }\n }\n"]);
_templateObject5 = function _templateObject5() {
return data;
};
return data;
}
function _templateObject4() {
var data = _taggedTemplateLiteralLoose(["\n width: calc(\n 100% * ", " -\n ", "px\n );\n padding-top: calc((100% / 7) - 2px);\n margin: 2px 0;\n position: relative;\n border: 1px solid transparent;\n"]);
_templateObject4 = function _templateObject4() {
return data;
};
return data;
}
function _templateObject3() {
var data = _taggedTemplateLiteralLoose(["\n && {\n position: absolute;\n display: flex;\n justify-content: center;\n align-items: center;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n }\n"]);
_templateObject3 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2() {
var data = _taggedTemplateLiteralLoose(["\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n"]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject() {
var data = _taggedTemplateLiteralLoose(["\n && {\n margin: 0 -8px 8px;\n }\n"]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
function fromTheme(theme, key, def) {
if (!theme || !theme.dateRangePicker) return def;
var value = theme.dateRangePicker[key];
return typeof value !== 'undefined' ? value : def;
}
var HeaderDivider = styled(Divider)(_templateObject());
var Row = styled.div(_templateObject2());
var Text = styled(Typography)(_templateObject3());
var Cell = styled.div(_templateObject4(), function (_ref) {
var _ref$widthPercentage = _ref.widthPercentage,
widthPercentage = _ref$widthPercentage === void 0 ? 1 / 7 : _ref$widthPercentage;
return widthPercentage;
}, function (_ref2) {
var horizontalSpacing = _ref2.horizontalSpacing;
return horizontalSpacing ? 3 : 0;
});
function getBorderRadius(_ref3) {
var isInRange = _ref3.isInRange,
isRangeStart = _ref3.isRangeStart,
isRangeEnd = _ref3.isRangeEnd;
if (isRangeStart) return '999px 0 0 999px';
if (isRangeEnd) return '0 999px 999px 0';
if (isInRange) return 0;
return '999px';
}
function getBackground(_ref4) {
var isInRange = _ref4.isInRange,
isSelected = _ref4.isSelected,
theme = _ref4.theme,
isHighlighted = _ref4.isHighlighted;
if (isSelected) return fromTheme(theme, 'selected', theme.palette.primary.main);
if (isHighlighted) return fromTheme(theme, 'highlighted', '#ebebeb');
if (isInRange) return fromTheme(theme, 'inRange', theme.palette.primary.light);
return '#fff';
}
function getColor(props) {
var isLessImportant = props.isLessImportant,
isSelected = props.isSelected,
theme = props.theme;
var color = theme.palette.getContrastText(getBackground(props));
if (isSelected || !isLessImportant) return color;
return fromTheme(theme, 'lessImportant', fade(color, 0.54));
}
var SelectableCell = withTheme()(styled(Cell)(_templateObject5(), getBorderRadius, function (_ref5) {
var theme = _ref5.theme,
isCurrent = _ref5.isCurrent;
return isCurrent ? fromTheme(theme, 'current', '#9e9e9e') : 'transparent';
}, getBackground, getColor));
var Header = withTheme()(styled(Cell)(_templateObject6(), function (_ref6) {
var theme = _ref6.theme;
return fromTheme(theme, 'header', '#9e9e9e');
}));
var dateIsInRange = function dateIsInRange(date, fromDate, toDate) {
return fromDate && toDate && isWithinRange(date, fromDate, toDate);
};
var isSelected = function isSelected(date, compareDate) {
return compareDate && isSameDay(date, compareDate);
};
function DaySelect(props) {
var fromDate = props.fromDate,
toDate = props.toDate,
getWeeksInMonth = props.getWeeksInMonth,
getDayLabelsInWeek = props.getDayLabelsInWeek,
date = props.date,
getItemProps = props.getItemProps,
getMenuProps = props.getMenuProps,
highlightedIndex = props.highlightedIndex,
setHighlightedIndex = props.setHighlightedIndex;
var weeksInMonth = getWeeksInMonth();
var isInOtherMonth = function isInOtherMonth(dateValue) {
return !isSameMonth(date, dateValue);
};
return React.createElement(Fragment, null, React.createElement(Row, null, getDayLabelsInWeek('dd').map(function (day) {
return React.createElement(Header, {
key: day
}, React.createElement(Text, null, day));
})), React.createElement(HeaderDivider, null), React.createElement(Row, getMenuProps({
onMouseLeave: function onMouseLeave() {
return setHighlightedIndex(null);
}
}), weeksInMonth.map(function (week, i) {
return week.map(function (day, j, _ref) {
var length = _ref.length;
var isFromDate = isSelected(day.dateValue, fromDate);
var isToDate = isSelected(day.dateValue, toDate);
var index = i * length + j;
return React.createElement(SelectableCell, getItemProps({
key: day.label,
item: day.dateValue,
index: index,
isHighlighted: highlightedIndex === index,
isLessImportant: isInOtherMonth(day.dateValue),
isInRange: dateIsInRange(day.dateValue, fromDate, toDate),
isRangeStart: isFromDate && toDate,
isRangeEnd: isToDate && fromDate,
isSelected: isFromDate || isToDate,
isCurrent: isToday(day.dateValue)
}), React.createElement(Text, null, day.label));
});
})));
}
function _templateObject$1() {
var data = _taggedTemplateLiteralLoose(["\n && {\n margin-top: 8px;\n }\n"]);
_templateObject$1 = function _templateObject() {
return data;
};
return data;
}
var Divider$1 = styled(HeaderDivider)(_templateObject$1());
function getSurroundingYears(date, amount, dateFormat) {
if (amount === void 0) {
amount = 8;
}
if (dateFormat === void 0) {
dateFormat = 'YYYY';
}
var result = [];
var selectedYearIndex = getYear(date) % amount;
for (var year = 0; year < amount; year++) {
var dateValue = addYears(date, year - selectedYearIndex);
result.push({
dateValue: dateValue,
label: format(dateValue, dateFormat)
});
}
return result;
}
function YearSelect(props) {
var setDate = props.setDate,
date = props.date;
return React.createElement(Fragment, null, React.createElement(Divider$1, null), React.createElement(Row, null, getSurroundingYears(date).map(function (year) {
return React.createElement(SelectableCell, {
key: year.label,
widthPercentage: 1 / 4,
horizontalSpacing: true,
onClick: function onClick() {
return setDate(year.dateValue);
},
isSelected: isSameYear(year.dateValue, date),
isCurrent: isThisYear(year.dateValue)
}, React.createElement(Text, null, year.label));
})));
}
function getMonthsInYear(date, dateFormat) {
if (dateFormat === void 0) {
dateFormat = 'MMM';
}
var result = [];
var selectedMonth = getMonth(date);
for (var month = 0; month < 12; month++) {
var dateValue = addMonths(date, month - selectedMonth);
result.push({
dateValue: dateValue,
label: format(dateValue, dateFormat)
});
}
return result;
}
function MonthSelect(props) {
var setDate = props.setDate,
date = props.date;
return React.createElement(Fragment, null, React.createElement(Header, {
widthPercentage: 1
}, React.createElement(Text, null, "Month & Year")), React.createElement(HeaderDivider, null), React.createElement(Row, null, getMonthsInYear(date).map(function (month) {
return React.createElement(SelectableCell, {
key: month.label,
widthPercentage: 1 / 4,
horizontalSpacing: true,
onClick: function onClick() {
return setDate(month.dateValue);
},
isSelected: isSameMonth(month.dateValue, date),
isCurrent: isThisMonth(month.dateValue)
}, React.createElement(Text, null, month.label));
})), React.createElement(YearSelect, props));
}
function _templateObject4$1() {
var data = _taggedTemplateLiteralLoose(["\n && {\n font-weight: 600;\n font-size: 14px;\n }\n"]);
_templateObject4$1 = function _templateObject4() {
return data;
};
return data;
}
function _templateObject3$1() {
var data = _taggedTemplateLiteralLoose(["\n flex: 1;\n"]);
_templateObject3$1 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2$1() {
var data = _taggedTemplateLiteralLoose(["\n && {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n }\n"]);
_templateObject2$1 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject$2() {
var data = _taggedTemplateLiteralLoose(["\n && {\n margin-top: 10px;\n width: 100%;\n min-width: 212px;\n position: absolute;\n z-index: 1;\n flex-direction: row;\n padding: 8px;\n }\n"]);
_templateObject$2 = function _templateObject() {
return data;
};
return data;
}
var Wrapper = styled(Card)(_templateObject$2());
var MonthButton = styled(IconButton)(_templateObject2$1());
var Spacer = styled.div(_templateObject3$1());
var MothText = styled(Button)(_templateObject4$1());
var Calendar =
/*#__PURE__*/
function (_PureComponent) {
_inheritsLoose(Calendar, _PureComponent);
function Calendar() {
var _this;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _PureComponent.call.apply(_PureComponent, [this].concat(args)) || this;
_this.state = {
monthSelectOpen: false
};
_this.handleMonthTextClick = function () {
return _this.setState(function (_ref) {
var monthSelectOpen = _ref.monthSelectOpen;
return {
monthSelectOpen: !monthSelectOpen
};
});
};
_this.preventInputLosingFocus = function (e) {
return e.preventDefault();
};
return _this;
}
var _proto = Calendar.prototype;
_proto.render = function render() {
var _this$props = this.props,
getFormattedDate = _this$props.getFormattedDate,
setDateNextMonth = _this$props.setDateNextMonth,
setDatePrevMonth = _this$props.setDatePrevMonth,
clearDateRange = _this$props.clearDateRange;
var monthSelectOpen = this.state.monthSelectOpen;
return React.createElement(Wrapper, {
raised: true,
onMouseDown: this.preventInputLosingFocus
}, React.createElement(Row, null, React.createElement(MothText, {
size: "small",
onClick: this.handleMonthTextClick
}, getFormattedDate('MMM YYYY'), monthSelectOpen ? React.createElement(ArrowDropUp, null) : React.createElement(ArrowDropDown, null)), React.createElement(Spacer, null), React.createElement(Cell, null, React.createElement(MonthButton, {
onClick: clearDateRange,
"aria-label": "Clear selection"
}, React.createElement(ClearAll, null))), React.createElement(Cell, null, React.createElement(MonthButton, {
onClick: setDatePrevMonth,
"aria-label": "Previous month"
}, React.createElement(NavigateBefore, null))), React.createElement(Cell, null, React.createElement(MonthButton, {
onClick: setDateNextMonth,
"aria-label": "Next month"
}, React.createElement(NavigateNext, null)))), monthSelectOpen ? React.createElement(MonthSelect, this.props) : React.createElement(DaySelect, this.props));
};
return Calendar;
}(PureComponent);
function _templateObject$3() {
var data = _taggedTemplateLiteralLoose(["\n position: relative;\n * {\n box-sizing: border-box;\n }\n"]);
_templateObject$3 = function _templateObject() {
return data;
};
return data;
}
var Wrapper$1 = styled.div(_templateObject$3());
var itemToString = function itemToString(dateFormat) {
return function (_temp) {
var _ref = _temp === void 0 ? {} : _temp,
fromDate = _ref.fromDate,
toDate = _ref.toDate;
return "" + (fromDate ? "From: " + format(fromDate, dateFormat) + (toDate ? ' ' : '') : '') + (toDate ? "To: " + format(toDate, dateFormat) : '');
};
};
function stateReducer(state, changes) {
// this prevents the menu from being closed when the user
// selects an item with a keyboard or mouse
switch (changes.type) {
case Downshift.stateChangeTypes.keyDownEnter:
case Downshift.stateChangeTypes.clickItem:
return _extends({}, changes, {
isOpen: state.isOpen,
highlightedIndex: state.highlightedIndex
});
default:
return changes;
}
}
var renderCalendar = function renderCalendar(props) {
return React.createElement(Calendar, props);
};
var DateRangePicker =
/*#__PURE__*/
function (_PureComponent) {
_inheritsLoose(DateRangePicker, _PureComponent);
function DateRangePicker() {
var _this;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _PureComponent.call.apply(_PureComponent, [this].concat(args)) || this;
_this.setDateRange = function (selectedDate, stateAndHelpers) {
var _this$props = _this.props,
fromDate = _this$props.fromDate,
toDate = _this$props.toDate;
if (!fromDate && toDate && isAfter(selectedDate, toDate)) {
_this.props.onChange({
fromDate: toDate,
toDate: selectedDate
});
return;
} // Reset the state if the selected date is equal
if (toDate && isSameDay(selectedDate, toDate)) {
_this.props.onChange({
toDate: null
});
return;
}
if (fromDate && isSameDay(selectedDate, fromDate)) {
_this.props.onChange({
fromDate: null
});
return;
} // Set the starting date to the selected date
// if the starting date is empty
if (!fromDate) {
_this.props.onChange({
fromDate: selectedDate
});
return;
} // Set the ending date to the selected date if the start date
// is given and the selected date is after the start date
if (fromDate && isAfter(selectedDate, fromDate)) {
_this.props.onChange({
toDate: selectedDate
});
} // Set the starting date to the selected date if the
// starting date is given and the selected date is
// before the ending date
else if (toDate && fromDate && isBefore(selectedDate, fromDate)) {
_this.props.onChange({
fromDate: selectedDate
});
} // Set the starting date to the selected date
// and the ending date to the last starting date
// if the starting date is given and the selected date is before this starting date
else if (fromDate && isBefore(selectedDate, fromDate)) {
_this.props.onChange({
fromDate: selectedDate,
toDate: fromDate
});
} // Both dates are selected if we get here
if (_this.props.closeDialogOnSelection) {
stateAndHelpers.closeMenu();
}
};
_this.clearDateRange = function () {
return _this.props.onChange({
fromDate: null,
toDate: null
});
};
return _this;
}
var _proto = DateRangePicker.prototype;
_proto.render = function render() {
var _this2 = this;
var _this$props2 = this.props,
fromDate = _this$props2.fromDate,
toDate = _this$props2.toDate,
dateFormat = _this$props2.dateFormat;
return React.createElement(Downshift, _extends({
stateReducer: stateReducer,
selectedItem: {
fromDate: fromDate,
toDate: toDate
},
itemToString: itemToString(dateFormat),
onSelect: this.setDateRange
}, this.props), function (_ref2) {
var getInputProps = _ref2.getInputProps,
getLabelProps = _ref2.getLabelProps,
selectedItem = _ref2.selectedItem,
downshiftProps = _objectWithoutPropertiesLoose(_ref2, ["getInputProps", "getLabelProps", "selectedItem"]);
return React.createElement("div", {
className: _this2.props.className
}, React.createElement(TextField, {
id: "date-range",
label: "Date range",
InputLabelProps: getLabelProps({
shrink: downshiftProps.isOpen || !!fromDate || !!toDate
}),
placeholder: "From:",
fullWidth: true,
InputProps: getInputProps({
readOnly: true,
onClick: downshiftProps.openMenu,
onFocus: downshiftProps.openMenu
})
}), downshiftProps.isOpen ? React.createElement(Wrapper$1, null, React.createElement(Kalendaryo, _extends({}, downshiftProps, {
startCurrentDateAt: selectedItem.fromDate || selectedItem.toDate,
fromDate: selectedItem.fromDate,
toDate: selectedItem.toDate,
clearDateRange: _this2.clearDateRange,
startWeekAt: 1,
defaultFormat: dateFormat,
render: renderCalendar
}))) : null);
});
};
return DateRangePicker;
}(PureComponent);
process.env.NODE_ENV !== "production" ? DateRangePicker.propTypes = {
fromDate: PropTypes.instanceOf(Date),
toDate: PropTypes.instanceOf(Date),
onChange: PropTypes.func.isRequired,
className: PropTypes.string,
dateFormat: PropTypes.string,
closeDialogOnSelection: PropTypes.bool
} : void 0;
DateRangePicker.defaultProps = {
fromDate: null,
toDate: null,
className: '',
dateFormat: 'YYYY-MM-DD'
};
export { DateRangePicker, Calendar };
//# sourceMappingURL=material-ui-pickers.esm.js.map