/**
 * reactstrap-date-picker v2.0.0
 *
 * https://reactstrap-date-picker.afialapis.com/
 *
 * Copyright (c) Donato Lorenzo <donato@afialapis.com>
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.md file in the root directory of this source tree.
 *
 * @license MIT
 */
/* eslint-disable */ 
import React, { useState, useEffect, useCallback, useRef, forwardRef, useImperativeHandle } from 'react';
import { InputGroup as InputGroup$1, InputGroupText, Input, Button, Popover, PopoverHeader, PopoverBody } from 'reactstrap';

var useCheckProps = (value, defaultValue) => {
  if (value && defaultValue) {
    return 'Conflicting DatePicker properties \'value\' and \'defaultValue\'';
  }
  return undefined;
};

var InputGroup = _ref => {
  var {
    children,
    customInputGroup,
    size,
    inputId
  } = _ref;
  if (customInputGroup != undefined) {
    return /*#__PURE__*/React.cloneElement(customInputGroup, {
      children: children
    });
  }
  return /*#__PURE__*/React.createElement(InputGroup$1, {
    size: size,
    id: inputId,
    className: "rdp-input-group"
  }, children);
};

var InputOverlay = _ref => {
  var {
    oid,
    overlayContainerRef,
    children
  } = _ref;
  return /*#__PURE__*/React.createElement("div", {
    ref: overlayContainerRef,
    id: oid,
    className: "rdp-overlay"
  }, children);
};

var InputHidden = _ref => {
  var {
    inputId,
    name,
    value,
    formattedValue,
    hiddenInputRef
  } = _ref;
  return /*#__PURE__*/React.createElement("input", {
    ref: hiddenInputRef,
    type: "hidden",
    className: "rdp-hidden",
    id: inputId,
    name: name,
    value: value || '',
    "data-formattedvalue": formattedValue
  });
};

var InputClearButton = _ref => {
  var {
    inputValue,
    disabled,
    clearButtonElement,
    onClick: _onClick
  } = _ref;
  return /*#__PURE__*/React.createElement("div", {
    className: "rdp-addon input-group-append"
  }, /*#__PURE__*/React.createElement(InputGroupText, {
    onClick: () => disabled ? null : _onClick(),
    style: {
      opacity: inputValue && !disabled ? 1 : 0.5,
      cursor: inputValue && !disabled ? 'pointer' : 'not-allowed',
      height: "100%"
    }
  }, clearButtonElement));
};

