"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _BaseCalendarSt = require("./BaseCalendar.st.css.js");
var _react = _interopRequireDefault(require("react"));
var _reactDayPicker = _interopRequireDefault(require("react-day-picker"));
var _LocaleUtils = _interopRequireDefault(require("../../common/LocaleUtils/LocaleUtils"));
var _context = require("../../WixStyleReactEnvironmentProvider/context");
var _jsxFileName = "/home/builduser/work/57e038ea7326c1ec/packages/wix-design-system/dist/cjs/Calendar/BaseCalendar/BaseCalendar.tsx";
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
class BaseCalendar extends _react.default.PureComponent {
  constructor() {
    var _this;
    super(...arguments);
    _this = this;
    this.context = void 0;
    this.dayPickerRef = void 0;
    this._renderDay = (day, modifiers) => {
      var {
        dateIndication
      } = this.props;
      var isOutsideDay = !!modifiers[(0, _BaseCalendarSt.cssStates)({
        outside: true
      })];
      var isSelectedDay = !!modifiers[(0, _BaseCalendarSt.cssStates)({
        selected: true
      })];
      var dateIndicationNode = dateIndication && dateIndication({
        date: day,
        isSelected: isSelectedDay
      });
      var shouldHasIndication = dateIndicationNode && !isOutsideDay;
      return /*#__PURE__*/_react.default.createElement("div", {
        className: (0, _BaseCalendarSt.st)(_BaseCalendarSt.classes.dayWrapper, {
          hasIndication: shouldHasIndication
        }),
        "data-date": "".concat(day.getFullYear(), "-").concat(day.getMonth(), "-").concat(day.getDate()),
        "data-outsideday": isOutsideDay,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 100,
          columnNumber: 7
        }
      }, /*#__PURE__*/_react.default.createElement("div", {
        className: _BaseCalendarSt.classes.dayText,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 107,
          columnNumber: 9
        }
      }, day.getDate()), shouldHasIndication ? /*#__PURE__*/_react.default.createElement("div", {
        className: _BaseCalendarSt.classes.dayIndicationContainer,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 109,
          columnNumber: 11
        }
      }, dateIndicationNode) : null);
    };
    this._handleDayClick = function (value) {
      var modifiers = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      var event = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
      _this._preventActionEventDefault(event);
      var propsValue = _this.props.value || {};
      var {
        onChange,
        shouldCloseOnSelect
      } = _this.props;
      var isNotRange = value => {
        if (!('from' in value) || !value.from) {
          return false;
        }
        if (!('to' in value) || !value.to) {
          return false;
        }
        return true;
      };
      var isCompleteRange = value => {
        if (!('from' in value) || !('to' in value)) {
          return false;
        }
        return !!(value.from && value.to);
      };
      if (_this.props.selectionMode === 'range') {
        if (isNotRange(propsValue) || isCompleteRange(propsValue)) {
          onChange({
            from: value
          }, modifiers);
        } else {
          /** Previous `if` checks that both are missing or both are present. At least one should be here */
          var anchor = propsValue.from || propsValue.to;
          var newVal = anchor < value ? {
            from: anchor,
            to: value
          } : {
            from: value,
            to: anchor
          };
          onChange(newVal, modifiers);
          shouldCloseOnSelect && _this.props.onClose(event);
        }
      } else {
        onChange(value, modifiers);
        shouldCloseOnSelect && _this.props.onClose(event);
      }
    };
    this._preventActionEventDefault = function () {
      var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
      if (event && (!('key' in event) || event.key !== 'Escape' && event.key !== 'Tab')) {
        event.preventDefault();
      }
    };
    this._createWeekdayElement = localeUtils => {
      return _ref => {
        var {
          className,
          weekday
        } = _ref;
        var weekdayShort = localeUtils.formatWeekdayShort(weekday);
        var weekdayLong = localeUtils.formatWeekdayLong(weekday);
        return /*#__PURE__*/_react.default.createElement("div", {
          className: className,
          "aria-label": weekdayLong,
          role: "columnheader",
          __self: this,
          __source: {
            fileName: _jsxFileName,
            lineNumber: 208,
            columnNumber: 9
          }
        }, /*#__PURE__*/_react.default.createElement("abbr", {
          "data-hook": "weekday-day",
          __self: this,
          __source: {
            fileName: _jsxFileName,
            lineNumber: 209,
            columnNumber: 11
          }
        }, weekdayShort));
      };
    };
    this._createDayPickerProps = () => {
      var {
        filterDate,
        excludePastDates,
        numOfMonths,
        firstDayOfWeek,
        rtl,
        today,
        onDisplayedViewChange,
        displayedMonth,
        captionElement,
        allowSelectingOutsideDays,
        size
      } = this.props;
      var locale = this._getLocale();
      var value = BaseCalendar.parseValue(this.props.value);
      var localeUtils = (0, _LocaleUtils.default)(locale, firstDayOfWeek);
      var {
        from,
        to
      } = value instanceof Date ? {
        from: undefined,
        to: undefined
      } : value;
      var singleDay = !from && !to && value;
      var firstOfMonth = [new Date(displayedMonth.getFullYear(), displayedMonth.getMonth(), 1), new Date(displayedMonth.getFullYear(), displayedMonth.getMonth() + 1, 1)];
      var lastOfMonth = [new Date(displayedMonth.getFullYear(), displayedMonth.getMonth() + 1, 0), new Date(displayedMonth.getFullYear(), displayedMonth.getMonth() + 2, 0)];
      var selectedDays = this._getSelectedDays(value);
      var weekdayElement = this._createWeekdayElement(localeUtils);
      var modifiers = _objectSpread({
        [(0, _BaseCalendarSt.cssStates)({
          start: true
        })]: from,
        [(0, _BaseCalendarSt.cssStates)({
          end: true
        })]: to,
        [(0, _BaseCalendarSt.cssStates)({
          firstOfMonth: true
        })]: firstOfMonth,
        [(0, _BaseCalendarSt.cssStates)({
          lastOfMonth: true
        })]: lastOfMonth,
        [(0, _BaseCalendarSt.cssStates)({
          singleDay: true
        })]: singleDay
      }, this.props.modifiers);
      if (today) {
        /** parseValue always returns Date if you give it a Date */
        modifiers[(0, _BaseCalendarSt.cssStates)({
          today: true
        })] = BaseCalendar.parseValue(today);
      }

      // We must add the dummy state since ReactDayPicker use it as a selector in their code
      var outsideCssState = allowSelectingOutsideDays ? (0, _BaseCalendarSt.cssStates)({
        dummyOutside: true
      }) : (0, _BaseCalendarSt.cssStates)({
        outside: true
      });
      return {
        disabledDays: [date => !filterDate(new Date(date)), excludePastDates ? {
          before: new Date()
        } : {}],
        initialMonth: displayedMonth,
        initialYear: displayedMonth,
        selectedDays,
        month: displayedMonth,
        year: displayedMonth,
        locale: typeof locale === 'string' ? locale : '',
        fixedWeeks: true,
        onKeyDown: this._handleKeyDown,
        onDayClick: this._handleDayClick,
        // @ts-expect-error Missing props probably aren't used
        localeUtils,
        navbarElement: () => null,
        captionElement,
        // @ts-expect-error Probably a live bug or there's no caption to click
        onCaptionClick: this._preventActionEventDefault,
        onDayKeyDown: this._handleDayKeyDown,
        numberOfMonths: numOfMonths,
        modifiers,
        renderDay: this._renderDay,
        dir: rtl ? 'rtl' : 'ltr',
        tabIndex: 0,
        weekdayElement,
        classNames: {
          /* The classes: 'DayPicker', 'DayPicker-wrapper', 'DayPicker-Month', 'DayPicker-Day', 'disabled'
          are used as selectors for the elements at the drivers and at the e2e tests */

          container: (0, _BaseCalendarSt.st)(_BaseCalendarSt.classes.container, {
            size
          }, 'DayPicker'),
          wrapper: 'DayPicker-wrapper',
          interactionDisabled: 'DayPicker--interactionDisabled',
          months: (0, _BaseCalendarSt.st)(_BaseCalendarSt.classes.months, {
            twoMonths: numOfMonths > 1
          }),
          month: (0, _BaseCalendarSt.st)(_BaseCalendarSt.classes.month, {
            size
          }, 'DayPicker-Month'),
          weekdays: _BaseCalendarSt.classes.weekdays,
          weekdaysRow: _BaseCalendarSt.classes.weekdaysRow,
          weekday: (0, _BaseCalendarSt.st)(_BaseCalendarSt.classes.weekday, {
            size
          }),
          body: (0, _BaseCalendarSt.st)(_BaseCalendarSt.classes.body, {
            size
          }),
          week: _BaseCalendarSt.classes.week,
          weekNumber: 'DayPicker-WeekNumber',
          day: (0, _BaseCalendarSt.st)(_BaseCalendarSt.classes.day, {
            size
          }, 'DayPicker-Day'),
          // default modifiers
          today: (0, _BaseCalendarSt.cssStates)({
            today: !today
          }),
          selected: (0, _BaseCalendarSt.cssStates)({
            selected: true
          }),
          disabled: (0, _BaseCalendarSt.st)('disabled', (0, _BaseCalendarSt.cssStates)({
            disabled: true
          })),
          outside: outsideCssState
        },
        onMonthChange: onDisplayedViewChange
      };
    };
    this._handleKeyDown = event => {
      var {
        onKeyDown
      } = this.props;
      if (onKeyDown) {
        onKeyDown(event);
        return;
      }
      if (event.key === 'Escape') {
        this.props.onClose(event);
      }
    };
    this._toggleFirstDayTabIndex = tabIndex => {
      var firstDay = this._getDayPicker().dayPicker.querySelector(".DayPicker-Day[tabindex=\"".concat(tabIndex, "\"]"));
      if (!firstDay) {
        throw new Error('<BaseCalendar /> No first day found in day picker');
      }
      firstDay.tabIndex = tabIndex === 0 ? -1 : 0;
    };
    this._focusSelectedDay = () => {
      if (this.dayPickerRef) {
        var selectedDay = this.dayPickerRef.dayPicker.querySelector(".".concat((0, _BaseCalendarSt.cssStates)({
          selected: true
        })));
        if (selectedDay) {
          // The 'unfocused' class is used as a selector at the drivers and e2e test
          selectedDay.classList.add((0, _BaseCalendarSt.cssStates)({
            unfocused: true
          }), 'unfocused');
          selectedDay.tabIndex = 0;
          selectedDay.focus();
          this._toggleFirstDayTabIndex(0);
        } else {
          this._toggleFirstDayTabIndex(-1);
        }
      }
    };
    this._handleDayKeyDown = function (_value, _modifiers) {
      var event = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
      _this._preventActionEventDefault(event);
      var unfocusedDay = _this._getDayPicker().dayPicker.querySelector(".".concat((0, _BaseCalendarSt.cssStates)({
        unfocused: true
      })));
      if (unfocusedDay) {
        // The 'unfocused' class is used as a selector at the drivers and e2e test
        unfocusedDay.classList.remove((0, _BaseCalendarSt.cssStates)({
          unfocused: true
        }), 'unfocused');
      }
    };
  }
  _getSelectedDays(value) {
    var {
      from,
      to
    } = !value || value instanceof Date ? {
      from: undefined,
      to: undefined
    } : value;
    if (from && to) {
      return {
        from,
        to
      };
    } else if (from) {
      return {
        after: BaseCalendar.prevDay(from)
      };
    } else if (to) {
      return {
        before: BaseCalendar.nextDay(to)
      };
    } else {
      // Single day OR empty value
      return value;
    }
  }
  _getDayPicker() {
    if (!this.dayPickerRef) {
      throw new Error("<BaseCalendar /> didn't have a day picker set");
    }
    return this.dayPickerRef;
  }
  _getLocale() {
    return this.props.locale || this.context.locale || 'en';
  }
  componentDidMount() {
    this.props.autoFocus && this._focusSelectedDay();
    if (this.dayPickerRef) {
      // @ts-expect-error wrapper is badly declared on DayPicker class
      this.dayPickerRef.wrapper.tabIndex = -1;
    }
  }
  componentDidUpdate(prevProps) {
    if (!prevProps.autoFocus && this.props.autoFocus) {
      this._focusSelectedDay();
    }
  }
  render() {
    var {
      dataHook,
      className,
      size
    } = this.props;
    return /*#__PURE__*/_react.default.createElement("div", {
      "data-hook": dataHook,
      "data-size": size,
      className: (0, _BaseCalendarSt.st)(_BaseCalendarSt.classes.root, className),
      onClick: this._preventActionEventDefault,
      role: "dialog",
      tabIndex: -1,
      __self: this,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 419,
        columnNumber: 7
      }
    }, /*#__PURE__*/_react.default.createElement(_reactDayPicker.default, (0, _extends2.default)({
      ref: _ref2 => {
        this.dayPickerRef = _ref2;
      }
    }, this._createDayPickerProps(), {
      __self: this,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 427,
        columnNumber: 9
      }
    })));
  }
}
exports.default = BaseCalendar;
BaseCalendar.displayName = 'BaseCalendar';
BaseCalendar.defaultProps = {
  className: '',
  filterDate: () => true,
  dateIndication: () => null,
  shouldCloseOnSelect: true,
  onClose: () => {},
  autoFocus: true,
  excludePastDates: false,
  selectionMode: 'day',
  numOfMonths: 1,
  size: 'medium',
  allowSelectingOutsideDays: false
};
/** Return a value in which all string-dates are parsed into Date objects */
BaseCalendar.parseValue = value => {
  if (!value) {
    return new Date();
  }
  if (value instanceof Date) {
    return value;
  } else {
    return {
      from: value.from,
      to: value.to
    };
  }
};
BaseCalendar.nextDay = date => {
  var day = new Date(date);
  day.setDate(day.getDate() + 1);
  return day;
};
BaseCalendar.prevDay = date => {
  var day = new Date(date);
  day.setDate(day.getDate() - 1);
  return day;
};
BaseCalendar.contextType = _context.WixStyleReactEnvironmentContext;
//# sourceMappingURL=BaseCalendar.js.map