@material-ui/pickers
Version:
React components, that implements material design pickers for material-ui v4
649 lines (582 loc) • 21.1 kB
JavaScript
import React__default, { useCallback, createElement, cloneElement, Fragment, Component, useEffect } from 'react';
import { node, bool, func } from 'prop-types';
import { u as useUtils } from './useUtils-cfb96ac9.js';
import clsx from 'clsx';
import _extends from '@babel/runtime/helpers/esm/extends';
import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
import Typography from '@material-ui/core/Typography';
import { makeStyles, useTheme, withStyles } from '@material-ui/core/styles';
import { a as arrayIncludes, r as runKeyHandler, V as VariantContext } from './Wrapper-241966d7.js';
import IconButton from '@material-ui/core/IconButton';
import SvgIcon from '@material-ui/core/SvgIcon';
import _classCallCheck from '@babel/runtime/helpers/esm/classCallCheck';
import _createClass from '@babel/runtime/helpers/esm/createClass';
import _possibleConstructorReturn from '@babel/runtime/helpers/esm/possibleConstructorReturn';
import _getPrototypeOf from '@babel/runtime/helpers/esm/getPrototypeOf';
import _inherits from '@babel/runtime/helpers/esm/inherits';
import Day from './Day.js';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import CircularProgress from '@material-ui/core/CircularProgress';
var findClosestEnabledDate = function findClosestEnabledDate(_ref) {
var date = _ref.date,
utils = _ref.utils,
minDate = _ref.minDate,
maxDate = _ref.maxDate,
disableFuture = _ref.disableFuture,
disablePast = _ref.disablePast,
shouldDisableDate = _ref.shouldDisableDate;
var today = utils.startOfDay(utils.date());
if (disablePast && utils.isBefore(minDate, today)) {
minDate = today;
}
if (disableFuture && utils.isAfter(maxDate, today)) {
maxDate = today;
}
var forward = date;
var backward = date;
if (utils.isBefore(date, minDate)) {
forward = utils.date(minDate);
backward = null;
}
if (utils.isAfter(date, maxDate)) {
if (backward) {
backward = utils.date(maxDate);
}
forward = null;
}
while (forward || backward) {
if (forward && utils.isAfter(forward, maxDate)) {
forward = null;
}
if (backward && utils.isBefore(backward, minDate)) {
backward = null;
}
if (forward) {
if (!shouldDisableDate(forward)) {
return forward;
}
forward = utils.addDays(forward, 1);
}
if (backward) {
if (!shouldDisableDate(backward)) {
return backward;
}
backward = utils.addDays(backward, -1);
}
} // fallback to today if no enabled days
return utils.date();
};
var isYearOnlyView = function isYearOnlyView(views) {
return views.length === 1 && views[0] === 'year';
};
var isYearAndMonthViews = function isYearAndMonthViews(views) {
return views.length === 2 && arrayIncludes(views, 'month') && arrayIncludes(views, 'year');
};
var getFormatByViews = function getFormatByViews(views, utils) {
if (isYearOnlyView(views)) {
return utils.yearFormat;
}
if (isYearAndMonthViews(views)) {
return utils.yearMonthFormat;
}
return utils.dateFormat;
};
var DayWrapper = function DayWrapper(_ref) {
var children = _ref.children,
value = _ref.value,
disabled = _ref.disabled,
onSelect = _ref.onSelect,
dayInCurrentMonth = _ref.dayInCurrentMonth,
other = _objectWithoutProperties(_ref, ["children", "value", "disabled", "onSelect", "dayInCurrentMonth"]);
var handleClick = useCallback(function () {
return onSelect(value);
}, [onSelect, value]);
return createElement("div", _extends({
role: "presentation",
onClick: dayInCurrentMonth && !disabled ? handleClick : undefined,
onKeyPress: dayInCurrentMonth && !disabled ? handleClick : undefined
}, other), children);
};
var animationDuration = 350;
var useStyles = makeStyles(function (theme) {
var slideTransition = theme.transitions.create('transform', {
duration: animationDuration,
easing: 'cubic-bezier(0.35, 0.8, 0.4, 1)'
});
return {
transitionContainer: {
display: 'block',
position: 'relative',
'& > *': {
position: 'absolute',
top: 0,
right: 0,
left: 0
}
},
'slideEnter-left': {
willChange: 'transform',
transform: 'translate(100%)'
},
'slideEnter-right': {
willChange: 'transform',
transform: 'translate(-100%)'
},
slideEnterActive: {
transform: 'translate(0%)',
transition: slideTransition
},
slideExit: {
transform: 'translate(0%)'
},
'slideExitActiveLeft-left': {
willChange: 'transform',
transform: 'translate(-200%)',
transition: slideTransition
},
'slideExitActiveLeft-right': {
willChange: 'transform',
transform: 'translate(200%)',
transition: slideTransition
}
};
}, {
name: 'MuiPickersSlideTransition'
});
var SlideTransition = function SlideTransition(_ref) {
var children = _ref.children,
transKey = _ref.transKey,
slideDirection = _ref.slideDirection,
_ref$className = _ref.className,
className = _ref$className === void 0 ? null : _ref$className;
var classes = useStyles();
var transitionClasses = {
exit: classes.slideExit,
enterActive: classes.slideEnterActive,
// @ts-ignore
enter: classes['slideEnter-' + slideDirection],
// @ts-ignore
exitActive: classes['slideExitActiveLeft-' + slideDirection]
};
return createElement(TransitionGroup, {
className: clsx(classes.transitionContainer, className),
childFactory: function childFactory(element) {
return cloneElement(element, {
classNames: transitionClasses
});
}
}, createElement(CSSTransition, {
mountOnEnter: true,
unmountOnExit: true,
key: transKey + slideDirection,
timeout: animationDuration,
classNames: transitionClasses,
children: children
}));
};
var ArrowLeftIcon = function ArrowLeftIcon(props) {
return React__default.createElement(SvgIcon, props, React__default.createElement("path", {
d: "M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z"
}), React__default.createElement("path", {
fill: "none",
d: "M0 0h24v24H0V0z"
}));
};
var ArrowRightIcon = function ArrowRightIcon(props) {
return React__default.createElement(SvgIcon, props, React__default.createElement("path", {
d: "M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"
}), React__default.createElement("path", {
fill: "none",
d: "M0 0h24v24H0V0z"
}));
};
var useStyles$1 = makeStyles(function (theme) {
return {
switchHeader: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginTop: theme.spacing(0.5),
marginBottom: theme.spacing(1)
},
transitionContainer: {
width: '100%',
overflow: 'hidden',
height: 23
},
iconButton: {
zIndex: 1,
backgroundColor: theme.palette.background.paper
},
daysHeader: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
maxHeight: 16
},
dayLabel: {
width: 36,
margin: '0 2px',
textAlign: 'center',
color: theme.palette.text.hint
}
};
}, {
name: 'MuiPickersCalendarHeader'
});
var CalendarHeader = function CalendarHeader(_ref) {
var currentMonth = _ref.currentMonth,
onMonthChange = _ref.onMonthChange,
leftArrowIcon = _ref.leftArrowIcon,
rightArrowIcon = _ref.rightArrowIcon,
leftArrowButtonProps = _ref.leftArrowButtonProps,
rightArrowButtonProps = _ref.rightArrowButtonProps,
disablePrevMonth = _ref.disablePrevMonth,
disableNextMonth = _ref.disableNextMonth,
slideDirection = _ref.slideDirection;
var utils = useUtils();
var classes = useStyles$1();
var theme = useTheme();
var rtl = theme.direction === 'rtl';
var selectNextMonth = function selectNextMonth() {
return onMonthChange(utils.getNextMonth(currentMonth), 'left');
};
var selectPreviousMonth = function selectPreviousMonth() {
return onMonthChange(utils.getPreviousMonth(currentMonth), 'right');
};
return createElement("div", null, createElement("div", {
className: classes.switchHeader
}, createElement(IconButton, _extends({}, leftArrowButtonProps, {
disabled: disablePrevMonth,
onClick: selectPreviousMonth,
className: classes.iconButton
}), rtl ? rightArrowIcon : leftArrowIcon), createElement(SlideTransition, {
slideDirection: slideDirection,
transKey: currentMonth.toString(),
className: classes.transitionContainer
}, createElement(Typography, {
align: "center",
variant: "body1"
}, utils.getCalendarHeaderText(currentMonth))), createElement(IconButton, _extends({}, rightArrowButtonProps, {
disabled: disableNextMonth,
onClick: selectNextMonth,
className: classes.iconButton
}), rtl ? leftArrowIcon : rightArrowIcon)), createElement("div", {
className: classes.daysHeader
}, utils.getWeekdays().map(function (day, index) {
return createElement(Typography, {
key: index // eslint-disable-line react/no-array-index-key
,
variant: "caption",
className: classes.dayLabel
}, day);
})));
};
CalendarHeader.displayName = 'CalendarHeader';
process.env.NODE_ENV !== "production" ? CalendarHeader.propTypes = {
leftArrowIcon: node,
rightArrowIcon: node,
disablePrevMonth: bool,
disableNextMonth: bool
} : void 0;
CalendarHeader.defaultProps = {
leftArrowIcon: createElement(ArrowLeftIcon, null),
rightArrowIcon: createElement(ArrowRightIcon, null),
disablePrevMonth: false,
disableNextMonth: false
};
var withUtils = function withUtils() {
return function (Component) {
var WithUtils = function WithUtils(props) {
var utils = useUtils();
return createElement(Component, _extends({
utils: utils
}, props));
};
WithUtils.displayName = "WithUtils(".concat(Component.displayName || Component.name, ")");
return WithUtils;
};
};
var KeyDownListener = function KeyDownListener(_ref) {
var onKeyDown = _ref.onKeyDown;
useEffect(function () {
window.addEventListener('keydown', onKeyDown);
return function () {
window.removeEventListener('keydown', onKeyDown);
};
}, [onKeyDown]);
return null;
};
var Calendar =
/*#__PURE__*/
function (_React$Component) {
_inherits(Calendar, _React$Component);
function Calendar() {
var _getPrototypeOf2;
var _this;
_classCallCheck(this, Calendar);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Calendar)).call.apply(_getPrototypeOf2, [this].concat(args)));
_this.state = {
slideDirection: 'left',
currentMonth: _this.props.utils.startOfMonth(_this.props.date),
loadingQueue: 0
};
_this.pushToLoadingQueue = function () {
var loadingQueue = _this.state.loadingQueue + 1;
_this.setState({
loadingQueue: loadingQueue
});
};
_this.popFromLoadingQueue = function () {
var loadingQueue = _this.state.loadingQueue;
loadingQueue = loadingQueue <= 0 ? 0 : loadingQueue - 1;
_this.setState({
loadingQueue: loadingQueue
});
};
_this.handleChangeMonth = function (newMonth, slideDirection) {
_this.setState({
currentMonth: newMonth,
slideDirection: slideDirection
});
if (_this.props.onMonthChange) {
var returnVal = _this.props.onMonthChange(newMonth);
if (returnVal) {
_this.pushToLoadingQueue();
returnVal.then(function () {
_this.popFromLoadingQueue();
});
}
}
};
_this.validateMinMaxDate = function (day) {
var _this$props = _this.props,
minDate = _this$props.minDate,
maxDate = _this$props.maxDate,
utils = _this$props.utils,
disableFuture = _this$props.disableFuture,
disablePast = _this$props.disablePast;
var now = utils.date();
return Boolean(disableFuture && utils.isAfterDay(day, now) || disablePast && utils.isBeforeDay(day, now) || minDate && utils.isBeforeDay(day, utils.date(minDate)) || maxDate && utils.isAfterDay(day, utils.date(maxDate)));
};
_this.shouldDisablePrevMonth = function () {
var _this$props2 = _this.props,
utils = _this$props2.utils,
disablePast = _this$props2.disablePast,
minDate = _this$props2.minDate;
var now = utils.date();
var firstEnabledMonth = utils.startOfMonth(disablePast && utils.isAfter(now, utils.date(minDate)) ? now : utils.date(minDate));
return !utils.isBefore(firstEnabledMonth, _this.state.currentMonth);
};
_this.shouldDisableNextMonth = function () {
var _this$props3 = _this.props,
utils = _this$props3.utils,
disableFuture = _this$props3.disableFuture,
maxDate = _this$props3.maxDate;
var now = utils.date();
var lastEnabledMonth = utils.startOfMonth(disableFuture && utils.isBefore(now, utils.date(maxDate)) ? now : utils.date(maxDate));
return !utils.isAfter(lastEnabledMonth, _this.state.currentMonth);
};
_this.shouldDisableDate = function (day) {
var shouldDisableDate = _this.props.shouldDisableDate;
return _this.validateMinMaxDate(day) || Boolean(shouldDisableDate && shouldDisableDate(day));
};
_this.handleDaySelect = function (day) {
var isFinish = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var _this$props4 = _this.props,
date = _this$props4.date,
utils = _this$props4.utils;
_this.props.onChange(utils.mergeDateAndTime(day, date), isFinish);
};
_this.moveToDay = function (day) {
var utils = _this.props.utils;
if (day && !_this.shouldDisableDate(day)) {
if (utils.getMonth(day) !== utils.getMonth(_this.state.currentMonth)) {
_this.handleChangeMonth(utils.startOfMonth(day), 'left');
}
_this.handleDaySelect(day, false);
}
};
_this.handleKeyDown = function (event) {
var _this$props5 = _this.props,
theme = _this$props5.theme,
date = _this$props5.date,
utils = _this$props5.utils;
runKeyHandler(event, {
ArrowUp: function ArrowUp() {
return _this.moveToDay(utils.addDays(date, -7));
},
ArrowDown: function ArrowDown() {
return _this.moveToDay(utils.addDays(date, 7));
},
ArrowLeft: function ArrowLeft() {
return _this.moveToDay(utils.addDays(date, theme.direction === 'ltr' ? -1 : 1));
},
ArrowRight: function ArrowRight() {
return _this.moveToDay(utils.addDays(date, theme.direction === 'ltr' ? 1 : -1));
}
});
};
_this.renderWeeks = function () {
var _this$props6 = _this.props,
utils = _this$props6.utils,
classes = _this$props6.classes;
var weeks = utils.getWeekArray(_this.state.currentMonth);
return weeks.map(function (week) {
return createElement("div", {
key: "week-".concat(week[0].toString()),
className: classes.week
}, _this.renderDays(week));
});
};
_this.renderDays = function (week) {
var _this$props7 = _this.props,
date = _this$props7.date,
renderDay = _this$props7.renderDay,
utils = _this$props7.utils;
var now = utils.date();
var selectedDate = utils.startOfDay(date);
var currentMonthNumber = utils.getMonth(_this.state.currentMonth);
return week.map(function (day) {
var disabled = _this.shouldDisableDate(day);
var isDayInCurrentMonth = utils.getMonth(day) === currentMonthNumber;
var dayComponent = createElement(Day, {
disabled: disabled,
current: utils.isSameDay(day, now),
hidden: !isDayInCurrentMonth,
selected: utils.isSameDay(selectedDate, day)
}, utils.getDayText(day));
if (renderDay) {
dayComponent = renderDay(day, selectedDate, isDayInCurrentMonth, dayComponent);
}
return createElement(DayWrapper, {
value: day,
key: day.toString(),
disabled: disabled,
dayInCurrentMonth: isDayInCurrentMonth,
onSelect: _this.handleDaySelect
}, dayComponent);
});
};
return _this;
}
_createClass(Calendar, [{
key: "componentDidMount",
value: function componentDidMount() {
var _this$props8 = this.props,
date = _this$props8.date,
minDate = _this$props8.minDate,
maxDate = _this$props8.maxDate,
utils = _this$props8.utils,
disablePast = _this$props8.disablePast,
disableFuture = _this$props8.disableFuture;
if (this.shouldDisableDate(date)) {
var closestEnabledDate = findClosestEnabledDate({
date: date,
utils: utils,
minDate: utils.date(minDate),
maxDate: utils.date(maxDate),
disablePast: Boolean(disablePast),
disableFuture: Boolean(disableFuture),
shouldDisableDate: this.shouldDisableDate
});
this.handleDaySelect(closestEnabledDate, false);
}
}
}, {
key: "render",
value: function render() {
var _this$state = this.state,
currentMonth = _this$state.currentMonth,
slideDirection = _this$state.slideDirection;
var _this$props9 = this.props,
classes = _this$props9.classes,
allowKeyboardControl = _this$props9.allowKeyboardControl,
leftArrowButtonProps = _this$props9.leftArrowButtonProps,
leftArrowIcon = _this$props9.leftArrowIcon,
rightArrowButtonProps = _this$props9.rightArrowButtonProps,
rightArrowIcon = _this$props9.rightArrowIcon,
loadingIndicator = _this$props9.loadingIndicator;
var loadingElement = loadingIndicator ? loadingIndicator : createElement(CircularProgress, null);
return createElement(Fragment, null, allowKeyboardControl && this.context !== 'static' && createElement(KeyDownListener, {
onKeyDown: this.handleKeyDown
}), createElement(CalendarHeader, {
currentMonth: currentMonth,
slideDirection: slideDirection,
onMonthChange: this.handleChangeMonth,
leftArrowIcon: leftArrowIcon,
leftArrowButtonProps: leftArrowButtonProps,
rightArrowIcon: rightArrowIcon,
rightArrowButtonProps: rightArrowButtonProps,
disablePrevMonth: this.shouldDisablePrevMonth(),
disableNextMonth: this.shouldDisableNextMonth()
}), createElement(SlideTransition, {
slideDirection: slideDirection,
transKey: currentMonth.toString(),
className: classes.transitionContainer
}, createElement(Fragment, null, this.state.loadingQueue > 0 && createElement("div", {
className: classes.progressContainer
}, loadingElement) || createElement("div", null, this.renderWeeks()))));
}
}], [{
key: "getDerivedStateFromProps",
value: function getDerivedStateFromProps(nextProps, state) {
var utils = nextProps.utils,
nextDate = nextProps.date;
if (!utils.isEqual(nextDate, state.lastDate)) {
var nextMonth = utils.getMonth(nextDate);
var lastDate = state.lastDate || nextDate;
var lastMonth = utils.getMonth(lastDate);
return {
lastDate: nextDate,
currentMonth: nextProps.utils.startOfMonth(nextDate),
// prettier-ignore
slideDirection: nextMonth === lastMonth ? state.slideDirection : utils.isAfterDay(nextDate, lastDate) ? 'left' : 'right'
};
}
return null;
}
}]);
return Calendar;
}(Component);
Calendar.contextType = VariantContext;
process.env.NODE_ENV !== "production" ? Calendar.propTypes = {
renderDay: func,
shouldDisableDate: func,
allowKeyboardControl: bool
} : void 0;
Calendar.defaultProps = {
minDate: new Date('1900-01-01'),
maxDate: new Date('2100-01-01'),
disablePast: false,
disableFuture: false,
allowKeyboardControl: true
};
var styles = function styles(theme) {
return {
transitionContainer: {
minHeight: 36 * 6,
marginTop: theme.spacing(1.5)
},
progressContainer: {
width: '100%',
height: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
},
week: {
display: 'flex',
justifyContent: 'center'
}
};
};
var Calendar$1 = withStyles(styles, {
name: 'MuiPickersCalendar',
withTheme: true
})(withUtils()(Calendar));
export { Calendar as C, Calendar$1 as a, isYearAndMonthViews as b, getFormatByViews as g, isYearOnlyView as i, styles as s };
//# sourceMappingURL=Calendar-11ae61f6.js.map