UNPKG

@material-ui/pickers

Version:

React components, that implements material design pickers for material-ui v4

649 lines (582 loc) 21.1 kB
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