Blueprint: Feature Request: DateTimeRangePicker

Created on 20 Jan 2017  路  6Comments  路  Source: palantir/blueprint

I'd like to use a DateRangePicker but will also need time controls. Existing workarounds involve either using two separate DateTimePickers for start/end date (not ideal), or using a DateRangePicker with separate start/end time controls (even less ideal). Would love either a dedicated DateTimeRangePicker component or support for time controls in the existing DateRangePicker.

datetime feature request

Most helpful comment

this suggests to me that we may want to reconsider the datetime components such that a (Date|Range|Time)+Picker is composed from a handful of other components to meet a user's exact needs.

All 6 comments

@cmslewis worth thinking about time in the input you're building in anticipation for this feature

Noted.

this suggests to me that we may want to reconsider the datetime components such that a (Date|Range|Time)+Picker is composed from a handful of other components to meet a user's exact needs.

+1. Would also be great to be able to create a DateRangeInput again ideally with time controls, so if there's any work being put into the Date*Input component that'd be good to consider. Also maybe not the right ticket for this but chrome's type="date" input (http://www.w3schools.com/html/tryit.asp?filename=tryhtml_input_date) interactions are nice, having each day/month/year section act as separate inputs that auto-tab as you complete a section.

Currently, I just use the following code as a workaround for an incomplete and buggy DateTimeRangeInput component:

import React from 'react';
import addDays from 'date-fns/add_days';
import subDays from 'date-fns/sub_days';
import classNames from 'classnames';
import {Classes, Popover, Position, Boundary} from '@blueprintjs/core';
import {
  DateRangeInput,
  DateTimePicker,
  DateRangePicker
} from '@blueprintjs/datetime';
import * as DateClasses from '@blueprintjs/datetime/lib/esm/common/classes';
import * as DateUtils from '@blueprintjs/datetime/lib/esm/common/dateUtils';
import {combineModifiers} from '@blueprintjs/datetime/lib/esm/datePickerCore';

class DateTimeRangePicker extends DateRangePicker {
  onLeftDateTimePickerValueChange = date => {
    const {value} = this.state;
    const {onChange} = this.props;

    onChange([date, value[1] || addDays(date, 1)]);
  };

  onRightDateTimePickerValueChange = date => {
    const {value} = this.state;
    const {onChange} = this.props;

    onChange([value[0] || subDays(date, 1), date]);
  };

  render() {
    const modifiers = combineModifiers(this.modifiers, this.props.modifiers);
    const {
      locale,
      maxDate,
      minDate,
      className,
      localeUtils,
      dayPickerProps
    } = this.props;

    const {leftView, rightView} = this.state;
    const disabledDays = this.getDisabledDaysModifier();

    const dayPickerBaseProps = {
      locale,
      modifiers,
      localeUtils,
      showOutsideDays: true,
      ...dayPickerProps,
      onDayClick: this.handleDayClick,
      disabledDays,
      selectedDays: this.state.value,
      onDayMouseEnter: this.handleDayMouseEnter,
      onDayMouseLeave: this.handleDayMouseLeave
    };

    return (
      <div
        className={classNames(
          DateClasses.DATEPICKER,
          DateClasses.DATERANGEPICKER,
          className
        )}>
        {this.maybeRenderShortcuts()}

        <DateTimePicker
          value={this.state.value[0]}
          onChange={this.onLeftDateTimePickerValueChange}
          datePickerProps={{
            dayPickerProps: {
              ...dayPickerBaseProps,
              month: leftView.getFullDate(),
              toMonth: DateUtils.getDatePreviousMonth(maxDate),
              fromMonth: minDate,
              onMonthChange: this.handleLeftMonthChange,
              canChangeMonth: true,
              captionElement: this.renderLeftCaption
            }
          }}
        />

        <DateTimePicker
          value={this.state.value[1]}
          onChange={this.onRightDateTimePickerValueChange}
          datePickerProps={{
            dayPickerProps: {
              ...dayPickerBaseProps,
              month: rightView.getFullDate(),
              toMonth: DateUtils.getDatePreviousMonth(minDate),
              fromMonth: maxDate,
              onMonthChange: this.handleRightMonthChange,
              canChangeMonth: true,
              captionElement: this.renderRightCaption
            }
          }}
        />
      </div>
    );
  }
}

export default class DateTimeRangeInput extends DateRangeInput {
  render() {
    const {className, popoverProps = {}} = this.props;

    const popoverContent = (
      <DateTimeRangePicker
        {...this.props}
        value={this.getSelectedRange()}
        onChange={this.handleDateRangePickerChange}
        onHoverChange={this.handleDateRangePickerHoverChange}
        boundaryToModify={this.state.boundaryToModify}
      />
    );

    const popoverClassName = classNames(popoverProps.className, className);

    return (
      <Popover
        isOpen={this.state.isOpen}
        position={Position.BOTTOM_LEFT}
        {...popoverProps}
        content={popoverContent}
        onClose={this.handlePopoverClose}
        autoFocus={false}
        className={popoverClassName}
        enforceFocus={false}>
        <div className={Classes.CONTROL_GROUP}>
          {this.renderInputGroup(Boundary.START)}
          {this.renderInputGroup(Boundary.END)}
        </div>
      </Popover>
    );
  }
}

But a official <DateTimeRangeInput> component from you guys would be great.

intended appearance:
daterangepicker time

Was this page helpful?
0 / 5 - 0 ratings

Related issues

havesomeleeway picture havesomeleeway  路  3Comments

havesomeleeway picture havesomeleeway  路  3Comments

vinz243 picture vinz243  路  3Comments

giladgray picture giladgray  路  3Comments

sunabozu picture sunabozu  路  3Comments