"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _react = _interopRequireDefault(require("react"));

var _index = require("../button/index.js");

var _calendarHeader = _interopRequireDefault(require("./calendar-header.js"));

var _month = _interopRequireDefault(require("./month.js"));

var _styledComponents = require("./styled-components.js");

var _index2 = require("./utils/index.js");

var _constants = require("./constants.js");

var _overrides = require("../helpers/overrides.js");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

var Calendar =
/*#__PURE__*/
function (_React$Component) {
  _inherits(Calendar, _React$Component);

  function Calendar(props) {
    var _this;

    _classCallCheck(this, Calendar);

    _this = _possibleConstructorReturn(this, _getPrototypeOf(Calendar).call(this, props));

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "root", void 0);

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "calendar", void 0);

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "getDateInView", function () {
      var _this$props = _this.props,
          highlightedDate = _this$props.highlightedDate,
          value = _this$props.value;
      var minDate = (0, _index2.getEffectiveMinDate)(_this.props);
      var maxDate = (0, _index2.getEffectiveMaxDate)(_this.props);
      var current = new Date();
      var initialDate = _this.getSingleDate(value) || highlightedDate;

      if (initialDate) {
        return initialDate;
      } else {
        if (minDate && (0, _index2.isBefore)(current, minDate)) {
          return minDate;
        } else if (maxDate && (0, _index2.isAfter)(current, maxDate)) {
          return maxDate;
        }
      }

      return current;
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleMonthChange", function (date) {
      _this.setHighlightedDate(date);

      if (_this.props.onMonthChange) {
        _this.props.onMonthChange({
          date: date
        });
      }
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleYearChange", function (date) {
      _this.setHighlightedDate(date);

      if (_this.props.onYearChange) {
        _this.props.onYearChange({
          date: date
        });
      }
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "changeMonth", function (_ref) {
      var date = _ref.date;

      _this.setState({
        date: date
      }, function () {
        return _this.handleMonthChange(_this.state.date);
      });
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "changeYear", function (_ref2) {
      var date = _ref2.date;

      _this.setState({
        date: date
      }, function () {
        return _this.handleYearChange(_this.state.date);
      });
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "renderCalendarHeader", function () {
      var date = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.state.date;
      var order = arguments.length > 1 ? arguments[1] : undefined;
      return _react.default.createElement(_calendarHeader.default, _extends({}, _this.props, {
        key: "month-header-".concat(order),
        date: date,
        order: order,
        onMonthChange: _this.changeMonth,
        onYearChange: _this.changeYear
      }));
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "renderMonthHeader", function () {
      var date = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.state.date;
      var order = arguments.length > 1 ? arguments[1] : undefined;
      var _this$props2 = _this.props,
          locale = _this$props2.locale,
          _this$props2$override = _this$props2.overrides,
          overrides = _this$props2$override === void 0 ? {} : _this$props2$override;
      var startOfWeek = (0, _index2.getStartOfWeek)(date, locale);

      var _getOverrides = (0, _overrides.getOverrides)(overrides.MonthHeader, _styledComponents.StyledMonthHeader),
          _getOverrides2 = _slicedToArray(_getOverrides, 2),
          MonthHeader = _getOverrides2[0],
          monthHeaderProps = _getOverrides2[1];

      var _getOverrides3 = (0, _overrides.getOverrides)(overrides.WeekdayHeader, _styledComponents.StyledDay),
          _getOverrides4 = _slicedToArray(_getOverrides3, 2),
          WeekdayHeader = _getOverrides4[0],
          weekdayHeaderProps = _getOverrides4[1];

      return _react.default.createElement(MonthHeader, _extends({
        role: "presentation"
      }, monthHeaderProps), _constants.WEEKDAYS.map(function (offset) {
        var day = (0, _index2.addDays)(startOfWeek, offset);
        return _react.default.createElement(WeekdayHeader, _extends({
          $disabled: true,
          key: offset
        }, weekdayHeaderProps), (0, _index2.getWeekdayMinInLocale)(day, locale));
      }));
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "onKeyDown", function (event) {
      switch (event.key) {
        case 'ArrowUp':
        case 'ArrowDown':
        case 'ArrowLeft':
        case 'ArrowRight':
          _this.handleArrowKey(event.key);

          event.preventDefault();
          event.stopPropagation();
          break;
      }
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleArrowKey", function (key) {
      var oldDate = _this.state.highlightedDate;
      var highlightedDate = oldDate;

      switch (key) {
        case 'ArrowLeft':
          // adding `new Date()` as the last option to satisfy Flow
          highlightedDate = (0, _index2.subDays)(highlightedDate ? highlightedDate : new Date(), 1);
          break;

        case 'ArrowRight':
          highlightedDate = (0, _index2.addDays)( // adding `new Date()` as the last option to satisfy Flow
          highlightedDate ? highlightedDate : new Date(), 1);
          break;

        case 'ArrowUp':
          highlightedDate = (0, _index2.subWeeks)( // adding `new Date()` as the last option to satisfy Flow
          highlightedDate ? highlightedDate : new Date(), 1);
          break;

        case 'ArrowDown':
          highlightedDate = (0, _index2.addWeeks)( // adding `new Date()` as the last option to satisfy Flow
          highlightedDate ? highlightedDate : new Date(), 1);
          break;
      }

      _this.setState({
        highlightedDate: highlightedDate,
        date: highlightedDate
      });
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "focusCalendar", function () {
      if (!_this.state.focused) {
        _this.setState({
          focused: true
        });
      }
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "blurCalendar", function () {
      if (typeof document !== 'undefined') {
        var activeElm = document.activeElement;

        if (_this.calendar && !_this.calendar.contains(activeElm)) {
          _this.setState({
            focused: false
          });
        }
      }
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleTabbing", function (event) {
      if (typeof document !== 'undefined') {
        if (event.keyCode === 9) {
          var activeElm = document.activeElement; // need to look for any tabindex >= 0 and ideally for not disabled
          // focusable by default elements like input, button, etc.

          var focusable = _this.root ? _this.root.querySelectorAll('[tabindex="0"]') : null;
          var length = focusable ? focusable.length : 0;

          if (event.shiftKey) {
            if (focusable && activeElm === focusable[0]) {
              event.preventDefault();
              focusable[length - 1].focus();
            }
          } else {
            if (focusable && activeElm === focusable[length - 1]) {
              event.preventDefault();
              focusable[0].focus();
            }
          }
        }
      }
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "onDayMouseOver", function (data) {
      var date = data.date;

      _this.setState({
        highlightedDate: date
      });

      _this.props.onDayMouseOver(data);
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "onDayMouseLeave", function (data) {
      var date = data.date;

      _this.setHighlightedDate(date);

      _this.props.onDayMouseLeave(data);
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "renderMonths", function () {
      var _this$props$overrides = _this.props.overrides,
          overrides = _this$props$overrides === void 0 ? {} : _this$props$overrides;
      var monthList = [];

      var _getOverrides5 = (0, _overrides.getOverrides)(overrides.CalendarContainer, _styledComponents.StyledCalendarContainer),
          _getOverrides6 = _slicedToArray(_getOverrides5, 2),
          CalendarContainer = _getOverrides6[0],
          calendarContainerProps = _getOverrides6[1];

      for (var i = 0; i < _this.props.monthsShown; ++i) {
        var monthDate = (0, _index2.addMonths)(_this.state.date, i);
        var monthKey = "month-".concat(i);
        monthList.push(_this.renderCalendarHeader(monthDate, i));
        monthList.push(_react.default.createElement(CalendarContainer, _extends({
          key: monthKey,
          $ref: function $ref(calendar) {
            _this.calendar = calendar;
          },
          onKeyDown: _this.onKeyDown
        }, calendarContainerProps), _this.renderMonthHeader(monthDate, i), _react.default.createElement(_month.default, {
          date: monthDate,
          excludeDates: _this.props.excludeDates,
          filterDate: _this.props.filterDate,
          highlightedDate: _this.state.highlightedDate,
          includeDates: _this.props.includeDates,
          focusedCalendar: _this.state.focused,
          range: _this.props.range,
          locale: _this.props.locale,
          maxDate: _this.props.maxDate,
          minDate: _this.props.minDate,
          month: (0, _index2.getMonth)(_this.state.date),
          onDayBlur: _this.blurCalendar,
          onDayFocus: _this.focusCalendar,
          onDayClick: _this.props.onDayClick,
          onDayMouseOver: _this.onDayMouseOver,
          onDayMouseLeave: _this.onDayMouseLeave,
          onChange: _this.props.onChange,
          overrides: overrides,
          value: _this.props.value,
          peekNextMonth: _this.props.peekNextMonth
        })));
      }

      return monthList;
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "renderQuickSelect", function () {
      var _this$props$overrides2 = _this.props.overrides,
          overrides = _this$props$overrides2 === void 0 ? {} : _this$props$overrides2;

      var _getOverrides7 = (0, _overrides.getOverrides)(overrides.QuickSelectContainer, _styledComponents.StyledQuickSelectContainer),
          _getOverrides8 = _slicedToArray(_getOverrides7, 2),
          QuickSelectContainer = _getOverrides8[0],
          quickSelectContainerProps = _getOverrides8[1];

      var _getOverrides9 = (0, _overrides.getOverrides)(overrides.QuickSelectLabel, _styledComponents.StyledQuickSelectLabel),
          _getOverrides10 = _slicedToArray(_getOverrides9, 2),
          QuickSelectLabel = _getOverrides10[0],
          quickSelectLabelProps = _getOverrides10[1];

      var _getOverrides11 = (0, _overrides.getOverrides)(overrides.QuickSelectButtons, _styledComponents.StyledQuickSelectButtons),
          _getOverrides12 = _slicedToArray(_getOverrides11, 2),
          QuickSelectButtons = _getOverrides12[0],
          quickSelectButtonsProps = _getOverrides12[1];

      if (!_this.props.range || !_this.props.quickSelect) {
        return null;
      }

      var NOW = new Date();
      var QUICK_SELECT_ACTIONS = [{
        label: 'Past Week',
        beginDate: (0, _index2.subWeeks)(NOW, 1)
      }, {
        label: 'Past Month',
        beginDate: (0, _index2.subMonths)(NOW, 1)
      }, {
        label: 'Past 3 Months',
        beginDate: (0, _index2.subMonths)(NOW, 3)
      }, {
        label: 'Past 6 Months',
        beginDate: (0, _index2.subMonths)(NOW, 6)
      }, {
        label: 'Past Year',
        beginDate: (0, _index2.subYears)(NOW, 1)
      }, {
        label: 'Past 2 Years',
        beginDate: (0, _index2.subYears)(NOW, 2)
      }];
      return _react.default.createElement(QuickSelectContainer, quickSelectContainerProps, _react.default.createElement(QuickSelectLabel, quickSelectLabelProps, "Quick Select"), _react.default.createElement(QuickSelectButtons, quickSelectButtonsProps, QUICK_SELECT_ACTIONS.map(function (_ref3) {
        var label = _ref3.label,
            beginDate = _ref3.beginDate;
        return _react.default.createElement(_index.Button, {
          key: label,
          tabIndex: 0,
          kind: _index.KIND.tertiary,
          onClick: function onClick() {
            _this.props.onChange({
              date: [beginDate, NOW]
            });
          },
          overrides: {
            BaseButton: {
              style: {
                flexBasis: 0,
                flexGrow: 1,
                marginBottom: '8px',
                paddingLeft: 0,
                paddingRight: 0,
                marginLeft: 0,
                marginRight: 0,
                minWidth: '142px',
                ':nth-of-type(odd)': {
                  marginRight: '8px'
                }
              }
            }
          }
        }, label);
      })));
    });

    _this.state = {
      highlightedDate: _this.props.highlightedDate || _this.getSingleDate(_this.props.value) || new Date(),
      focused: false,
      date: _this.getDateInView()
    };
    return _this;
  }

  _createClass(Calendar, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      if (this.props.autoFocusCalendar) {
        this.focusCalendar();
      }
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(prevProps) {
      if (this.props.highlightedDate && !(0, _index2.isSameDay)(this.props.highlightedDate, prevProps.highlightedDate)) {
        this.setState({
          date: this.props.highlightedDate
        });
      }

      if (this.props.autoFocusCalendar && this.props.autoFocusCalendar !== prevProps.autoFocusCalendar) {
        this.focusCalendar();
      }
    }
  }, {
    key: "getSingleDate",
    value: function getSingleDate(value) {
      // need to check this.props.range but flow would complain
      // at the return value in the else clause
      if (Array.isArray(value)) {
        return value[0] || null;
      }

      return value;
    }
  }, {
    key: "setHighlightedDate",
    value: function setHighlightedDate(date) {
      var value = this.props.value;
      var selected = this.getSingleDate(value);
      var nextState;

      if (selected && (0, _index2.isSameMonth)(selected, date) && (0, _index2.isSameYear)(selected, date)) {
        nextState = {
          highlightedDate: selected
        };
      } else {
        nextState = {
          highlightedDate: date
        };
      }

      this.setState(nextState);
    }
  }, {
    key: "render",
    value: function render() {
      var _this2 = this;

      var _this$props$overrides3 = this.props.overrides,
          overrides = _this$props$overrides3 === void 0 ? {} : _this$props$overrides3;

      var _getOverrides13 = (0, _overrides.getOverrides)(overrides.Root, _styledComponents.StyledRoot),
          _getOverrides14 = _slicedToArray(_getOverrides13, 2),
          Root = _getOverrides14[0],
          rootProps = _getOverrides14[1];

      return _react.default.createElement(Root, _extends({
        "data-baseweb": "calendar",
        $ref: function $ref(root) {
          _this2.root = root;
        },
        role: "application",
        "aria-label": "calendar",
        onKeyDown: this.props.trapTabbing ? this.handleTabbing : null
      }, rootProps), this.renderMonths(), this.renderQuickSelect());
    }
  }]);

  return Calendar;
}(_react.default.Component);

exports.default = Calendar;

_defineProperty(Calendar, "defaultProps", {
  autoFocusCalendar: false,
  excludeDates: null,
  filterDate: null,
  highlightedDate: null,
  includeDates: null,
  range: false,
  locale: null,
  maxDate: null,
  minDate: null,
  monthsShown: 1,
  onDayClick: function onDayClick() {},
  onDayMouseOver: function onDayMouseOver() {},
  onDayMouseLeave: function onDayMouseLeave() {},
  onMonthChange: function onMonthChange() {},
  onYearChange: function onYearChange() {},
  onChange: function onChange() {},
  overrides: {},
  peekNextMonth: false,
  value: null,
  trapTabbing: false
});