<commit_before>import BpkInput from 'bpk-component-input';
import BpkModal from 'bpk-component-modal';
import BpkPopover from 'bpk-component-popover';
import React, { PropTypes, Component } from 'react';
import BpkBreakpoint, { BREAKPOINTS } from 'bpk-component-breakpoint';
import BpkCalendar, { CustomPropTypes } from 'bpk-component-calendar';

import './bpk-datepicker.scss';

const KEYCODES = {
  ENTER: 13,
  SPACEBAR: 32,
};

const handleKeyEvent = (keyCode, callback) => (e) => {
  if (e.keyCode === keyCode) {
    e.preventDefault();
    callback();
  }
};

class BpkDatepicker extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isOpen: false,
    };

    this.onOpen = this.onOpen.bind(this);
    this.onClose = this.onClose.bind(this);
    this.handleDateSelect = this.handleDateSelect.bind(this);

    this.focusCanOpen = true;
  }

  onOpen() {
    this.setState({
      isOpen: true,
    });
  }

  onClose() {
    this.setState({
      isOpen: false,
    });
  }

  handleDateSelect(dateObj) {
    this.setState({
      isOpen: false,
    });
    if (this.props.onDateSelect) {
      this.props.onDateSelect(dateObj);
    }
  }

  render() {
    const {
      changeMonthLabel,
      closeButtonText,
      DateComponent,
      date,
      dateModifiers,
      daysOfWeek,
      formatDate,
      formatDateFull,
      formatMonth,
      id,
      inputProps,
      markOutsideDays,
      markToday,
      maxDate,
      minDate,
      title,
      showWeekendSeparator,
      weekStartsOn,
      getApplicationElement,
      ...rest
    } = this.props;

    const {
      onClick,
      onFocus,
      onBlur,
      onTouchEnd,
      onKeyDown,
      onKeyUp,
      ...restInputProps
    } = inputProps;

    // The following props are not used in render
    delete rest.onDateSelect;

    const inputComponent = (
      <BpkInput
        id={id}
        name={`${id}_input`}
        value={date ? formatDate(date) : ''}
        onClick={(event) => {
          this.onOpen();
          if (onClick) {
            onClick(event);
          }
        }}
        onFocus={(event) => {
          if (this.focusCanOpen) {
            this.onOpen();
          }
          if (onFocus) {
            onFocus(event);
          }
        }}
        onBlur={(event) => {
          if (this.state.isOpen) {
            // If the input loses focus when the popover/modal is open, it should not open on a subsequent focus.
            // Fixes an issue with IE9.
            this.focusCanOpen = false;
          } else {
            this.focusCanOpen = true;
          }
          if (onBlur) {
            onBlur(event);
          }
        }}
        onTouchEnd={(event) => {
          // preventDefault fixes an issue on Android and iOS in which the popover closes immediately
          // because a touch event is registered on one of the dates.
          event.preventDefault();
          this.onOpen();
          if (onTouchEnd) {
            onTouchEnd(event);
          }
        }}
        onKeyDown={(event) => {
          handleKeyEvent(KEYCODES.ENTER, this.onOpen)(event);
          if (onKeyDown) {
            onKeyDown(event);
          }
        }}
        onKeyUp={(event) => {
          handleKeyEvent(KEYCODES.SPACEBAR, this.onOpen)(event);
          if (onKeyUp) {
            onKeyUp(event);
          }
        }}
        className="bpk-datepicker__input"
        aria-live="assertive"<commit_msg>Create HOF for passing through of event handlers<commit_after>import BpkInput from 'bpk-component-input';
import BpkModal from 'bpk-component-modal';
import BpkPopover from 'bpk-component-popover';
import React, { PropTypes, Component } from 'react';
import BpkBreakpoint, { BREAKPOINTS } from 'bpk-component-breakpoint';
import BpkCalendar, { CustomPropTypes } from 'bpk-component-calendar';

import './bpk-datepicker.scss';

const KEYCODES = {
  ENTER: 13,
  SPACEBAR: 32,
};

const handleKeyEvent = (keyCode, callback) => (e) => {
  if (e.keyCode === keyCode) {
    e.preventDefault();
    callback();
  }
};

const withEventHandler = (fn, eventHandler) => (e) => {
  fn(e);
  if (eventHandler) {
    eventHandler(e);
  }
};

class BpkDatepicker extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isOpen: false,
    };

    this.onOpen = this.onOpen.bind(this);
    this.onClose = this.onClose.bind(this);
    this.handleDateSelect = this.handleDateSelect.bind(this);

    this.focusCanOpen = true;
  }

  onOpen() {
    this.setState({
      isOpen: true,
    });
  }

  onClose() {
    this.setState({
      isOpen: false,
    });
  }

  handleDateSelect(dateObj) {
    this.setState({
      isOpen: false,
    });
    if (this.props.onDateSelect) {
      this.props.onDateSelect(dateObj);
    }
  }

  render() {
    const {
      changeMonthLabel,
      closeButtonText,
      DateComponent,
      date,
      dateModifiers,
      daysOfWeek,
      formatDate,
      formatDateFull,
      formatMonth,
      id,
      inputProps,
      markOutsideDays,
      markToday,
      maxDate,
      minDate,
      title,
      showWeekendSeparator,
      weekStartsOn,
      getApplicationElement,
      ...rest
    } = this.props;

    const {
      onClick,
      onFocus,
      onBlur,
      onTouchEnd,
      onKeyDown,
      onKeyUp,
      ...restInputProps
    } = inputProps;

    // The following props are not used in render
    delete rest.onDateSelect;

    const inputComponent = (
      <BpkInput
        id={id}
        name={`${id}_input`}
        value={date ? formatDate(date) : ''}
        onClick={withEventHandler(this.onOpen, onClick)}
        onFocus={withEventHandler(() => {
          if (this.focusCanOpen) {
            this.onOpen();
          }
        }, onFocus)}
        onBlur={withEventHandler(() => {
          if (this.state.isOpen) {
            // If the input loses focus when the popover/modal is open, it should not open on a subsequent focus.
            // Fixes an issue with IE9.
            this.focusCanOpen = false;
          } else {
            this.focusCanOpen = true;
          }
        }, onBlur)}
        onTouchEnd={withEventHandler((event) => {
          // preventDefault fixes an issue on Android and iOS in which the popover closes immediately
          // because a touch event is registered on one of the dates.
          event.preventDefault();
          this.onOpen();
        }, onTouchEnd)}
        onKeyDown={withEventHandler(handleKeyEvent(KEYCODES.ENTER, this.onOpen), onKeyDown)}
        onKeyUp={withEventHandler(handleKeyEvent(KEYCODES.SPACEBAR, this.onOpen), onKeyUp)}
        className="bpk-datepicker__input"
        aria-live="assertive"
{'fraction_non_alphanumeric': 0.11752423564504101, 'fraction_numerical': 0.0014914243102162564, 'mean_word_length': 2.049567985447931, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3867455', 'n_tokens_mistral': 2081, 'n_tokens_neox': 2063, 'n_words': 436}