/** @format */ /** * External dependencies */ import { Component, Fragment } from '@wordpress/element'; import moment from 'moment'; import { DayPickerRangeController, isInclusivelyAfterDay, isInclusivelyBeforeDay, } from 'react-dates'; import { partial } from 'lodash'; import { __, sprintf } from '@wordpress/i18n'; import classnames from 'classnames'; import PropTypes from 'prop-types'; import 'react-dates/lib/css/_datepicker.css'; /** * Internal dependencies */ import { toMoment } from 'lib/date'; import phrases from './phrases'; import './style.scss'; const START_DATE = 'startDate'; const END_DATE = 'endDate'; // 782px is the width designated by Gutenberg's `` component. // * https://github.com/WordPress/gutenberg/blob/c8f8806d4465a83c1a0bc62d5c61377b56fa7214/components/popover/utils.js#L6 const isMobileViewport = () => window.innerWidth < 782; const shortDateFormat = __( 'MM/DD/YYYY', 'woo-dash' ); class DateRange extends Component { constructor( props ) { super( props ); const { after, before } = props; this.state = { focusedInput: START_DATE, afterText: after ? after.format( shortDateFormat ) : '', beforeText: before ? before.format( shortDateFormat ) : '', }; this.onDatesChange = this.onDatesChange.bind( this ); this.onFocusChange = this.onFocusChange.bind( this ); this.onInputChange = this.onInputChange.bind( this ); this.getOutsideRange = this.getOutsideRange.bind( this ); } onDatesChange( { startDate, endDate } ) { this.setState( { afterText: startDate ? startDate.format( shortDateFormat ) : '', beforeText: endDate ? endDate.format( shortDateFormat ) : '', } ); this.props.onSelect( { after: startDate, before: endDate, } ); } onFocusChange( focusedInput ) { this.setState( { focusedInput: ! focusedInput ? START_DATE : focusedInput, } ); } onInputChange( input, event ) { const value = event.target.value; this.setState( { [ input + 'Text' ]: value } ); const date = toMoment( shortDateFormat, value ); if ( date ) { this.props.onSelect( { [ input ]: date, } ); } } getOutsideRange() { const { inValidDays } = this.props; if ( 'string' === typeof inValidDays ) { switch ( inValidDays ) { case 'past': return day => isInclusivelyBeforeDay( day, moment() ); case 'future': return day => isInclusivelyAfterDay( day, moment() ); case 'none': default: return undefined; } } return 'function' === typeof inValidDays ? inValidDays : undefined; } render() { const { focusedInput, afterText, beforeText } = this.state; const { after, before } = this.props; const isOutsideRange = this.getOutsideRange(); const isMobile = isMobileViewport(); return (

{ sprintf( __( "Date input describing a selected date range's start date in format %s", 'woo-dash' ), shortDateFormat ) }

{ __( 'to', 'woo-dash' ) }

{ sprintf( __( "Date input describing a selected date range's end date in format %s", 'woo-dash' ), shortDateFormat ) }

after || moment() } phrases={ phrases } />
); } } DateRange.propTypes = { after: PropTypes.object, before: PropTypes.object, onSelect: PropTypes.func.isRequired, inValidDays: PropTypes.oneOfType( [ PropTypes.oneOf( [ 'past', 'future', 'none' ] ), PropTypes.func, ] ), }; export { DateRange };