/** @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'; import { date as datePHPFormat, getSettings } from '@wordpress/date'; /** * 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 PHPFormatString = getSettings().formats.date; class DateRange extends Component { constructor( props ) { super( props ); const { start, end } = props; this.state = { focusedInput: START_DATE, startText: start ? datePHPFormat( PHPFormatString, start ) : '', endText: end ? datePHPFormat( PHPFormatString, end ) : '', }; 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( { startText: startDate ? datePHPFormat( PHPFormatString, startDate ) : '', endText: endDate ? datePHPFormat( PHPFormatString, endDate ) : '', } ); this.props.onSelect( { start: startDate, end: endDate, } ); } onFocusChange( focusedInput ) { this.setState( { focusedInput: ! focusedInput ? START_DATE : focusedInput, } ); } onInputChange( input, event ) { const value = event.target.value; this.setState( { [ input ]: value } ); const date = toMoment( value ); if ( date ) { const match = input.match( /.*(?=Text)/ ); if ( match ) { this.props.onSelect( { [ match[ 0 ] ]: 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, startText, endText } = this.state; const { start, end } = 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' ), PHPFormatString ) }

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

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

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