UNPKG

@appearhere/bloom

Version:

Appear Here's pattern library and styleguide

138 lines (116 loc) 3.65 kB
import PropTypes from 'prop-types'; import React, { Component } from 'react'; import keyMirror from 'key-mirror'; import momentPropTypes from 'react-moment-proptypes'; import noop from '../../../utils/noop'; import DayPicker from '../DayPicker/DayPicker'; import { defaultDayState } from '../DayPicker/DayPickerItem'; export const SELECT_DATE = keyMirror({ START: null, END: null, }); export const dayInRange = (day, startDate, endDate) => { if (!day) return false; const isEqualToStart = day.isSame(startDate, 'day'); const isEqualToEnd = day.isSame(endDate, 'day'); const isAfterStart = day.isAfter(startDate, 'day'); const isBeforeEnd = day.isBefore(endDate, 'day'); const isEqualToOrAfterStart = isEqualToStart || isAfterStart; const isEqualToOrBeforeEnd = isEqualToEnd || isBeforeEnd; if (!startDate && isEqualToEnd) return true; if (!endDate && isEqualToStart) return true; return isEqualToOrAfterStart && isEqualToOrBeforeEnd; }; const defaultIsDisabledDay = () => false; export default class DayRangePicker extends Component { static propTypes = { startDate: momentPropTypes.momentObj, endDate: momentPropTypes.momentObj, selectDate: PropTypes.oneOf([SELECT_DATE.START, SELECT_DATE.END]), onInteraction: PropTypes.func, onMonthChange: PropTypes.func, isDisabled: PropTypes.func, }; static defaultProps = { startDate: null, endDate: null, selectDate: SELECT_DATE.START, onInteraction: noop, onMonthChange: noop, isDisabled: defaultIsDisabledDay, }; state = { endHighlight: null, }; getDayState = (day) => { const { startDate, endDate, isDisabled } = this.props; const { endHighlight } = this.state; if (!day) return defaultDayState; return { isDisabled: isDisabled(day), isSelected: dayInRange(day, startDate, endDate), isFirstSelected: day.isSame(startDate, 'day') || (startDate && !endDate) || (!startDate && endDate), isLastSelected: day.isSame(endDate, 'day') || (startDate && !endDate) || (!startDate && endDate), isHighlighted: dayInRange(day, startDate, endHighlight), isFirstHighlighted: day.isSame(startDate, 'day'), isLastHighlighted: day.isSame(endHighlight, 'day'), }; }; handleInteraction = (e, date) => { const { startDate, endDate, selectDate, onInteraction } = this.props; if (selectDate === SELECT_DATE.START) { if (date.isAfter(endDate, 'day')) { onInteraction(e, date, null); } else { onInteraction(e, date, endDate); } } else if (selectDate === SELECT_DATE.END) { if ( (startDate && endDate && date.isSame(endDate, 'day')) || (startDate && date.isBefore(startDate, 'day')) ) { onInteraction(e, date, null); } else { onInteraction(e, startDate, date); } } }; handleHighlight = (e, date) => { this.setState((currentState, props) => { if (props.startDate && props.endDate) { return { endHighlight: null, }; } if (props.startDate && !props.endDate) { return { endHighlight: date, }; } return null; }); }; render() { const { startDate: _startDate, endDate: _endDate, onMonthChange, ...rest } = this.props; return ( <DayPicker {...rest} dayProps={{ getDayState: this.getDayState, onHighlight: this.handleHighlight, }} onInteraction={this.handleInteraction} onMonthChange={onMonthChange} /> ); } }