<commit_before>import React, { Component, PropTypes } from 'react';
import PrevMonth from './PrevMonth';
import NextMonth from './NextMonth';
import { getWeeks, navigateMonth, isSame, isBeforeDay, isAfterDay, isOutsideMonth, formatMonth, formatYear } from './utils';

const WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

class Day extends Component {

  _handleDateSelect(day) {
    this.props.onDateSelect(day);
  }

  render() {

    const {month, date, disabledDays, minDay, maxDay, selectedDays, outsideDays, onClick} = this.props;

    let className = 'cal__day';
    let modifiers = [];
    let onDayClick = this._handleDateSelect.bind(this, date);

    const isToday = isSame(date, new Date());

    if(isToday) {
      modifiers.push('today');
    }

    const isOutside = isOutsideMonth(date, month);

    if(isOutside) {
      modifiers.push('outside');
    }

    const isDisabled = disabledDays ? isSame(date, disabledDays) : null;
    const isBefore = minDay ? isBeforeDay(date, minDay) : null;
    const isAfter = maxDay ? isAfterDay(date, maxDay) : null;

    if(isDisabled || isBefore || isAfter) {
      modifiers.push('disabled');
      onDayClick = null;
    }

    if(selectedDays) {

      const isSelected = isSame(date, selectedDays);

      if(isSelected || isSelected === 0) {
        modifiers.push('selected');
      }

      if(isSelected === 0) {
        modifiers.push('selected-first');
      }

      if(isSelected === selectedDays.length - 1) {
        modifiers.push('selected-last');
      }
    }

    className += modifiers.map(modifier => ` ${className}--${modifier}`).join('');

    if(isOutside && !outsideDays) {
      return <td aria-hidden="true" className={className} />;
    }

    return(
      <td
        role="presentation"
        aria-label={date}
        className={className}
        onClick={onDayClick}
      >
        {date.getDate()}
      </td>
    );
  }
}

class Week extends Component {

  render() {

    const {date, month} = this.props;

    let days = this.props.days.map(day =>
      <Day
        key={day.getTime()}
        date={day}
        month={month}
        minDay={this.props.minDay}
        maxDay={this.props.maxDay}
        disabledDays={this.props.disabledDays}
        selectedDays={this.props.selectedDays}
        outsideDays={this.props.outsideDays}
        onDateSelect={this.props.onDateSelect}
      />
    );

    return(
      <tr className="cal__week">
        {days}
      </tr>
    );
  }
}

class Calendar extends Component {

  static propTypes = {
    date: PropTypes.instanceOf(Date),
    minDay: PropTypes.instanceOf(Date),
    maxDay: PropTypes.instanceOf(Date),
    disabledDays: PropTypes.array,
    selectedDays: PropTypes.array,
    trimWeekdays: PropTypes.number,
    weekStartsOn: PropTypes.number,
    forceSixRows: PropTypes.bool,
    outsideDays: PropTypes.bool,
    onDateSelect: PropTypes.func,
    prevHTML: PropTypes.node,
    nextHTML: PropTypes.node,
    prevDisabled: PropTypes.bool,
    nextDisabled: PropTypes.bool
    // events: PropTypes.array,
  }

  static defaultProps = {
    date: new Date(),
    minDay: null,
    maxDay: null,
    // instead of passing things like disabledDays and selectedDays
    // we could pass an object and the proper class will get appended
    // to it so the user could pass custom days, maybe Sunday is a special
    // day and needs to be treated a certain way, could go alongside
    // the events prop below we want to implement
    disabledDays: null,
    selectedDays: null,
    trimWeekdays: null,
    weekStartsOn: 0,
    forceSixRows: true,
    outsideDays: true,
    onDateSelect: () => null,
    prevHTML: '',
    nextHTML: ''
    // show how we could map events using microformat
    // https://moz.com/blog/markup-events-hcalendar-microformat
    // https://developer.mozilla.org/en-US/docs/The_hCalendar_microformat
    // events: [],
  }

  state = {
    month: this.props.date
  }

  componentWillMount() {
    if(this.props.selectedDays) {
      this._normalizeDates(this.props.selectedDays);
    }
    if(this.props.disabledDays) {
      this._normalizeDates(this.props.disabledDays);
    }
  }

  componentWillReceiveProps(nextProps) {
    if(nextProps.selectedDays) {
      this._normalizeDates(nextProps.selectedDays);
    }
    if(nextProps.disabledDays) {
      this._normalizeDates(nextProps.disabledDays);
    }
    this.setState({month: nextProps.date});
  }