function _defineProperty(e, r, t) {
  return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
    value: t,
    enumerable: true,
    configurable: true,
    writable: true
  }) : e[r] = t, e;
}
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 _objectSpread2(e) {
  for (var r = 1; r < arguments.length; r++) {
    var t = null != arguments[r] ? arguments[r] : {};
    r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
      _defineProperty(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;
}
function _toPrimitive(t, r) {
  if ("object" != typeof t || !t) return t;
  var e = t[Symbol.toPrimitive];
  if (void 0 !== e) {
    var i = e.call(t, r);
    if ("object" != typeof i) return i;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return ("string" === r ? String : Number)(t);
}
function _toPropertyKey(t) {
  var i = _toPrimitive(t, "string");
  return "symbol" == typeof i ? i : i + "";
}

var InputControlInput = _ref => {
  var {
    customControl,
    controlId,
    value,
    required,
    placeholder,
    inputRef,
    disabled,
    className,
    style,
    autoFocus,
    autoComplete,
    valid,
    invalid,
    onInvalid,
    noValidate,
    onKeyDown,
    onFocus,
    onBlur,
    onChange
  } = _ref;
  var validityClassNames = "".concat(invalid === true ? 'is-invalid' : '', " ").concat(valid === true ? 'is-valid' : '');
  if (customControl != undefined) {
    return /*#__PURE__*/React.cloneElement(customControl, {
      id: controlId,
      value: value || '',
      required: required,
      placeholder: placeholder,
      ref: inputRef,
      disabled: disabled,
      className: "rdp-form-control ".concat(className || '', " ").concat(customControl.props.className || '', " ").concat(validityClassNames),
      style: _objectSpread2(_objectSpread2({}, customControl.props.style || {}), style || {}),
      autoComplete: autoComplete,
      onInvalid: onInvalid,
      noValidate: noValidate,
      onKeyDown: onKeyDown,
      onFocus: onFocus,
      onBlur: onBlur,
      onChange: onChange,
      valid: valid,
      invalid: invalid
    });
  }
  return /*#__PURE__*/React.createElement(Input, {
    id: controlId,
    name: controlId,
    value: value || '',
    required: required,
    placeholder: placeholder,
    innerRef: inputRef,
    disabled: disabled,
    type: "text",
    className: "rdp-form-control ".concat(className || '', " ").concat(validityClassNames),
    style: style,
    autoFocus: autoFocus,
    autoComplete: autoComplete,
    onInvalid: onInvalid,
    noValidate: noValidate,
    onKeyDown: onKeyDown,
    onFocus: onFocus,
    onBlur: onBlur,
    onChange: onChange,
    valid: valid,
    invalid: invalid
  });
};

var setTimeToNoon = date => {
  if (!date) {
    return null;
  }
  date.setHours(12 - date.getTimezoneOffset() / 60);
  date.setMinutes(0);
  date.setSeconds(0);
  date.setMilliseconds(0);
  return date;
};

var getDateFromIsoString = isoString => isoString ? setTimeToNoon(new Date(isoString)) : null;

var getIsoStringFromDate = date => date ? setTimeToNoon(date).toISOString() : null;

var _makeInputValueString = (date, separator, dateFormat) => {
  var month = date.getMonth() + 1;
  var day = date.getDate();
  if (dateFormat.match(/MM.DD.YYYY/)) {
    return (month > 9 ? month : "0".concat(month)) + separator + (day > 9 ? day : "0".concat(day)) + separator + date.getFullYear();
  } else if (dateFormat.match(/DD.MM.YYYY/)) {
    return (day > 9 ? day : "0".concat(day)) + separator + (month > 9 ? month : "0".concat(month)) + separator + date.getFullYear();
  } else {
    return date.getFullYear() + separator + (month > 9 ? month : "0".concat(month)) + separator + (day > 9 ? day : "0".concat(day));
  }
};
var useInputValues = (controlInputRef, value, defaultValue, minDate, maxDate, dateFormat, onClear, onChange) => {
  var [separator, setSeparator] = useState(dateFormat.match(/[^A-Z]/)[0]);
  var [innerValue, setInnerValue] = useState(null);
  var [inputValue, setInputValue] = useState(null);
  var [displayDate, setDisplayDate] = useState(null);
  var [selectedDate, setSelectedDate] = useState(null);

  // handle props changes
  useEffect(() => {
    setSeparator(dateFormat.match(/[^A-Z]/)[0]);
  }, [dateFormat]);

  // handle input values
  useEffect(() => {
    var isoString = value || defaultValue;
    var minDate = getDateFromIsoString(minDate);
    var maxDate = getDateFromIsoString(maxDate);
    var nSelectedDate = getDateFromIsoString(isoString);
    var nInnerValue = getIsoStringFromDate(nSelectedDate);
    var nInputValue = isoString ? _makeInputValueString(nSelectedDate, separator, dateFormat) : null;
    var nDisplayDate;
    if (nSelectedDate) {
      //nDisplayDate = new Date(nSelectedDate)
      nDisplayDate = nSelectedDate;
    } else {
      var today = getDateFromIsoString(new Date().toISOString());
      if (minDate && Date.parse(minDate) >= Date.parse(today)) {
        nDisplayDate = minDate;
      } else if (maxDate && Date.parse(maxDate) <= Date.parse(today)) {
        nDisplayDate = maxDate;
      } else {
        nDisplayDate = today;
      }
    }
    setInnerValue(nInnerValue);
    setInputValue(nInputValue);
    setSelectedDate(nSelectedDate);
    setDisplayDate(nDisplayDate);
  }, [value, defaultValue, minDate, maxDate, separator, dateFormat]);

  //
  var handleClear = /*useCallback(*/() => {
    if (onClear) {
      onClear();
    } else {
      setInnerValue(null);
      setInputValue(null);
      setSelectedDate(null);
      setDisplayDate(null);
      if (onChange) {
        onChange(null, null);
      }
    }
  }; /*, [onClear, onChange])*/

  var handleBadInput = /*useCallback(*/function handleBadInput(originalValue) {
    var tail = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
    var parts = originalValue.replace(new RegExp("[^0-9".concat(separator, "]")), '').split(separator);
    if (dateFormat.match(/MM.DD.YYYY/) || dateFormat.match(/DD.MM.YYYY/)) {
      if (parts[0] && parts[0].length > 2) {
        parts[1] = parts[0].slice(2) + (parts[1] || '');
        parts[0] = parts[0].slice(0, 2);
      }
      if (parts[1] && parts[1].length > 2) {
        parts[2] = parts[1].slice(2) + (parts[2] || '');
        parts[1] = parts[1].slice(0, 2);
      }
      if (parts[2]) {
        parts[2] = parts[2].slice(0, 4);
        if (tail) {
          if (parts[2].length < 4) {
            parts[2] = parts[2].padEnd(4, '0');
          }
        }
      }
    } else {
      if (parts[0] && parts[0].length > 4) {
        parts[1] = parts[0].slice(4) + (parts[1] || '');
        parts[0] = parts[0].slice(0, 4);
      }
      if (parts[1] && parts[1].length > 2) {
        parts[2] = parts[1].slice(2) + (parts[2] || '');
        parts[1] = parts[1].slice(0, 2);
      }
      if (parts[2]) {
        parts[2] = parts[2].slice(0, 2);
      }
    }
    var nInputValue = parts.join(separator);
    setInputValue(nInputValue);
  }; /*, [dateFormat, separator])*/

  var handleBadInputOnBlur = () => {
    var _controlInputRef$curr;
    var originalValue = (controlInputRef === null || controlInputRef === void 0 || (_controlInputRef$curr = controlInputRef.current) === null || _controlInputRef$curr === void 0 ? void 0 : _controlInputRef$curr.value) || '';
    if (originalValue) {
      handleBadInput(originalValue, true);
    }
  };
  var handleInputChange = /*useCallback(*/() => {
    var _controlInputRef$curr2;
    var originalValue = (controlInputRef === null || controlInputRef === void 0 || (_controlInputRef$curr2 = controlInputRef.current) === null || _controlInputRef$curr2 === void 0 ? void 0 : _controlInputRef$curr2.value) || '';
    var nInputValue = originalValue.replace(/(-|\/\/)/g, separator).slice(0, 10);
    if (!nInputValue) {
      handleClear();
      return;
    }
    var month, day, year;
    if (dateFormat.match(/MM.DD.YYYY/)) {
      if (!nInputValue.match(/[0-1][0-9].[0-3][0-9].[1-2][0-9][0-9][0-9]/)) {
        return handleBadInput(originalValue);
      }
      month = nInputValue.slice(0, 2).replace(/[^0-9]/g, '');
      day = nInputValue.slice(3, 5).replace(/[^0-9]/g, '');
      year = nInputValue.slice(6, 10).replace(/[^0-9]/g, '');
    } else if (dateFormat.match(/DD.MM.YYYY/)) {
      if (!nInputValue.match(/[0-3][0-9].[0-1][0-9].[1-2][0-9][0-9][0-9]/)) {
        return handleBadInput(originalValue);
      }
      day = nInputValue.slice(0, 2).replace(/[^0-9]/g, '');
      month = nInputValue.slice(3, 5).replace(/[^0-9]/g, '');
      year = nInputValue.slice(6, 10).replace(/[^0-9]/g, '');
    } else {
      if (!nInputValue.match(/[1-2][0-9][0-9][0-9].[0-1][0-9].[0-3][0-9]/)) {
        return handleBadInput(originalValue);
      }
      year = nInputValue.slice(0, 4).replace(/[^0-9]/g, '');
      month = nInputValue.slice(5, 7).replace(/[^0-9]/g, '');
      day = nInputValue.slice(8, 10).replace(/[^0-9]/g, '');
    }
    var monthInteger = parseInt(month, 10);
    var dayInteger = parseInt(day, 10);
    var yearInteger = parseInt(year, 10);
    if (monthInteger > 12 || dayInteger > 31) {
      return handleBadInput(originalValue);
    }
    var beforeMinDate = minDate && Date.parse(originalValue) < Date.parse(minDate);
    var afterMaxDate = maxDate && Date.parse(originalValue) > Date.parse(maxDate);
    if (beforeMinDate || afterMaxDate) {
      return handleBadInput(originalValue);
    }
    if (!isNaN(monthInteger) && !isNaN(dayInteger) && !isNaN(yearInteger) && monthInteger <= 12 && dayInteger <= 31 && yearInteger > 999) {
      var nSelectedDate = getDateFromIsoString(new Date(yearInteger, monthInteger - 1, dayInteger, 12, 0, 0, 0).toISOString());
      var nInnerValue = getIsoStringFromDate(nSelectedDate);
      setSelectedDate(nSelectedDate);
      setDisplayDate(nSelectedDate);
      setInnerValue(nInnerValue);
      if (onChange) {
        onChange(nInnerValue, nInputValue);
      }
    }
    setInputValue(nInputValue);
  }; /*, [controlInputRef, separator, onChange, minDate, maxDate])*/

  var handleChangeMonth = nDisplayDate => {
    setDisplayDate(nDisplayDate);
  };
  var handleChangeDate = /*useCallback(*/nSelectedDate => {
    var nInnerValue = getIsoStringFromDate(nSelectedDate);
    var nInputValue = _makeInputValueString(nSelectedDate, separator, dateFormat);
    setInputValue(nInputValue);
    setSelectedDate(nSelectedDate);
    setDisplayDate(nSelectedDate);
    setInnerValue(nInnerValue);
    if (onChange) {
      onChange(nInnerValue, nInputValue);
    }
  }; /*, [separator, dateFormat, onChange])*/

  return [innerValue, inputValue, displayDate, selectedDate, handleClear, handleInputChange, handleChangeMonth, handleChangeDate, handleBadInputOnBlur];
};

var getInstanceCount = () => {
  if (typeof window === 'object') {
    if (window._reactstrapDatePickerInstance == undefined) {
      window._reactstrapDatePickerInstance = 0;
    }
    var next = window._reactstrapDatePickerInstance + 1;
    window._reactstrapDatePickerInstance = next;
    return next;
  } else if (typeof process === 'object') {
    if (process._reactstrapDatePickerInstance == undefined) {
      process._reactstrapDatePickerInstance = 0;
    }
    var _next = process._reactstrapDatePickerInstance + 1;
    process._reactstrapDatePickerInstance = _next;
    return _next;
  } else {
    console.error("Reactstrap Date Picker cannot determine environment (it is neither browser's <window> nor Node's <process>).");
    return 1;
  }
};

var _getIdSuffix = (id, name) => {
  // Try <id> or <name> props to determine elements' id suffix
  if (id != undefined && id != '') return id;
  if (name != undefined && name != '') return name;
  // If none was passed, use global vars
  var iCount = getInstanceCount();
  return iCount.toString();
};
var _getInputIds = (id, name, customControl) => {
  var _customControl$props;
  var idSuffix = _getIdSuffix(id, name);
  var group = "rdp-input-group-".concat(idSuffix);
  var hidden = id != undefined ? id : "rdp-hidden-".concat(idSuffix);
  var control = "rdp-form-control-".concat(idSuffix);
  if (customControl != undefined && customControl !== null && customControl !== void 0 && (_customControl$props = customControl.props) !== null && _customControl$props !== void 0 && _customControl$props.id) {
    control = customControl.props.id;
  }
  var overlay = "rdp-overlay-".concat(idSuffix);
  return [group, hidden, control, overlay];
};
var useInputIds = (id, name, customControl) => {
  var [inputIds, setInputIds] = useState(_getInputIds(id, name, customControl));
  useEffect(() => {
    setInputIds(_getInputIds(id, name, customControl));
  }, [id, name, customControl]);
  return inputIds;
};

var _getFixedDayLabels = (dayLabels, weekStartsOn) => {
  if (weekStartsOn > 1) {
    return dayLabels.slice(weekStartsOn).concat(dayLabels.slice(0, weekStartsOn));
  }
  if (weekStartsOn === 1) {
    return dayLabels.slice(1).concat(dayLabels.slice(0, 1));
  }
  return dayLabels;
};
var useFixedDayLabels = (dayLabels, weekStartsOn) => {
  var [fixedDayLabels, setFixedDayLabels] = useState(_getFixedDayLabels(dayLabels, weekStartsOn));
  useEffect(() => {
    setFixedDayLabels(_getFixedDayLabels(dayLabels, weekStartsOn));
  }, [dayLabels, weekStartsOn]);
  return fixedDayLabels;
};

var compareMonths = (a, b) => {
  try {
    var da = new Date(a);
    var db = new Date(b);
    var sameYear = da.getFullYear() == db.getFullYear();
    var sameMonth = da.getMonth() == db.getMonth();
    return sameMonth && sameYear;
  } catch (e) {
    console.error(e);
    return true;
  }
};

var _getYearList = (minDate, maxDate) => {
  var minYear = minDate ? new Date(minDate).getFullYear() : 1970;
  var maxYear = maxDate ? new Date(maxDate).getFullYear() : 2045;
  var yList = [];
  for (var y = minYear; y <= maxYear; y++) {
    yList.push(y);
  }
  return yList;
};
var PickMonthDefault = _ref => {
  var {
    displayDate,
    minDate,
    maxDate,
    monthLabels,
    onChangeMonth,
    onChangeYear
  } = _ref;
  var [month, setMonth] = useState(new Date(displayDate).getMonth());
  var [year, setYear] = useState(new Date(displayDate).getFullYear());
  var [yearList, setYearList] = useState(_getYearList(minDate, maxDate));
  useEffect(() => {
    setMonth(new Date(displayDate).getMonth());
    setYear(new Date(displayDate).getFullYear());
  }, [displayDate]);
  useEffect(() => {
    setYearList(_getYearList(minDate, maxDate));
  }, [minDate, maxDate]);
  var handleChangeMonth = ev => {
    var m = ev.target.value;
    setMonth(m);
    onChangeMonth(m);
  };
  var handleChangeYear = ev => {
    var y = ev.target.value;
    setYear(y);
    onChangeYear(y);
  };
  return /*#__PURE__*/React.createElement("div", {
    className: "rdp-header-pick-month-default",
    style: {
      display: 'flex',
      flexFlow: 'row',
      flexWrap: 'nowrap'
    }
  }, /*#__PURE__*/React.createElement("div", {
    className: "rdp-header-pick-month-default-month",
    style: {
      flex: '2 1 auto'
    }
  }, /*#__PURE__*/React.createElement(Input, {
    type: "select",
    name: "rdp-header-pick-month-default-month",
    style: {
      lineHeight: "1.5",
      fontSize: "0.875rem",
      padding: "0.2rem"
    },
    value: month,
    onChange: handleChangeMonth
  }, monthLabels.map((lmonth, lidx) => {
    return /*#__PURE__*/React.createElement("option", {
      key: "month_".concat(lidx),
      value: lidx
    }, lmonth);
  }))), /*#__PURE__*/React.createElement("div", {
    className: "rdp-header-pick-month-default-year",
    style: {
      flex: '1 1 67px'
    }
  }, /*#__PURE__*/React.createElement(Input, {
    type: "select",
    name: "rdp-header-pick-month-default-year",
    style: {
      lineHeight: "1.5",
      fontSize: "0.875rem",
      padding: "0.2rem"
    },
    value: year,
    onChange: handleChangeYear
  }, yearList.map(lyear => {
    return /*#__PURE__*/React.createElement("option", {
      key: "year".concat(lyear),
      value: lyear
    }, lyear);
  }))));
};

function CalendarHeader(_ref) {
  var {
    previousButtonElement,
    nextButtonElement,
    pickMonthElement,
    displayDate,
    minDate,
    maxDate,
    onChange,
    monthLabels
  } = _ref;
  var [displayingMinMonth, setDisplayingMinMonth] = useState(false);
  var [displayingMaxMonth, setDisplayingMaxMonth] = useState(false);
  var [title, setTitle] = useState('');
  var PickMonthElement = pickMonthElement;
  useEffect(() => {
    if (displayDate == undefined) {
      return;
    }
    if (!minDate) {
      setDisplayingMinMonth(false);
    } else {
      setDisplayingMinMonth(compareMonths(displayDate, minDate));
    }
    if (!maxDate) {
      setDisplayingMaxMonth(false);
    } else {
      setDisplayingMaxMonth(compareMonths(displayDate, maxDate));
    }
    try {
      if (monthLabels) {
        setTitle("".concat(monthLabels[displayDate.getMonth()], " ").concat(displayDate.getFullYear()));
      }
    } catch (e) {
      console.error(e);
    }
  }, [displayDate, minDate, maxDate, monthLabels]);
  var handleChangeMonthIncr = inc => {
    var newDisplayDate = new Date(displayDate);
    newDisplayDate.setMonth(newDisplayDate.getMonth() + inc, 1);
    onChange(newDisplayDate);
  };
  var handleChangeMonth = m => {
    var newDisplayDate = new Date(displayDate);
    newDisplayDate.setMonth(m);
    onChange(newDisplayDate);
  };
  var handleChangeYear = y => {
    var newDisplayDate = new Date(displayDate);
    newDisplayDate.setFullYear(y);
    onChange(newDisplayDate);
  };
  return /*#__PURE__*/React.createElement("div", {
    className: "rdp-header text-center",
    style: {
      display: 'flex',
      flexFlow: 'row',
      flexWrap: 'nowrap'
    }
  }, /*#__PURE__*/React.createElement("div", {
    className: "text-muted rdp-header-previous-wrapper",
    onClick: () => handleChangeMonthIncr(-1),
    style: {
      cursor: 'pointer',
      userSelect: 'none',
      flexBasis: '1.25em',
      alignSelf: 'center'
    }
  }, displayingMinMonth ? null : previousButtonElement), /*#__PURE__*/React.createElement("div", {
    className: "rdp-header-pick-month-wrapper",
    style: {
      flex: '1 1 auto'
    }
  }, PickMonthElement == null || PickMonthElement === 'none' ? /*#__PURE__*/React.createElement("div", null, title) : PickMonthElement === 'default' ? /*#__PURE__*/React.createElement(PickMonthDefault, {
    displayDate: displayDate,
    monthLabels: monthLabels,
    minDate: minDate,
    maxDate: maxDate,
    onChangeMonth: m => handleChangeMonth(m),
    onChangeYear: y => handleChangeYear(y)
  }) : /*#__PURE__*/React.createElement(PickMonthElement, {
    displayDate: displayDate,
    minDate: minDate,
    maxDate: maxDate,
    onChangeMonth: m => handleChangeMonth(m),
    onChangeYear: y => handleChangeYear(y)
  })), /*#__PURE__*/React.createElement("div", {
    className: "text-muted rdp-header-next-wrapper",
    onClick: () => handleChangeMonthIncr(1),
    style: {
      cursor: 'pointer',
      userSelect: 'none',
      flexBasis: '1.25em',
      alignSelf: 'center'
    }
  }, displayingMaxMonth ? null : nextButtonElement));
}

var CalendarSubHeader = _ref => {
  var {
    dayLabels,
    showWeeks,
    cellPadding
  } = _ref;
  return /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, showWeeks ? /*#__PURE__*/React.createElement("td", {
    className: "text-muted current-week",
    style: {
      padding: cellPadding
    }
  }) : null, dayLabels.map((label, index) => /*#__PURE__*/React.createElement("td", {
    key: index,
    className: "text-muted",
    style: {
      padding: cellPadding
    }
  }, /*#__PURE__*/React.createElement("small", null, label)))));
};

var CalendarDayOutOfMonth = () => /*#__PURE__*/React.createElement("td", null);

var CAL_DAY_CLASSNAME_BY_MODE = {
  'normal': '',
  'muted': 'text-muted',
  'selected': 'bg-primary',
  'current': 'text-primary'
};
var CalendarDayInMonth = _ref => {
  var {
    day,
    mode,
    onDayClick,
    cellPadding,
    roundedCorners
  } = _ref;
  var handleClick = ev => {
    if (mode != 'muted') {
      onDayClick(ev);
    }
  };
  return /*#__PURE__*/React.createElement("td", {
    "data-day": day,
    onClick: handleClick,
    style: {
      cursor: mode == 'muted' ? 'default' : 'pointer',
      padding: cellPadding,
      borderRadius: roundedCorners ? '5px' : '0px'
    },
    className: CAL_DAY_CLASSNAME_BY_MODE[mode]
  }, day);
};

var CalendarWeekNum = _ref => {
  var {
    weekNum,
    cellPadding
  } = _ref;
  return /*#__PURE__*/React.createElement("td", {
    style: {
      padding: cellPadding,
      fontSize: '0.8em',
      color: 'darkgrey'
    },
    className: "text-muted"
  }, weekNum);
};

var CalendarBody = _ref => {
  var {
    calendarDays,
    showWeeks,
    onDayClick,
    cellPadding,
    roundedCorners
  } = _ref;
  if (!calendarDays) {
    return /*#__PURE__*/React.createElement("tbody", null);
  }
  return /*#__PURE__*/React.createElement("tbody", null, calendarDays.map((week, weekIndex) => /*#__PURE__*/React.createElement("tr", {
    key: "rdp_calendar_week_".concat(weekIndex)
  }, showWeeks ? /*#__PURE__*/React.createElement(CalendarWeekNum, {
    key: "rdp_calendar_week_".concat(weekIndex, "_weeknum"),
    weekNum: week.weekNum,
    cellPadding: cellPadding
  }) : null, week.weekDays.map((weekDay, weekDayIndex) => weekDay.inMonth ? /*#__PURE__*/React.createElement(CalendarDayInMonth, {
    key: "rdp_calendar_week_".concat(weekIndex, "_day_").concat(weekDayIndex),
    day: weekDay.day,
    mode: weekDay.mode,
    onDayClick: onDayClick,
    cellPadding: cellPadding,
    roundedCorners: roundedCorners
  }) : /*#__PURE__*/React.createElement(CalendarDayOutOfMonth, {
    key: "rdp_calendar_week_".concat(weekIndex, "_day_").concat(weekDayIndex)
  })))));
};

var CalendarFooter = _ref => {
  var {
    dayLabels,
    showWeeks,
    handleTodayClick,
    showTodayButton,
    todayButtonLabel
  } = _ref;
  if (!showTodayButton) {
    return null;
  }
  return /*#__PURE__*/React.createElement("tfoot", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
    colSpan: dayLabels.length + (showWeeks ? 1 : 0),
    style: {
      paddingTop: '9px'
    }
  }, /*#__PURE__*/React.createElement(Button, {
    block: true,
    size: "sm",
    className: "u-today-button",
    onClick: () => handleTodayClick()
  }, todayButtonLabel))));
};

