Skip to content

Instantly share code, notes, and snippets.

@Skitionek
Forked from RedHatter/DateMultiPicker.jsx
Last active January 30, 2020 04:01
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Skitionek/006f1f16aa26cf7cc576c901cffd1600 to your computer and use it in GitHub Desktop.
Save Skitionek/006f1f16aa26cf7cc576c901cffd1600 to your computer and use it in GitHub Desktop.
Range select for @mui-org/material-ui-pickers
import React, { useContext, useRef, useState } from 'react'
import { DatePicker, MuiPickersContext } from '@material-ui/pickers'
import withStyles from '@material-ui/core/styles/withStyles'
import clsx from "clsx";
import { useStyles as dayStyles } from '@material-ui/pickers/views/Calendar/Day';
function DateRangePicker({
classes,
value,
onChange,
labelFunc,
format,
emptyLabel,
autoOk,
onClose,
...props
}) {
const [begin, setBegin] = useState(value[0])
const [end, setEnd] = useState(value[1])
const [hover, setHover] = useState(undefined)
const picker = useRef()
const utils = useContext(MuiPickersContext)
const min = Math.min(begin || hover, end || hover)
const max = Math.max(begin || hover, end || hover)
const baseClasses = dayStyles();
function renderDay(day, selectedDate, dayInCurrentMonth, dayComponent) {
return React.cloneElement(dayComponent, {
onClick: e => {
e.stopPropagation()
if (!begin) setBegin(day)
else if (!end) {
setEnd(day)
if (autoOk) {
onChange([begin, day].sort())
picker.current.close()
}
} else {
setBegin(day)
setEnd(undefined)
}
},
onMouseEnter: e => setHover(day),
selected: day >= min && day <= max,
className: clsx(classes.day, [
dayComponent.props.hidden && [baseClasses.hidden, classes.hidden],
dayComponent.props.current && [baseClasses.current, classes.current],
dayComponent.props.disabled && [baseClasses.dayDisabled, classes.dayDisabled],
day >= min && day <= max && [baseClasses.daySelected, classes.daySelected],
utils.isSameDay(day, min) && [baseClasses.beginCap, classes.beginCap],
utils.isSameDay(day, max) && [baseClasses.endCap, classes.endCap]
])
}
)
}
const formatDate = date => utils.format(date, format || utils.dateFormat)
return (
<DatePicker
{...props}
value={begin}
renderDay={renderDay}
onClose={() => {
onChange([begin, end].sort())
if (onClose) onClose()
}}
onChange={() => {
}}
onClear={() => {
setBegin(undefined)
setEnd(undefined)
setHover(undefined)
onChange([])
}}
ref={picker}
labelFunc={(date, invalid) =>
labelFunc
? labelFunc([begin, end].sort(), invalid)
: date && begin && end
? `${formatDate(begin)} - ${formatDate(end)}`
: emptyLabel || ''
}
/>
)
}
export const styles = theme => {
return {
day: {
margin: 0,
width: '40px',
borderRadius: '0',
transition: 'none'
},
beginCap: {
borderTopLeftRadius: '50%',
borderBottomLeftRadius: '50%'
},
endCap: {
borderTopRightRadius: '50%',
borderBottomRightRadius: '50%'
}
}
};
export default withStyles(styles, { name: 'DateRangePicker' })(DateRangePicker)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment