UNPKG

@6thquake/react-material

Version:

React components that implement Google's Material Design.

190 lines (172 loc) 4.76 kB
import _extends from "@babel/runtime/helpers/extends"; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose"; /** * @ignore - do not document. */ import React, { useState, useContext } from 'react'; import compose from 'recompose/compose'; import classNames from 'classnames'; import PropTypes from 'prop-types'; import moment from 'moment'; import { Calendar, MuiPickersContext } from '@material-ui/pickers'; import withStyles from '../styles/withStyles'; import { withLocale } from '../LocaleProvider'; const sort = ([a, b]) => { if (!(a && b)) { return [a, b]; } if (b.isBefore(a)) { return [b, a]; } return [a, b]; }; const isWithinRange = (day, [min, max]) => { max = max || min; const isAfterMin = day.diff(min) >= 0; const isBeforeMax = day.diff(max) <= 0; return isAfterMin && isBeforeMax; }; const CalendarPicker = React.forwardRef(function CalendarPicker(props, ref) { const { className: classNamePro, classes, value, onChange } = props, other = _objectWithoutPropertiesLoose(props, ["className", "classes", "value", "onChange"]); const className = classNames(classNamePro); const classesPro = _extends({}, classes); const { start: startDate, end: endDate } = value || {}; const [preBegin, setPreBegin] = useState(null); const [preEnd, setPreEnd] = useState(null); const [begin, setBegin] = useState(moment(startDate)); const [end, setEnd] = useState(moment(endDate)); const utils = useContext(MuiPickersContext); if (preBegin !== startDate) { setPreBegin(startDate); setBegin(moment(startDate)); } if (preEnd !== endDate) { setPreEnd(endDate); setEnd(moment(endDate)); } const [min, max] = sort([begin, end]); function renderDay(day, selectedDate, dayInCurrentMonth, dayComponent) { return React.cloneElement(dayComponent, { onClick: e => { e.stopPropagation(); if (!begin) { setBegin(day); } else if (!end) { setEnd(day); const days = sort([begin, day]).map(item => item.format('YYYY-MM-DD')); const [start, end] = days; onChange({ start, end }); } else { setBegin(day); setEnd(undefined); } }, // onMouseEnter: e => setHover(day), className: classNames(classes.day, { [classes.hidden]: dayComponent.props.hidden, [classes.current]: dayComponent.props.current, [classes.dayDisabled]: dayComponent.props.disabled, [classes.daySelected]: isWithinRange(day, [min, max]), [classes.beginCap]: utils.isSameDay(day, min), [classes.endCap]: utils.isSameDay(day, max) }) }); } return React.createElement(Calendar, _extends({ date: begin, renderDay: renderDay, classes: classesPro, className: className, ref: ref }, other)); }); export const styles = theme => { const base = { day: { width: 36, height: 36, fontSize: theme.typography.caption.fontSize, margin: '0 2px', color: theme.palette.text.primary, fontWeight: theme.typography.fontWeightMedium, padding: 0 }, hidden: { opacity: 0, pointerEvents: 'none' }, current: { color: theme.palette.primary.main, fontWeight: 600 }, daySelected: { color: theme.palette.primary.contrastText, backgroundColor: theme.palette.primary.main, fontWeight: theme.typography.fontWeightMedium, '&:hover': { backgroundColor: theme.palette.primary.main } }, dayDisabled: { pointerEvents: 'none', color: theme.palette.text.hint } }; return _extends({}, base, { day: _extends({}, base.day, { margin: 0, width: 40, borderRadius: '0' }), beginCap: { borderTopLeftRadius: '50%', borderBottomLeftRadius: '50%' }, endCap: { borderTopRightRadius: '50%', borderBottomRightRadius: '50%' } }); }; process.env.NODE_ENV !== "production" ? CalendarPicker.propTypes = { /** * Override or extend the styles applied to the component. * See [CSS API](#css-api) below for more details. */ classes: PropTypes.object, /** * @ignore */ className: PropTypes.string, /** * Calendar onChange */ onChange: PropTypes.func, /** * the start date and end date of calendar */ value: PropTypes.shape({ end: PropTypes.string, start: PropTypes.string }) } : void 0; CalendarPicker.defaultProps = { onChange: () => {} }; export default compose(withLocale({ name: 'CalendarPicker' }), withStyles(styles, { name: 'CalendarPicker' }))(CalendarPicker);