var DAYS_BY_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

/**
  groupByWeeks: {
   year,
   month,
   weeks: [
      {weekNum: N,
      wekDays: [
        {inMonth: true, day: N, mode: ''}
        or
        {inMonth: false}
        ]
      },...
      ]
  }
 */

function _groupByWeeks(year, month, weekStartsOn) {
  if (year == undefined || month == undefined) {
    return undefined;
  }
  var firstDay = new Date(year, month, 1);
  var startingDay = weekStartsOn > 1 ? firstDay.getDay() - weekStartsOn + 7 : weekStartsOn === 1 ? firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1 : firstDay.getDay();
  var monthLength = DAYS_BY_MONTH[month];
  if (month == 1) {
    if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
      monthLength = 29;
    }
  }
  var isInMonth = (monthDay, weekIndex, weekDay) => {
    if (monthDay <= monthLength && (weekIndex > 0 || weekDay >= startingDay)) {
      return true;
    }
    return false;
  };
  var getWeekNumber = monthDay => {
    var date = new Date(year, month, monthDay - 1, 12, 0, 0, 0);
    var target = new Date(date.valueOf());
    var dayNr = (date.getDay() + 6) % 7;
    target.setDate(target.getDate() - dayNr + 3);
    var firstThursday = target.valueOf();
    target.setMonth(0, 1);
    if (target.getDay() !== 4) {
      target.setMonth(0, 1 + (4 - target.getDay() + 7) % 7);
    }
    return 1 + Math.ceil((firstThursday - target) / 604800000);
  };
  var allWeeks = [];
  var monthDay = 1;
  for (var weekIndex = 0; weekIndex < 9; weekIndex++) {
    var weekDays = [];
    for (var weekDay = 0; weekDay <= 6; weekDay++) {
      if (isInMonth(monthDay, weekIndex, weekDay)) {
        weekDays.push({
          inMonth: true,
          day: monthDay
        });
        monthDay += 1;
      } else {
        weekDays.push({
          inMonth: false
        });
      }
    }
    var weekNum = getWeekNumber(monthDay);
    allWeeks.push({
      weekDays,
      weekNum
    });
    if (monthDay > monthLength) {
      break;
    }
  }
  return {
    year,
    month,
    weeks: allWeeks
  };
}

/**
  calendarDays: [
  {weekNum: N,
   wekDays: [
     {inMonth: true, day: N, mode: ''}
     or
     {inMonth: false}
    ]
  },...
  ]
 */

function _makeCalendarDays(groupByWeeks, selectedDate, minDate, maxDate) {
  if (groupByWeeks == undefined) {
    return [];
  }
  var getDayMode = day => {
    var date = setTimeToNoon(new Date(groupByWeeks.year, groupByWeeks.month, day, 12, 0, 0, 0)).toISOString();
    var beforeMinDate = minDate != undefined ? Date.parse(date) < Date.parse(setTimeToNoon(new Date(minDate))) : false;
    var afterMaxDate = maxDate != undefined ? Date.parse(date) > Date.parse(setTimeToNoon(new Date(maxDate))) : false;
    var currentDate = setTimeToNoon(new Date());
    var nSelectedDate = setTimeToNoon(new Date(selectedDate));
    if (beforeMinDate || afterMaxDate) {
      return 'muted';
    } else if (Date.parse(date) === Date.parse(nSelectedDate)) {
      return 'selected';
    } else if (Date.parse(date) === Date.parse(currentDate)) {
      return 'current';
    } else {
      return 'normal';
    }
  };
  var calendarDays = [];
  groupByWeeks.weeks.map(week => {
    var weekNum = week.weekNum;
    var weekDays = week.weekDays.map(weekDay => {
      return _objectSpread2(_objectSpread2({}, weekDay), {}, {
        mode: weekDay.inMonth ? getDayMode(weekDay.day) : undefined
      });
    });
    calendarDays.push({
      weekNum,
      weekDays
    });
  });
  return calendarDays;
}
function useCalendarDays(displayDate, selectedDate, minDate, maxDate, weekStartsOn) {
  var [year, setYear] = useState(undefined);
  var [month, setMonth] = useState(undefined);
  var [groupByWeeks, setGroupByWeeks] = useState(undefined);
  var [calendarDays, setCalendarDays] = useState([]);
  useEffect(() => {
    if (displayDate) {
      setYear(displayDate.getFullYear());
      setMonth(displayDate.getMonth());
    }
  }, [displayDate]);
  useEffect(() => {
    setGroupByWeeks(_groupByWeeks(year, month, weekStartsOn));
  }, [year, month, weekStartsOn]);
  useEffect(() => {
    setCalendarDays(_makeCalendarDays(groupByWeeks, selectedDate, minDate, maxDate));
  }, [groupByWeeks, selectedDate, minDate, maxDate]);
  return calendarDays;
}

var Calendar = _ref => {
  var {
    popoverRef,
    selectedDate,
    displayDate,
    minDate,
    maxDate,
    onChange,
    dayLabels,
    cellPadding,
    weekStartsOn,
    showTodayButton,
    todayButtonLabel,
    roundedCorners,
    showWeeks,
    monthLabels,
    previousButtonElement,
    nextButtonElement,
    pickMonthElement,
    placement,
    open,
    container,
    target,
    onChangeMonth
  } = _ref;
  var calendarDays = useCalendarDays(displayDate, selectedDate, minDate, maxDate, weekStartsOn);
  var handleDayClick = e => {
    var day = e.currentTarget.getAttribute('data-day');
    var newSelectedDate = setTimeToNoon(new Date(displayDate));
    newSelectedDate.setDate(day);
    onChange(newSelectedDate);
  };
  var handleTodayClick = () => {
    var newSelectedDate = setTimeToNoon(new Date());
    onChange(newSelectedDate);
  };
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Popover, {
    innerRef: popoverRef,
    className: "rdp-popover ".concat(placement)
    //toggle     = {() => handleHide()}
    ,
    isOpen: open,
    container: container,
    target: target,
    placement: placement
    // delay      = {200} //  does not apply for us (manual triggering)
  }, /*#__PURE__*/React.createElement(PopoverHeader, {
    tag: "div"
  }, /*#__PURE__*/React.createElement(CalendarHeader, {
    previousButtonElement: previousButtonElement,
    nextButtonElement: nextButtonElement,
    pickMonthElement: pickMonthElement,
    displayDate: displayDate,
    minDate: minDate,
    maxDate: maxDate,
    onChange: newDisplayDate => onChangeMonth(newDisplayDate),
    monthLabels: monthLabels
  })), /*#__PURE__*/React.createElement(PopoverBody, null, /*#__PURE__*/React.createElement("table", {
    className: "rdp-calendar text-center"
  }, /*#__PURE__*/React.createElement(CalendarSubHeader, {
    dayLabels: dayLabels,
    showWeeks: showWeeks,
    cellPadding: cellPadding
  }), /*#__PURE__*/React.createElement(CalendarBody, {
    calendarDays: calendarDays,
    showWeeks: showWeeks,
    onDayClick: handleDayClick,
    cellPadding: cellPadding,
    roundedCorners: roundedCorners
  }), /*#__PURE__*/React.createElement(CalendarFooter, {
    dayLabels: dayLabels,
    showWeeks: showWeeks,
    handleTodayClick: handleTodayClick,
    showTodayButton: showTodayButton,
    todayButtonLabel: todayButtonLabel
  })))));
};

// NOTE: do we want to use the controlInput or  the hiddenInput here?
// We were previously using the hidden one, but I see no reasons.
// 'change' events would make sense on the hidden input, but focus
// control seems to be more on the control input.
// Anyway, this is not decided here, but when calling useCustomEvents()

var useCustomEvents = (inputRef, onBlur, onFocus) => {
  var customOnBlur = useCallback(() => {
    if (onBlur) {
      var event = document.createEvent('CustomEvent');
      event.initEvent('Change Date', true, false);
      inputRef.current.dispatchEvent(event);
      onBlur(event);
    }
  }, [inputRef, onBlur]);
  var customOnFocus = useCallback(() => {
    if (onFocus) {
      var event = document.createEvent('CustomEvent');
      event.initEvent('Change Date', true, false);
      inputRef.current.dispatchEvent(event);
      onFocus(event);
    }
  }, [inputRef, onFocus]);
  return [customOnBlur, customOnFocus];
};

var getMaybeFuncValue = value => {
  var tag = Object.prototype.toString.call(value);
  var isFunction = tag === '[object AsyncFunction]' || tag === '[object Function]' || tag === '[object GeneratorFunction]' || tag === '[object Proxy]';
  if (isFunction) {
    return value();
  } else {
    return value;
  }
};

// About autoFocus
// We could handle by our own through ref callbacks
//   (https://blog.maisie.ink/react-ref-autofocus/)
// But let's just use react's autoFocus attribute by now

var useCalendarProps = (calendarPlacement, inputRef, autoFocus, onBlur, onFocus) => {
  var [open, setOpen] = useState(false);
  var [placement, setPlacement] = useState(getMaybeFuncValue(calendarPlacement));
  var hiddenInputRef = useRef();
  var overlayContainerRef = useRef();
  var popoverRef = useRef();
  var controlInputRef = typeof inputRef == 'object' ? inputRef : useRef(inputRef); // eslint-disable-line react-hooks/rules-of-hooks

  // NOTE: do we want to use the controlInput or  the hiddenInput here?
  var [customOnBlur, customOnFocus] = useCustomEvents(/*hiddenInputRef*/controlInputRef, onBlur, onFocus);
  var isOutside = useCallback(event => {
    var outOfCalendar = (popoverRef === null || popoverRef === void 0 ? void 0 : popoverRef.current) == undefined || !(popoverRef !== null && popoverRef !== void 0 && popoverRef.current.contains(event.target));
    var outOfControlInput = (controlInputRef === null || controlInputRef === void 0 ? void 0 : controlInputRef.current) == undefined || !controlInputRef.current.contains(event.target);
    var isOut = outOfCalendar && outOfControlInput;
    return isOut;
  }, [popoverRef, controlInputRef]);

  // Control the click outside
  useEffect(() => {
    function handleClickOutside(event) {
      event.stopPropagation();
      if (open) {
        if (isOutside(event)) {
          setOpen(false);
          customOnBlur();
        }
      }
    }
    document.addEventListener("mousedown", handleClickOutside);
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [open, isOutside, customOnBlur]);

  //
  //  This callback is bound to Calendar.Popover's toggle() method,
  //    but seems it's unneccesary 
  //  Leaving, by now, this testimonial comments
  //
  //  const handleHide = () => {
  //    let inputFocused = false
  //    try {
  //      inputFocused= controlInputRef.current==document.activeElement
  //    } catch(e) {}
  //    
  //    if (inputFocused) {
  //      return
  //    }
  //    setOpen(false)
  //    customOnBlur()
  //  }

  var handleFocus = useCallback(() => {
    var nPlacement = getMaybeFuncValue(calendarPlacement);
    setPlacement(nPlacement);
    setOpen(true);
    customOnFocus();
  }, [calendarPlacement, customOnFocus]);
  var handleBlur = useCallback(event => {
    if (isOutside(event)) {
      setOpen(false);
      customOnBlur();
    }
  }, [isOutside, customOnBlur]);
  return [hiddenInputRef, overlayContainerRef, popoverRef, controlInputRef, open, placement, handleFocus, handleBlur];
};

var _defaultDateFormat = () => {
  var language = typeof window !== 'undefined' && window.navigator ? (window.navigator.userLanguage || window.navigator.language || '').toLowerCase() : '';
  var dateFormat = !language || language === 'en-us' ? 'MM/DD/YYYY' : 'DD/MM/YYYY';
  return dateFormat;
};
var DEFAULT_DAY_LABELS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
var DEFAULT_MONTH_LABELS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
var DatePickerBase = (props, ref) => {
  var {
    // Global props
    value,
    defaultValue,
    id,
    name,
    dateFormat = _defaultDateFormat(),
    minDate,
    maxDate,
    clearButtonElement = '×',
    showClearButton = true,
    // Event props
    onInvalid,
    onChange,
    onClear,
    onBlur,
    onFocus,
    // Input Group props
    size,
    valid,
    invalid,
    customInputGroup,
    // Input props
    autoComplete = 'on',
    autoFocus = false,
    disabled = false,
    noValidate = false,
    placeholder,
    required,
    className,
    style = undefined /* {
                      width: '100%'
                      } */,
    inputRef,
    customControl,
    children,
    // Calendar props
    // target,
    calendarContainer,
    dayLabels = DEFAULT_DAY_LABELS,
    monthLabels = DEFAULT_MONTH_LABELS,
    weekStartsOn,
    showWeeks = false,
    previousButtonElement = '<',
    nextButtonElement = '>',
    pickMonthElement = undefined,
    showTodayButton = false,
    todayButtonLabel = 'Today',
    roundedCorners = false,
    cellPadding = '5px',
    calendarPlacement = 'bottom'
  } = props;
  var propError = useCheckProps(value, defaultValue);
  if (propError != undefined) {
    throw new Error(propError);
  }
  var [hiddenInputRef, overlayContainerRef, popoverRef, controlInputRef, open, placement, handleFocus, handleBlur] = useCalendarProps(calendarPlacement, inputRef, autoFocus, onBlur, onFocus);
  var [innerValue, inputValue, displayDate, selectedDate, handleClear, handleInputChange, handleChangeMonth, handleChangeDate, handleBadInputOnBlur] = useInputValues(controlInputRef, value, defaultValue, minDate, maxDate, dateFormat, onClear, onChange);
  var [groupInputId, hiddenInputId, controlInputId, overlayId] = useInputIds(id, name, customControl);
  useImperativeHandle(ref, () => ({
    getValue: () => {
      return selectedDate ? selectedDate.toISOString() : null;
    },
    getFormattedValue: () => {
      return displayDate ? inputValue : null;
    },
    getNode: () => controlInputRef === null || controlInputRef === void 0 ? void 0 : controlInputRef.current
  })); //, [controlInputRef, displayDate, inputValue, selectedDate]))

  var fixedDayLabels = useFixedDayLabels(dayLabels, weekStartsOn);
  var handleChangeDateAndBlur = nSelectedDate => {
    handleChangeDate(nSelectedDate);
    handleBlur(true);
  };
  return /*#__PURE__*/React.createElement(InputGroup, {
    customInputGroup: customInputGroup,
    size: size,
    inputId: groupInputId
  }, /*#__PURE__*/React.createElement(InputControlInput, {
    controlId: controlInputId,
    customControl: customControl,
    value: inputValue || '',
    required: required,
    placeholder: placeholder || '',
    inputRef: controlInputRef,
    disabled: disabled,
    className: className,
    style: style,
    autoFocus: autoFocus,
    autoComplete: autoComplete,
    onInvalid: onInvalid,
    noValidate: noValidate,
    valid: valid,
    invalid: invalid,
    onFocus: () => handleFocus(),
    onBlur: event => {
      handleBadInputOnBlur();
      handleBlur(event);
    },
    onChange: () => handleInputChange()
  }), /*#__PURE__*/React.createElement(InputOverlay, {
    overlayContainerRef: overlayContainerRef,
    oid: overlayId
  }, overlayContainerRef.current == undefined ? null : /*#__PURE__*/React.createElement(Calendar, {
    popoverRef: popoverRef,
    placement: placement,
    open: open,
    container: calendarContainer || overlayContainerRef,
    target: controlInputId,
    previousButtonElement: previousButtonElement,
    nextButtonElement: nextButtonElement,
    pickMonthElement: pickMonthElement,
    displayDate: displayDate,
    minDate: minDate,
    maxDate: maxDate,
    onChangeMonth: newDisplayDate => handleChangeMonth(newDisplayDate),
    monthLabels: monthLabels,
    cellPadding: cellPadding,
    selectedDate: selectedDate,
    onChange: newSelectedDate => handleChangeDateAndBlur(newSelectedDate),
    dayLabels: fixedDayLabels,
    weekStartsOn: weekStartsOn,
    showTodayButton: showTodayButton,
    todayButtonLabel: todayButtonLabel,
    roundedCorners: roundedCorners,
    showWeeks: showWeeks
  })), /*#__PURE__*/React.createElement(InputHidden, {
    inputId: hiddenInputId,
    name: name,
    value: innerValue || '',
    formattedValue: innerValue ? inputValue : '',
    hiddenInputRef: hiddenInputRef
  }), showClearButton && !customControl ? /*#__PURE__*/React.createElement(InputClearButton, {
    inputValue: inputValue,
    disabled: disabled,
    clearButtonElement: clearButtonElement,
    onClick: () => handleClear()
  }) : null, children);
};
var DatePicker = /*#__PURE__*/forwardRef(DatePickerBase);

export { DatePicker };
//# sourceMappingURL=reactstrap-date-picker.mjs.map