  _normalizeDates(mixed) {

    let month = new Date();

    for(let i = mixed.length; i--;) {

      let mix = mixed[i];

        // if it's a Date object already then push it
        // and contiue
        if(mix instanceof Date) {
          mixed[i] = mix;
          continue;
        }

        // test if digit and in between current month
        // or test to block day of week out somehow
        // reference pickadate and how they do it
        // just block out day for now
        if(/^\d+$/.test(mix)) {
          mixed[i] = new Date(month.getFullYear(), month.getMonth(), mix);<commit_msg>fixed bug where state would get updated with same month from prop<commit_after>import React, { Component, PropTypes } from 'react';
import PrevMonth from './PrevMonth';
import NextMonth from './NextMonth';
import { getWeeks, navigateMonth, isSame, isBeforeDay, isAfterDay, isOutsideMonth, formatMonth, formatYear } from './utils';

const WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

class Day extends Component {

  _handleDateSelect(day) {
    this.props.onDateSelect(day);
  }

  render() {

    const {month, date, disabledDays, minDay, maxDay, selectedDays, outsideDays, onClick} = this.props;

    let className = 'cal__day';
    let modifiers = [];
    let onDayClick = this._handleDateSelect.bind(this, date);

    const isToday = isSame(date, new Date());

    if(isToday) {
      modifiers.push('today');
    }

    const isOutside = isOutsideMonth(date, month);

    if(isOutside) {
      modifiers.push('outside');
    }

    const isDisabled = disabledDays ? isSame(date, disabledDays) : null;
    const isBefore = minDay ? isBeforeDay(date, minDay) : null;
    const isAfter = maxDay ? isAfterDay(date, maxDay) : null;

    if(isDisabled || isBefore || isAfter) {
      modifiers.push('disabled');
      onDayClick = null;
    }

    if(selectedDays) {

      const isSelected = isSame(date, selectedDays);

      if(isSelected || isSelected === 0) {
        modifiers.push('selected');
      }

      if(isSelected === 0) {
        modifiers.push('selected-first');
      }

      if(isSelected === selectedDays.length - 1) {
        modifiers.push('selected-last');
      }
    }

    className += modifiers.map(modifier => ` ${className}--${modifier}`).join('');

    if(isOutside && !outsideDays) {
      return <td aria-hidden="true" className={className} />;
    }

    return(
      <td
        role="presentation"
        aria-label={date}
        className={className}
        onClick={onDayClick}
      >
        {date.getDate()}
      </td>
    );
  }
}

class Week extends Component {

  render() {

    const {date, month} = this.props;

    let days = this.props.days.map(day =>
      <Day
        key={day.getTime()}
        date={day}
        month={month}
        minDay={this.props.minDay}
        maxDay={this.props.maxDay}
        disabledDays={this.props.disabledDays}
        selectedDays={this.props.selectedDays}
        outsideDays={this.props.outsideDays}
        onDateSelect={this.props.onDateSelect}
      />
    );

    return(
      <tr className="cal__week">
        {days}
      </tr>
    );
  }
}

class Calendar extends Component {

  static propTypes = {
    date: PropTypes.instanceOf(Date),
    minDay: PropTypes.instanceOf(Date),
    maxDay: PropTypes.instanceOf(Date),
    disabledDays: PropTypes.array,
    selectedDays: PropTypes.array,
    trimWeekdays: PropTypes.number,
    weekStartsOn: PropTypes.number,
    forceSixRows: PropTypes.bool,
    outsideDays: PropTypes.bool,
    onDateSelect: PropTypes.func,
    prevHTML: PropTypes.node,
    nextHTML: PropTypes.node,
    prevDisabled: PropTypes.bool,
    nextDisabled: PropTypes.bool
    // events: PropTypes.array,
  }

  static defaultProps = {
    date: new Date(),
    minDay: null,
    maxDay: null,
    // instead of passing things like disabledDays and selectedDays
    // we could pass an object and the proper class will get appended
    // to it so the user could pass custom days, maybe Sunday is a special
    // day and needs to be treated a certain way, could go alongside
    // the events prop below we want to implement
    disabledDays: null,
    selectedDays: null,
    trimWeekdays: null,
    weekStartsOn: 0,
    forceSixRows: true,
    outsideDays: true,
    onDateSelect: () => null,
    prevHTML: '',
    nextHTML: ''
    // show how we could map events using microformat
    // https://moz.com/blog/markup-events-hcalendar-microformat
    // https://developer.mozilla.org/en-US/docs/The_hCalendar_microformat
    // events: [],
  }

  state = {
    month: this.props.date
  }

  componentWillMount() {
    if(this.props.selectedDays) {
      this._normalizeDates(this.props.selectedDays);
    }
    if(this.props.disabledDays) {
      this._normalizeDates(this.props.disabledDays);
    }
  }

  componentWillReceiveProps(nextProps) {
    if(nextProps.selectedDays) {
      this._normalizeDates(nextProps.selectedDays);
    }
    if(nextProps.disabledDays) {
      this._normalizeDates(nextProps.disabledDays);
    }
    if(this.props.month !== nextProps.month) {
      this.setState({month: nextProps.date});
    }
  }

  _normalizeDates(mixed) {

    let month = new Date();

    for(let i = mixed.length; i--;) {

      let mix = mixed[i];

        // if it's a Date object already then push it
        // and contiue
        if(mix instanceof Date) {
          mixed[i] = mix;
          continue;
        }

        // test if digit and in between current month
        // or test to block day of week out somehow
        // reference pickadate and how they do it
        // just block out day for now
        if(/^\d+$/.test(mix)) {
          mixed[i] = new Date(month.getFullYear(), month.getMonth(), mix);
{'fraction_non_alphanumeric': 0.12496350364963503, 'fraction_numerical': 0.0007785888077858881, 'mean_word_length': 2.6569395017793593, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 21, 'https://': 4, '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': '3693613', 'n_tokens_mistral': 3253, 'n_tokens_neox': 3088, 'n_words': 738}