Skip to content
Snippets Groups Projects
Commit 1286c4b7 authored by Maja Wichrowska's avatar Maja Wichrowska
Browse files

Adds DateRangePickerInputController component

parent 231342a6
No related branches found
No related tags found
No related merge requests found
var DateRangePicker = require('./lib/components/DateRangePicker').default;
var DateRangePickerInput = require('./lib/components/DateRangePickerInput').default;
var DateRangePickerInputController = require('./lib/components/DateRangePickerInputController').default;
var SingleDatePicker = require('./lib/components/SingleDatePicker').default;
var SingleDatePickerInput = require('./lib/components/SingleDatePickerInput').default;
var DayPicker = require('./lib/components/DayPicker').default;
......@@ -24,6 +25,7 @@ module.exports = {
DateRangePicker: DateRangePicker,
SingleDatePicker: SingleDatePicker,
DateRangePickerInputController: DateRangePickerInputController,
DateRangePickerInput: DateRangePickerInput,
SingleDatePickerInput: SingleDatePickerInput,
DayPicker: DayPicker,
......
......@@ -7,15 +7,12 @@ import includes from 'array-includes';
import isTouchDevice from '../utils/isTouchDevice';
import getResponsiveContainerStyles from '../utils/getResponsiveContainerStyles';
import toMomentObject from '../utils/toMomentObject';
import toLocalizedDateString from '../utils/toLocalizedDateString';
import isInclusivelyAfterDay from '../utils/isInclusivelyAfterDay';
import isInclusivelyBeforeDay from '../utils/isInclusivelyBeforeDay';
import isNextDay from '../utils/isNextDay';
import isSameDay from '../utils/isSameDay';
import DateRangePickerInput from './DateRangePickerInput';
import DateRangePickerInputController from './DateRangePickerInputController';
import DayPicker from './DayPicker';
import CloseButton from '../svg/close.svg';
......@@ -87,13 +84,6 @@ export default class DateRangePicker extends React.Component {
this.onDayMouseLeave = this.onDayMouseLeave.bind(this);
this.onDayClick = this.onDayClick.bind(this);
this.onClearFocus = this.onClearFocus.bind(this);
this.onStartDateChange = this.onStartDateChange.bind(this);
this.onStartDateFocus = this.onStartDateFocus.bind(this);
this.onEndDateChange = this.onEndDateChange.bind(this);
this.onEndDateFocus = this.onEndDateFocus.bind(this);
this.clearDates = this.clearDates.bind(this);
this.responsivizePickerPosition = this.responsivizePickerPosition.bind(this);
}
......@@ -106,10 +96,6 @@ export default class DateRangePicker extends React.Component {
window.removeEventListener('resize', this.responsivizePickerPosition);
}
onClearFocus() {
this.props.onFocusChange(null);
}
onDayClick(day, modifiers, e) {
const { keepOpenOnDateSelect, minimumNights } = this.props;
if (e) e.preventDefault();
......@@ -160,43 +146,6 @@ export default class DateRangePicker extends React.Component {
});
}
onEndDateChange(endDateString) {
const {
startDate,
isOutsideRange,
keepOpenOnDateSelect,
onDatesChange,
onFocusChange,
} = this.props;
const endDate = toMomentObject(endDateString, this.getDisplayFormat());
const isEndDateValid = endDate && !isOutsideRange(endDate) &&
!isInclusivelyBeforeDay(endDate, startDate);
if (isEndDateValid) {
onDatesChange({ startDate, endDate });
if (!keepOpenOnDateSelect) onFocusChange(null);
} else {
onDatesChange({
startDate,
endDate: null,
});
}
}
onEndDateFocus() {
const { startDate, onFocusChange, withFullScreenPortal, disabled } = this.props;
if (!startDate && withFullScreenPortal && !disabled) {
// When the datepicker is full screen, we never want to focus the end date first
// because there's no indication that that is the case once the datepicker is open and it
// might confuse the user
onFocusChange(START_DATE);
} else if (!disabled) {
onFocusChange(END_DATE);
}
}
onOutsideClick() {
const { focusedInput, onFocusChange } = this.props;
if (!focusedInput) return;
......@@ -204,41 +153,6 @@ export default class DateRangePicker extends React.Component {
onFocusChange(null);
}
onStartDateChange(startDateString) {
const startDate = toMomentObject(startDateString, this.getDisplayFormat());
let { endDate } = this.props;
const { isOutsideRange, onDatesChange, onFocusChange } = this.props;
const isStartDateValid = startDate && !isOutsideRange(startDate);
if (isStartDateValid) {
if (isInclusivelyBeforeDay(endDate, startDate)) {
endDate = null;
}
onDatesChange({ startDate, endDate });
onFocusChange(END_DATE);
} else {
onDatesChange({
startDate: null,
endDate,
});
}
}
onStartDateFocus() {
if (!this.props.disabled) {
this.props.onFocusChange(START_DATE);
}
}
getDateString(date) {
const displayFormat = this.getDisplayFormat();
if (date && displayFormat) {
return date && date.format(displayFormat);
}
return toLocalizedDateString(date);
}
getDayPickerContainerClasses() {
const {
focusedInput,
......@@ -269,19 +183,6 @@ export default class DateRangePicker extends React.Component {
return ReactDOM.findDOMNode(this.dayPicker);
}
getDisplayFormat() {
const { displayFormat } = this.props;
return typeof displayFormat === 'string' ? displayFormat : displayFormat();
}
clearDates() {
const { onDatesChange, reopenPickerOnClearDates, onFocusChange } = this.props;
onDatesChange({ startDate: null, endDate: null });
if (reopenPickerOnClearDates) {
onFocusChange(START_DATE);
}
}
responsivizePickerPosition() {
const { anchorDirection, horizontalMargin } = this.props;
const { dayPickerContainerStyles } = this.state;
......@@ -461,44 +362,48 @@ export default class DateRangePicker extends React.Component {
render() {
const {
startDate,
startDateId,
startDatePlaceholderText,
endDate,
endDateId,
endDatePlaceholderText,
focusedInput,
showClearDates,
disabled,
required,
startDateId,
endDateId,
phrases,
isOutsideRange,
withPortal,
withFullScreenPortal,
displayFormat,
reopenPickerOnClearDates,
keepOpenOnDateSelect,
onDatesChange,
onFocusChange,
} = this.props;
const startDateString = this.getDateString(startDate);
const endDateString = this.getDateString(endDate);
return (
<div className="DateRangePicker">
<DateRangePickerInput
ref={(ref) => { this.input = ref; }}
<DateRangePickerInputController
startDate={startDate}
startDateId={startDateId}
startDatePlaceholderText={this.props.startDatePlaceholderText}
startDatePlaceholderText={startDatePlaceholderText}
isStartDateFocused={focusedInput === START_DATE}
endDate={endDate}
endDateId={endDateId}
endDatePlaceholderText={this.props.endDatePlaceholderText}
endDatePlaceholderText={endDatePlaceholderText}
isEndDateFocused={focusedInput === END_DATE}
onStartDateChange={this.onStartDateChange}
onStartDateFocus={this.onStartDateFocus}
onStartDateShiftTab={this.onClearFocus}
onEndDateChange={this.onEndDateChange}
onEndDateFocus={this.onEndDateFocus}
onEndDateTab={this.onClearFocus}
startDate={startDateString}
endDate={endDateString}
displayFormat={displayFormat}
showClearDates={showClearDates}
onClearDates={this.clearDates}
showCaret={!withPortal && !withFullScreenPortal}
disabled={disabled}
required={required}
showCaret={!withPortal && !withFullScreenPortal}
reopenPickerOnClearDates={reopenPickerOnClearDates}
keepOpenOnDateSelect={keepOpenOnDateSelect}
isOutsideRange={isOutsideRange}
withFullScreenPortal={withFullScreenPortal}
onDatesChange={onDatesChange}
onFocusChange={onFocusChange}
phrases={phrases}
/>
......
import React, { PropTypes } from 'react';
import moment from 'moment';
import momentPropTypes from 'react-moment-proptypes';
import DateRangePickerInput from './DateRangePickerInput';
import toMomentObject from '../utils/toMomentObject';
import toLocalizedDateString from '../utils/toLocalizedDateString';
import isInclusivelyAfterDay from '../utils/isInclusivelyAfterDay';
import isInclusivelyBeforeDay from '../utils/isInclusivelyBeforeDay';
import { START_DATE, END_DATE } from '../../constants';
const propTypes = {
startDate: momentPropTypes.momentObj,
startDateId: PropTypes.string,
startDatePlaceholderText: PropTypes.string,
isStartDateFocused: PropTypes.bool,
endDate: momentPropTypes.momentObj,
endDateId: PropTypes.string,
endDatePlaceholderText: PropTypes.string,
isEndDateFocused: PropTypes.bool,
showClearDates: PropTypes.bool,
showCaret: PropTypes.bool,
disabled: PropTypes.bool,
required: PropTypes.bool,
keepOpenOnDateSelect: PropTypes.bool,
reopenPickerOnClearDates: PropTypes.bool,
withFullScreenPortal: PropTypes.bool,
isOutsideRange: PropTypes.func,
displayFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
onFocusChange: PropTypes.func,
onDatesChange: PropTypes.func,
// i18n
phrases: PropTypes.shape({
clearDates: PropTypes.node,
}),
};
const defaultProps = {
startDate: null,
startDateId: START_DATE,
startDatePlaceholderText: 'Start Date',
isStartDateFocused: false,
endDate: null,
endDateId: END_DATE,
endDatePlaceholderText: 'End Date',
isEndDateFocused: false,
showClearDates: false,
showCaret: false,
disabled: false,
required: false,
keepOpenOnDateSelect: false,
reopenPickerOnClearDates: false,
withFullScreenPortal: false,
isOutsideRange: day => !isInclusivelyAfterDay(day, moment()),
displayFormat: () => moment.localeData().longDateFormat('L'),
onFocusChange() {},
onDatesChange() {},
// i18n
phrases: {
clearDates: 'Clear Dates',
},
};
export default class DateRangePickerInputWithHandlers extends React.Component {
constructor(props) {
super(props);
this.onClearFocus = this.onClearFocus.bind(this);
this.onStartDateChange = this.onStartDateChange.bind(this);
this.onStartDateFocus = this.onStartDateFocus.bind(this);
this.onEndDateChange = this.onEndDateChange.bind(this);
this.onEndDateFocus = this.onEndDateFocus.bind(this);
this.clearDates = this.clearDates.bind(this);
}
onClearFocus() {
this.props.onFocusChange(null);
}
onEndDateChange(endDateString) {
const {
startDate,
isOutsideRange,
keepOpenOnDateSelect,
onDatesChange,
onFocusChange,
} = this.props;
const endDate = toMomentObject(endDateString, this.getDisplayFormat());
const isEndDateValid = endDate && !isOutsideRange(endDate) &&
!isInclusivelyBeforeDay(endDate, startDate);
if (isEndDateValid) {
onDatesChange({ startDate, endDate });
if (!keepOpenOnDateSelect) onFocusChange(null);
} else {
onDatesChange({
startDate,
endDate: null,
});
}
}
onEndDateFocus() {
const { startDate, onFocusChange, withFullScreenPortal, disabled } = this.props;
if (!startDate && withFullScreenPortal && !disabled) {
// When the datepicker is full screen, we never want to focus the end date first
// because there's no indication that that is the case once the datepicker is open and it
// might confuse the user
onFocusChange(START_DATE);
} else if (!disabled) {
onFocusChange(END_DATE);
}
}
onStartDateChange(startDateString) {
const startDate = toMomentObject(startDateString, this.getDisplayFormat());
let { endDate } = this.props;
const { isOutsideRange, onDatesChange, onFocusChange } = this.props;
const isStartDateValid = startDate && !isOutsideRange(startDate);
if (isStartDateValid) {
if (isInclusivelyBeforeDay(endDate, startDate)) {
endDate = null;
}
onDatesChange({ startDate, endDate });
onFocusChange(END_DATE);
} else {
onDatesChange({
startDate: null,
endDate,
});
}
}
onStartDateFocus() {
if (!this.props.disabled) {
this.props.onFocusChange(START_DATE);
}
}
getDisplayFormat() {
const { displayFormat } = this.props;
return typeof displayFormat === 'string' ? displayFormat : displayFormat();
}
getDateString(date) {
const displayFormat = this.getDisplayFormat();
if (date && displayFormat) {
return date && date.format(displayFormat);
}
return toLocalizedDateString(date);
}
clearDates() {
const { onDatesChange, reopenPickerOnClearDates, onFocusChange } = this.props;
onDatesChange({ startDate: null, endDate: null });
if (reopenPickerOnClearDates) {
onFocusChange(START_DATE);
}
}
render() {
const {
startDate,
startDateId,
startDatePlaceholderText,
isStartDateFocused,
endDate,
endDateId,
endDatePlaceholderText,
isEndDateFocused,
showClearDates,
showCaret,
disabled,
required,
phrases,
} = this.props;
const startDateString = this.getDateString(startDate);
const endDateString = this.getDateString(endDate);
return (
<DateRangePickerInput
startDate={startDateString}
startDateId={startDateId}
startDatePlaceholderText={startDatePlaceholderText}
isStartDateFocused={isStartDateFocused}
endDate={endDateString}
endDateId={endDateId}
endDatePlaceholderText={endDatePlaceholderText}
isEndDateFocused={isEndDateFocused}
disabled={disabled}
required={required}
showCaret={showCaret}
phrases={phrases}
onStartDateChange={this.onStartDateChange}
onStartDateFocus={this.onStartDateFocus}
onStartDateShiftTab={this.onClearFocus}
onEndDateChange={this.onEndDateChange}
onEndDateFocus={this.onEndDateFocus}
onEndDateTab={this.onClearFocus}
showClearDates={showClearDates}
onClearDates={this.clearDates}
/>
);
}
}
DateRangePickerInputWithHandlers.propTypes = propTypes;
DateRangePickerInputWithHandlers.defaultProps = defaultProps;
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment