UNPKG

@cbinsights/fds

Version:
229 lines (180 loc) • 9.58 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.DATE_FORMAT_MAP = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _react = _interopRequireWildcard(require("react")); var _dayjs = _interopRequireDefault(require("dayjs")); var _customParseFormat = _interopRequireDefault(require("dayjs/plugin/customParseFormat")); var _localizedFormat = _interopRequireDefault(require("dayjs/plugin/localizedFormat")); var _utc = _interopRequireDefault(require("dayjs/plugin/utc")); var _reactDayPicker = _interopRequireDefault(require("react-day-picker")); var _DatePickerIcon = _interopRequireDefault(require("../../icons/react/DatePickerIcon")); var _TextInput = _interopRequireDefault(require("../TextInput")); var _YearAndMonthSelector = _interopRequireDefault(require("./YearAndMonthSelector")); var _NavArrows = _interopRequireDefault(require("./NavArrows")); var _util = require("./util"); var _Popover = _interopRequireDefault(require("../Popover")); var _excluded = ["futureYears", "pastYears", "dateFormat", "popoverProps", "inputRef", "popoverRef", "defaultDate", "onDateChange", "onInputChange", "label", "labelPosition", "labelWidth", "minDate", "maxDate", "hasError", "errorText"]; function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } _dayjs.default.extend(_customParseFormat.default); _dayjs.default.extend(_localizedFormat.default); _dayjs.default.extend(_utc.default); // Is this the correct way to localize dates? No, it is not. // Fortunately, this is display-only. // // The I/O of DateInput is always a JS Date object, which ensures this // hacky formatting is internal to DateInput and will never leak out. var DATE_FORMAT_MAP = { MDY: 'MM/DD/YYYY', DMY: 'DD/MM/YYYY', YMD: 'YYYY/MM/DD' // ISO-8601, the best but least used standard }; exports.DATE_FORMAT_MAP = DATE_FORMAT_MAP; /** * @param {Object} props react props * @returns {ReactElement} */ var DateInput = function DateInput(_ref) { var _ref$futureYears = _ref.futureYears, futureYears = _ref$futureYears === void 0 ? 1 : _ref$futureYears, _ref$pastYears = _ref.pastYears, pastYears = _ref$pastYears === void 0 ? 40 : _ref$pastYears, _ref$dateFormat = _ref.dateFormat, dateFormat = _ref$dateFormat === void 0 ? 'MDY' : _ref$dateFormat, popoverProps = _ref.popoverProps, inputRef = _ref.inputRef, popoverRef = _ref.popoverRef, defaultDateInput = _ref.defaultDate, _ref$onDateChange = _ref.onDateChange, onDateChange = _ref$onDateChange === void 0 ? function () {} : _ref$onDateChange, _ref$onInputChange = _ref.onInputChange, onInputChange = _ref$onInputChange === void 0 ? function () {} : _ref$onInputChange, _ref$label = _ref.label, label = _ref$label === void 0 ? '' : _ref$label, labelPosition = _ref.labelPosition, labelWidth = _ref.labelWidth, minDate = _ref.minDate, maxDate = _ref.maxDate, hasError = _ref.hasError, errorText = _ref.errorText, rest = (0, _objectWithoutProperties2.default)(_ref, _excluded); var defaultDate = defaultDateInput ? (0, _dayjs.default)(defaultDateInput).utc().toDate() : undefined; var _useState = (0, _react.useState)(defaultDate), _useState2 = (0, _slicedToArray2.default)(_useState, 2), selectedDate = _useState2[0], setSelectedDate = _useState2[1]; var _useState3 = (0, _react.useState)(defaultDate || new Date()), _useState4 = (0, _slicedToArray2.default)(_useState3, 2), pickerMonth = _useState4[0], setPickerMonth = _useState4[1]; var _useState5 = (0, _react.useState)(dateFormat), _useState6 = (0, _slicedToArray2.default)(_useState5, 2), prevDateFormat = _useState6[0], setPrevDateFormat = _useState6[1]; var _useState7 = (0, _react.useState)(defaultDate ? (0, _dayjs.default)(defaultDate).format(DATE_FORMAT_MAP[dateFormat]) : ''), _useState8 = (0, _slicedToArray2.default)(_useState7, 2), inputValue = _useState8[0], setInputValue = _useState8[1]; var _useState9 = (0, _react.useState)(false), _useState10 = (0, _slicedToArray2.default)(_useState9, 2), isOpen = _useState10[0], setIsOpen = _useState10[1]; // If the dateFormat prop changes while the input has a user-entered value, // we want the value to change to reflect the new dateFormat if (dateFormat !== prevDateFormat && inputValue.length > 0) { // convert input value back into dayjs obj based on previous date format var parsedInputValue = (0, _dayjs.default)(inputValue, prevDateFormat); // reformat the date in new `dateFormat`; set as new input value setInputValue(parsedInputValue.format(DATE_FORMAT_MAP[dateFormat])); // store dateFormat for next render setPrevDateFormat(dateFormat); } var _getYearRange = (0, _util.getYearRange)(new Date().getFullYear(), pastYears, futureYears, minDate, maxDate, selectedDate), startYear = _getYearRange.startYear, endYear = _getYearRange.endYear; var openPopover = function openPopover() { setIsOpen(true); }; var closePopover = function closePopover() { setIsOpen(false); }; var handleYearMonthChange = function handleYearMonthChange(date) { setPickerMonth(date); }; var handleDaySelect = function handleDaySelect(date, modifiers) { if (modifiers !== null && modifiers !== void 0 && modifiers.disabled) return; setPickerMonth(date); setSelectedDate(date); setInputValue((0, _dayjs.default)(date).format(DATE_FORMAT_MAP[dateFormat])); onDateChange(date); closePopover(); }; var handleInputChange = function handleInputChange(_ref2) { var value = _ref2.target.value; setInputValue(value); onInputChange(value); // when the user types a date that appears valid based on the given format, // we attempt to parse the date string with dayjs. If the date is parsed // as valid, update the selected day. if ((0, _util.isValidUserDate)(value, dateFormat)) { var parsedDate = (0, _dayjs.default)(value, DATE_FORMAT_MAP[dateFormat]); if (parsedDate.isValid()) { handleDaySelect(parsedDate.toDate()); } } // if user backspaces to clear the input, clear out the picker if (value === '') { setSelectedDate(undefined); onDateChange(null); } }; return /*#__PURE__*/_react.default.createElement(_Popover.default, (0, _extends2.default)({ ref: popoverRef, interactionMode: "controlled", isOpen: isOpen, onUserDismiss: closePopover, trigger: /*#__PURE__*/_react.default.createElement(_TextInput.default, (0, _extends2.default)({ "aria-label": "Date Input", ref: inputRef }, rest, { hasError: hasError, errorText: errorText, label: label, labelPosition: labelPosition, labelWidth: labelWidth, type: "text", value: inputValue, onFocus: openPopover, onChange: handleInputChange, placeholder: DATE_FORMAT_MAP[dateFormat], pattern: "[0-9/]*", IconRight: _DatePickerIcon.default })) }, popoverProps), /*#__PURE__*/_react.default.createElement("div", { className: "elevation--2 rounded--all bgColor--white" }, /*#__PURE__*/_react.default.createElement(_reactDayPicker.default, { fromMonth: minDate, toMonth: maxDate, disabledDays: (0, _util.getDisabledDays)(minDate, maxDate), month: pickerMonth, className: "fdsDateInput", onDayClick: handleDaySelect, selectedDays: selectedDate, showOutsideDays: true, navbarElement: /*#__PURE__*/_react.default.createElement(_NavArrows.default, null), captionElement: function captionElement(_ref3) { var date = _ref3.date, localeUtils = _ref3.localeUtils; return /*#__PURE__*/_react.default.createElement(_YearAndMonthSelector.default, { date: date, localeUtils: localeUtils, onChange: handleYearMonthChange, startYear: startYear, endYear: endYear }); } }))); }; var _default = DateInput; exports.default = _default;