UNPKG

@nateradebaugh/react-datetime

Version:

A lightweight but complete datetime picker React.js component

785 lines (773 loc) 34 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@reach/popover'), require('use-onclickoutside'), require('date-fns/format'), require('date-fns/parse'), require('date-fns/isDate'), require('date-fns/toDate'), require('date-fns/isValid'), require('date-fns/startOfDay'), require('clsx'), require('date-fns/getHours'), require('date-fns/addHours'), require('date-fns/addMinutes'), require('date-fns/addSeconds'), require('date-fns/addMilliseconds'), require('date-fns/setHours'), require('date-fns/addDays'), require('date-fns/differenceInDays'), require('date-fns/startOfWeek'), require('date-fns/startOfMonth'), require('date-fns/endOfMonth'), require('date-fns/isSameDay'), require('date-fns/isBefore'), require('date-fns/addMonths'), require('date-fns/getDate'), require('date-fns/addYears'), require('date-fns/isSameMonth'), require('date-fns/setMonth'), require('date-fns/getDaysInMonth'), require('date-fns/setDate'), require('date-fns/getYear'), require('date-fns/setYear'), require('date-fns/getDaysInYear'), require('date-fns/setDayOfYear'), require('date-fns/isSameYear')) : typeof define === 'function' && define.amd ? define(['exports', 'react', '@reach/popover', 'use-onclickoutside', 'date-fns/format', 'date-fns/parse', 'date-fns/isDate', 'date-fns/toDate', 'date-fns/isValid', 'date-fns/startOfDay', 'clsx', 'date-fns/getHours', 'date-fns/addHours', 'date-fns/addMinutes', 'date-fns/addSeconds', 'date-fns/addMilliseconds', 'date-fns/setHours', 'date-fns/addDays', 'date-fns/differenceInDays', 'date-fns/startOfWeek', 'date-fns/startOfMonth', 'date-fns/endOfMonth', 'date-fns/isSameDay', 'date-fns/isBefore', 'date-fns/addMonths', 'date-fns/getDate', 'date-fns/addYears', 'date-fns/isSameMonth', 'date-fns/setMonth', 'date-fns/getDaysInMonth', 'date-fns/setDate', 'date-fns/getYear', 'date-fns/setYear', 'date-fns/getDaysInYear', 'date-fns/setDayOfYear', 'date-fns/isSameYear'], factory) : (global = global || self, factory(global['@nateradebaugh/react-datetime'] = {}, global.React, global.popover, global.useOnClickOutside, global.format, global.rawParse, global.isDate, global.toDate, global.isDateValid, global.startOfDay, global.clsx, global.getHours, global.addHours, global.addMinutes, global.addSeconds, global.addMilliseconds, global.setHours, global.addDays, global.differenceInDays, global.startOfWeek, global.startOfMonth, global.endOfMonth, global.isSameDay, global.isBefore, global.addMonths, global.getDate, global.addYears, global.isSameMonth, global.setMonth, global.getDaysInMonth, global.setDate, global.getYear, global.setYear, global.getDaysInYear, global.setDayOfYear, global.isSameYear)); }(this, (function (exports, React, popover, useOnClickOutside, format, rawParse, isDate, toDate, isDateValid, startOfDay, clsx, getHours, addHours, addMinutes, addSeconds, addMilliseconds, setHours, addDays, differenceInDays, startOfWeek, startOfMonth, endOfMonth, isSameDay, isBefore, addMonths, getDate, addYears, isSameMonth, setMonth, getDaysInMonth, setDate, getYear, setYear, getDaysInYear, setDayOfYear, isSameYear) { 'use strict'; var React__default = 'default' in React ? React['default'] : React; useOnClickOutside = useOnClickOutside && Object.prototype.hasOwnProperty.call(useOnClickOutside, 'default') ? useOnClickOutside['default'] : useOnClickOutside; format = format && Object.prototype.hasOwnProperty.call(format, 'default') ? format['default'] : format; rawParse = rawParse && Object.prototype.hasOwnProperty.call(rawParse, 'default') ? rawParse['default'] : rawParse; isDate = isDate && Object.prototype.hasOwnProperty.call(isDate, 'default') ? isDate['default'] : isDate; toDate = toDate && Object.prototype.hasOwnProperty.call(toDate, 'default') ? toDate['default'] : toDate; isDateValid = isDateValid && Object.prototype.hasOwnProperty.call(isDateValid, 'default') ? isDateValid['default'] : isDateValid; startOfDay = startOfDay && Object.prototype.hasOwnProperty.call(startOfDay, 'default') ? startOfDay['default'] : startOfDay; clsx = clsx && Object.prototype.hasOwnProperty.call(clsx, 'default') ? clsx['default'] : clsx; getHours = getHours && Object.prototype.hasOwnProperty.call(getHours, 'default') ? getHours['default'] : getHours; addHours = addHours && Object.prototype.hasOwnProperty.call(addHours, 'default') ? addHours['default'] : addHours; addMinutes = addMinutes && Object.prototype.hasOwnProperty.call(addMinutes, 'default') ? addMinutes['default'] : addMinutes; addSeconds = addSeconds && Object.prototype.hasOwnProperty.call(addSeconds, 'default') ? addSeconds['default'] : addSeconds; addMilliseconds = addMilliseconds && Object.prototype.hasOwnProperty.call(addMilliseconds, 'default') ? addMilliseconds['default'] : addMilliseconds; setHours = setHours && Object.prototype.hasOwnProperty.call(setHours, 'default') ? setHours['default'] : setHours; addDays = addDays && Object.prototype.hasOwnProperty.call(addDays, 'default') ? addDays['default'] : addDays; differenceInDays = differenceInDays && Object.prototype.hasOwnProperty.call(differenceInDays, 'default') ? differenceInDays['default'] : differenceInDays; startOfWeek = startOfWeek && Object.prototype.hasOwnProperty.call(startOfWeek, 'default') ? startOfWeek['default'] : startOfWeek; startOfMonth = startOfMonth && Object.prototype.hasOwnProperty.call(startOfMonth, 'default') ? startOfMonth['default'] : startOfMonth; endOfMonth = endOfMonth && Object.prototype.hasOwnProperty.call(endOfMonth, 'default') ? endOfMonth['default'] : endOfMonth; isSameDay = isSameDay && Object.prototype.hasOwnProperty.call(isSameDay, 'default') ? isSameDay['default'] : isSameDay; isBefore = isBefore && Object.prototype.hasOwnProperty.call(isBefore, 'default') ? isBefore['default'] : isBefore; addMonths = addMonths && Object.prototype.hasOwnProperty.call(addMonths, 'default') ? addMonths['default'] : addMonths; getDate = getDate && Object.prototype.hasOwnProperty.call(getDate, 'default') ? getDate['default'] : getDate; addYears = addYears && Object.prototype.hasOwnProperty.call(addYears, 'default') ? addYears['default'] : addYears; isSameMonth = isSameMonth && Object.prototype.hasOwnProperty.call(isSameMonth, 'default') ? isSameMonth['default'] : isSameMonth; setMonth = setMonth && Object.prototype.hasOwnProperty.call(setMonth, 'default') ? setMonth['default'] : setMonth; getDaysInMonth = getDaysInMonth && Object.prototype.hasOwnProperty.call(getDaysInMonth, 'default') ? getDaysInMonth['default'] : getDaysInMonth; setDate = setDate && Object.prototype.hasOwnProperty.call(setDate, 'default') ? setDate['default'] : setDate; getYear = getYear && Object.prototype.hasOwnProperty.call(getYear, 'default') ? getYear['default'] : getYear; setYear = setYear && Object.prototype.hasOwnProperty.call(setYear, 'default') ? setYear['default'] : setYear; getDaysInYear = getDaysInYear && Object.prototype.hasOwnProperty.call(getDaysInYear, 'default') ? getDaysInYear['default'] : getDaysInYear; setDayOfYear = setDayOfYear && Object.prototype.hasOwnProperty.call(setDayOfYear, 'default') ? setDayOfYear['default'] : setDayOfYear; isSameYear = isSameYear && Object.prototype.hasOwnProperty.call(isSameYear, 'default') ? isSameYear['default'] : isSameYear; function _extends() { _extends = Object.assign ? Object.assign.bind() : 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 _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var allCounters = ["hours", "minutes", "seconds", "milliseconds"]; var defaultTimeConstraints = { hours: { step: 1 }, minutes: { step: 1 }, seconds: { step: 1 }, milliseconds: { step: 1 } }; var TimePart = function TimePart(props) { var showPrefix = props.showPrefix, onUp = props.onUp, onDown = props.onDown, value = props.value; return value !== null && value !== undefined ? React.createElement(React.Fragment, null, showPrefix && React.createElement("div", { className: "rdtCounterSeparator" }, ":"), React.createElement("div", { className: "rdtCounter" }, React.createElement("span", { className: "rdtBtn", onMouseDown: onUp }, "\u25B2"), React.createElement("div", { className: "rdtCount" }, value), React.createElement("span", { className: "rdtBtn", onMouseDown: onDown }, "\u25BC"))) : null; }; function getStepSize(type, timeConstraints) { var step = defaultTimeConstraints[type].step; var config = timeConstraints ? timeConstraints[type] : undefined; if (config && config.step) { step = config.step; } return step; } var changeLookup = { hours: addHours, minutes: addMinutes, seconds: addSeconds, milliseconds: addMilliseconds }; function change(op, type, timestamp, timeConstraints) { var mult = op === "sub" ? -1 : 1; var step = getStepSize(type, timeConstraints) * mult; return changeLookup[type](timestamp, step); } function getFormatted(type, timestamp, timeFormat, formatOptions) { var fmt = timeFormat; function has(f, val) { return f.indexOf(val) !== -1; } var hasHours = has(fmt.toLowerCase(), FORMATS.SHORT_HOUR); var hasMinutes = has(fmt, FORMATS.SHORT_MINUTE); var hasSeconds = has(fmt, FORMATS.SHORT_SECOND); var hasMilliseconds = has(fmt, FORMATS.SHORT_MILLISECOND); var hasDayPart = has(fmt, FORMATS.AM_PM); var typeFormat = type === "hours" && hasHours ? hasDayPart ? FORMATS.HOUR : FORMATS.MILITARY_HOUR : type === "minutes" && hasMinutes ? FORMATS.MINUTE : type === "seconds" && hasSeconds ? FORMATS.SECOND : type === "milliseconds" && hasMilliseconds ? FORMATS.MILLISECOND : type === "daypart" && hasDayPart ? FORMATS.AM_PM : undefined; if (typeFormat) { return format(timestamp, typeFormat, formatOptions); } return undefined; } function toggleDayPart(timestamp, setSelectedDate) { return function () { var hours = getHours(timestamp); var newHours = hours >= 12 ? hours - 12 : hours + 12; setSelectedDate(setHours(timestamp, newHours)); }; } var timer; var increaseTimer; var _mouseUpListener; function onStartClicking(op, type, props) { return function () { var readonly = props.readonly, origViewTimestamp = props.viewTimestamp, timeConstraints = props.timeConstraints, setViewTimestamp = props.setViewTimestamp, setSelectedDate = props.setSelectedDate; if (!readonly) { var viewTimestamp = change(op, type, origViewTimestamp, timeConstraints); setViewTimestamp(viewTimestamp); timer = setTimeout(function () { increaseTimer = setInterval(function () { viewTimestamp = change(op, type, viewTimestamp, timeConstraints); setViewTimestamp(viewTimestamp); }, 70); }, 500); _mouseUpListener = function mouseUpListener() { clearTimeout(timer); clearInterval(increaseTimer); setSelectedDate(viewTimestamp); document.body.removeEventListener("mouseup", _mouseUpListener); document.body.removeEventListener("touchend", _mouseUpListener); }; document.body.addEventListener("mouseup", _mouseUpListener); document.body.addEventListener("touchend", _mouseUpListener); } }; } function TimeView(props) { var viewTimestamp = props.viewTimestamp, dateFormat = props.dateFormat, setViewMode = props.setViewMode, timeFormat = props.timeFormat, formatOptions = props.formatOptions, setSelectedDate = props.setSelectedDate; var numCounters = 0; return React.createElement("div", { className: "rdtTime", "data-testid": "time-picker" }, React.createElement("table", null, dateFormat ? React.createElement("thead", null, React.createElement("tr", null, React.createElement("th", { className: "rdtSwitch", "data-testid": "time-mode-switcher", colSpan: 4, onClick: function onClick() { return setViewMode("days"); } }, format(viewTimestamp, dateFormat)))) : null, React.createElement("tbody", null, React.createElement("tr", null, React.createElement("td", null, React.createElement("div", { className: "rdtCounters" }, allCounters.map(function (type) { var val = getFormatted(type, viewTimestamp, timeFormat, formatOptions); if (val) { numCounters++; } return React.createElement(TimePart, { key: type, showPrefix: numCounters > 1, onUp: onStartClicking("add", type, props), onDown: onStartClicking("sub", type, props), value: val }); }), React.createElement(TimePart, { onUp: toggleDayPart(viewTimestamp, setSelectedDate), onDown: toggleDayPart(viewTimestamp, setSelectedDate), value: getFormatted("daypart", viewTimestamp, timeFormat, formatOptions) }))))))); } function DaysView(props) { var timeFormat = props.timeFormat, viewDate = props.viewDate, setViewDate = props.setViewDate, selectedDate = props.selectedDate, setSelectedDate = props.setSelectedDate, formatOptions = props.formatOptions, setViewMode = props.setViewMode, isValidDate = props.isValidDate; var weekStart = startOfWeek(viewDate, formatOptions); var prevMonth = addMonths(viewDate, -1); var daysSincePrevMonthLastWeekStart = differenceInDays(startOfWeek(endOfMonth(prevMonth), formatOptions), viewDate); var prevMonthLastWeekStart = addDays(viewDate, daysSincePrevMonthLastWeekStart); return React.createElement("div", { className: "rdtDays", "data-testid": "day-picker" }, React.createElement("table", null, React.createElement("thead", null, React.createElement("tr", null, React.createElement("th", { className: "rdtPrev", onClick: function onClick() { return setViewDate(addMonths(viewDate, -1)); } }, React.createElement("span", null, "\u2039")), React.createElement("th", { className: "rdtSwitch", "data-testid": "day-mode-switcher", onClick: function onClick() { return setViewMode("months"); }, colSpan: 5 }, format(viewDate, FORMATS.FULL_MONTH_NAME + " " + FORMATS.YEAR, formatOptions)), React.createElement("th", { className: "rdtNext", onClick: function onClick() { return setViewDate(addMonths(viewDate, 1)); } }, React.createElement("span", null, "\u203A"))), React.createElement("tr", null, [0, 1, 2, 3, 4, 5, 6].map(function (colNum) { return React.createElement("th", { key: colNum, className: "dow" }, format(addDays(weekStart, colNum), FORMATS.SHORT_DAY_OF_WEEK, formatOptions)); }))), React.createElement("tbody", null, [0, 1, 2, 3, 4, 5].map(function (rowNum) { // Use 7 columns per row var rowStartDay = rowNum * 7; return React.createElement("tr", { key: format(addDays(prevMonthLastWeekStart, rowStartDay), FORMATS.FULL_TIMESTAMP) }, [0, 1, 2, 3, 4, 5, 6].map(function (d) { var i = d + rowStartDay; var workingDate = addDays(prevMonthLastWeekStart, i); var isDisabled = typeof isValidDate === "function" && !isValidDate(workingDate); var isActive = selectedDate && isSameDay(workingDate, selectedDate); return React.createElement("td", { key: getDate(workingDate), className: clsx(["rdtDay", { rdtOld: isBefore(workingDate, startOfMonth(viewDate)), rdtNew: isBefore(endOfMonth(viewDate), workingDate), rdtActive: isActive, rdtToday: isSameDay(workingDate, new Date()), rdtDisabled: isDisabled }]), onClick: function onClick() { if (!isDisabled) { setSelectedDate(workingDate); } } }, format(workingDate, FORMATS.SHORT_DAY, formatOptions)); })); })), timeFormat ? React.createElement("tfoot", null, React.createElement("tr", null, React.createElement("td", { onClick: function onClick() { return setViewMode("time"); }, colSpan: 7, className: "rdtTimeToggle", "data-testid": "day-to-time-mode-switcher" }, format(viewDate, timeFormat, formatOptions)))) : null)); } function MonthsView(props) { var viewDate = props.viewDate, setViewDate = props.setViewDate, selectedDate = props.selectedDate, setSelectedDate = props.setSelectedDate, formatOptions = props.formatOptions, setViewMode = props.setViewMode, isValidDate = props.isValidDate; return React.createElement("div", { className: "rdtMonths", "data-testid": "month-picker" }, React.createElement("table", null, React.createElement("thead", null, React.createElement("tr", null, React.createElement("th", { className: "rdtPrev", onClick: function onClick() { return setViewDate(addYears(viewDate, -1)); } }, React.createElement("span", null, "\u2039")), React.createElement("th", { className: "rdtSwitch", "data-testid": "month-mode-switcher", onClick: function onClick() { return setViewMode("years"); }, colSpan: 2 }, format(viewDate, FORMATS.YEAR, formatOptions)), React.createElement("th", { className: "rdtNext", onClick: function onClick() { return setViewDate(addYears(viewDate, 1)); } }, React.createElement("span", null, "\u203A"))))), React.createElement("table", null, React.createElement("tbody", null, [0, 1, 2].map(function (rowNum) { // Use 4 columns per row var rowStartMonth = rowNum * 4; return React.createElement("tr", { key: rowStartMonth }, [0, 1, 2, 3].map(function (m) { var month = m + rowStartMonth; var currentMonth = setMonth(viewDate, month); var daysInMonths = Array.from({ length: getDaysInMonth(currentMonth) }, function (e, i) { return setDate(currentMonth, i + 1); }); var isDisabled = daysInMonths.every(function (d) { return typeof isValidDate === "function" && !isValidDate(d); }); var monthDate = setMonth(new Date(), month); var isActive = selectedDate && isSameMonth(selectedDate, currentMonth); return React.createElement("td", { key: month, className: clsx(["rdtMonth", { rdtDisabled: isDisabled, rdtActive: isActive }]), onClick: function onClick() { if (!isDisabled) { setSelectedDate(setMonth(viewDate, month)); } } }, format(monthDate, FORMATS.SHORT_MONTH_NAME, formatOptions)); })); })))); } function YearsView(props) { var viewDate = props.viewDate, setViewDate = props.setViewDate, selectedDate = props.selectedDate, setSelectedDate = props.setSelectedDate, formatOptions = props.formatOptions, setViewMode = props.setViewMode, isValidDate = props.isValidDate; var startYear = Math.floor(getYear(viewDate) / 10) * 10; return React.createElement("div", { className: "rdtYears", "data-testid": "year-picker" }, React.createElement("table", null, React.createElement("thead", null, React.createElement("tr", null, React.createElement("th", { className: "rdtPrev", onClick: function onClick() { return setViewDate(addYears(viewDate, -10)); } }, React.createElement("span", null, "\u2039")), React.createElement("th", { className: "rdtSwitch", "data-testid": "year-mode-switcher", onClick: function onClick() { return setViewMode("years"); }, colSpan: 2 }, startYear, "-", startYear + 9), React.createElement("th", { className: "rdtNext", onClick: function onClick() { return setViewDate(addYears(viewDate, 10)); } }, React.createElement("span", null, "\u203A"))))), React.createElement("table", null, React.createElement("tbody", null, [0, 1, 2].map(function (rowNum) { // Use 4 columns per row var rowStartYear = startYear - 1 + rowNum * 4; return React.createElement("tr", { key: rowStartYear }, [0, 1, 2, 3].map(function (y) { var year = y + rowStartYear; var currentYear = setYear(viewDate, year); var daysInYear = Array.from({ length: getDaysInYear(viewDate) }, function (e, i) { return setDayOfYear(currentYear, i + 1); }); var isDisabled = daysInYear.every(function (d) { return typeof isValidDate === "function" && !isValidDate(d); }); var isActive = selectedDate && isSameYear(selectedDate, currentYear); return React.createElement("td", { key: year, className: clsx(["rdtYear", { rdtDisabled: isDisabled, rdtActive: isActive }]), onClick: function onClick() { if (!isDisabled) { setSelectedDate(setYear(viewDate, year)); } } }, format(currentYear, "yyyy", formatOptions)); })); })))); } var _excluded = ["viewMode", "isStatic", "id", "className", "style"]; var viewLookup = { time: TimeView, months: MonthsView, years: YearsView, days: DaysView }; var CalendarContainer = /*#__PURE__*/React.forwardRef(function CalendarContainer(props, ref) { var viewMode = props.viewMode, isStatic = props.isStatic, id = props.id, className = props.className, style = props.style, rest = _objectWithoutPropertiesLoose(props, _excluded); if (!viewMode) { return null; } var CalendarElement = viewLookup[viewMode]; return React.createElement("div", { ref: ref, id: id, "data-testid": "picker-wrapper", className: clsx(["rdtPicker", className, { rdtStatic: isStatic }]), style: style }, CalendarElement && React.createElement(CalendarElement, Object.assign({}, rest))); }); var _excluded$1 = ["isValidDate", "dateTypeMode", "value", "onChange", "onBlur", "onFocus", "dateFormat", "timeFormat", "locale", "weekStartsOn", "shouldHideInput", "timeConstraints"]; var FORMATS = { MONTH: "LL", SHORT_MONTH_NAME: "LLL", FULL_MONTH_NAME: "LLLL", SHORT_DAY: "d", DAY: "dd", SHORT_DAY_OF_WEEK: "iiiiii", YEAR: "yyyy", MILITARY_HOUR: "H", HOUR: "h", SHORT_HOUR: "h", SHORT_MINUTE: "m", MINUTE: "mm", SHORT_SECOND: "s", SECOND: "ss", SHORT_MILLISECOND: "SSS", MILLISECOND: "SSS", AM_PM: "a", FULL_TIMESTAMP: "yyyy-MM-dd'T'HH:mm:ss.SSSxxx" }; function useDefaultStateWithOverride(defaultValue) { var _useState = React.useState(undefined), override = _useState[0], setOverride = _useState[1]; var value = override || defaultValue; // Clear the override if the default changes React.useEffect(function () { setOverride(undefined); }, [defaultValue]); return [value, setOverride]; } function useDefaultDateWithOverride(defaultValue) { var _useState2 = React.useState(undefined), override = _useState2[0], setOverride = _useState2[1]; var value = override || defaultValue; // Clear the override if the default changes var changeVal = defaultValue.getTime(); React.useEffect(function () { setOverride(undefined); }, [changeVal]); return [value, setOverride]; } function parse(date, fullFormat, formatOptions) { if (typeof date === "string") { var asDate = rawParse(date, fullFormat, new Date(), formatOptions); if (isDateValid(asDate)) { var formatted = format(asDate, fullFormat, formatOptions); if (date === formatted) { return asDate; } } } else if (date) { var _asDate = toDate(date); if (isDateValid(_asDate)) { return _asDate; } } return undefined; } var nextViewModes = { days: "days", months: "days", years: "months" }; function getDefaultViewMode(dateFormat, timeFormat) { if (dateFormat) { if (dateFormat.match(/[d]/)) { return "days"; } else if (dateFormat.indexOf("L") !== -1) { return "months"; } else if (dateFormat.indexOf("y") !== -1) { return "years"; } } if (timeFormat) { return "time"; } return undefined; } function getDateTypeMode(rawDateTypeMode) { if (typeof rawDateTypeMode === "string") { var lowerRawDateTypeMode = rawDateTypeMode.toLowerCase(); switch (lowerRawDateTypeMode) { case "utc-ms-timestamp": case "input-format": return lowerRawDateTypeMode; } } return "Date"; } // Please do not use types off of a default export module or else Storybook Docs will suffer. // see: https://github.com/storybookjs/storybook/issues/9556 var DateTime = function DateTime(props) { var isValidDate = props.isValidDate, rawDateTypeMode = props.dateTypeMode, value = props.value, rawOnChange = props.onChange, onBlur = props.onBlur, onFocus = props.onFocus, _props$dateFormat = props.dateFormat, rawDateFormat = _props$dateFormat === void 0 ? true : _props$dateFormat, _props$timeFormat = props.timeFormat, rawTimeFormat = _props$timeFormat === void 0 ? true : _props$timeFormat, locale = props.locale, weekStartsOn = props.weekStartsOn, _props$shouldHideInpu = props.shouldHideInput, shouldHideInput = _props$shouldHideInpu === void 0 ? false : _props$shouldHideInpu, timeConstraints = props.timeConstraints, rest = _objectWithoutPropertiesLoose(props, _excluded$1); var isDisabled = props.disabled || props.readOnly; // // Formats // var defaultDateFormat = FORMATS.MONTH + "/" + FORMATS.DAY + "/" + FORMATS.YEAR; var dateFormat = rawDateFormat === true ? defaultDateFormat : rawDateFormat === false ? "" : rawDateFormat; var defaultTimeFormat = FORMATS.HOUR + ":" + FORMATS.MINUTE + " " + FORMATS.AM_PM; var timeFormat = rawTimeFormat === true ? defaultTimeFormat : rawTimeFormat === false ? "" : rawTimeFormat; var fullFormat = dateFormat && timeFormat ? dateFormat + " " + timeFormat : dateFormat || timeFormat || ""; var formatOptions = React.useMemo(function () { return { locale: locale, weekStartsOn: typeof weekStartsOn === "number" ? weekStartsOn % 7 : weekStartsOn }; }, [locale, weekStartsOn]); var valueAsDate = parse(value, fullFormat, formatOptions); var dateTypeMode = getDateTypeMode(rawDateTypeMode); var getChangedValue = React.useCallback(function (newValue) { if (typeof newValue === "string") { return newValue; } if (!newValue) { return newValue; } switch (dateTypeMode) { case "utc-ms-timestamp": return newValue.getTime(); case "input-format": return format(newValue, fullFormat, formatOptions); } return newValue; }, [dateTypeMode, formatOptions, fullFormat]); // // On Change // string -> string // falsy -> raw onChange // Date -> if numeric, number (ms) // Date -> if not numeric, Date // var onChange = React.useCallback(function (newValue) { if (typeof rawOnChange !== "function") { return; } var changedValue = getChangedValue(newValue); // // Suppress change event when the value didn't change! // if (value && changedValue && isDate(value) && isDate(changedValue)) { var oldValStr = format(value, fullFormat, formatOptions); var newValStr = format(changedValue, fullFormat, formatOptions); if (oldValStr === newValStr) { return; } } rawOnChange(changedValue); }, [formatOptions, fullFormat, getChangedValue, rawOnChange, value]); // // ViewDate // var _useDefaultDateWithOv = useDefaultDateWithOverride(valueAsDate || startOfDay(new Date())), viewDate = _useDefaultDateWithOv[0], setViewDate = _useDefaultDateWithOv[1]; // // ViewMode // var defaultViewMode = getDefaultViewMode(dateFormat, timeFormat); var _useDefaultStateWithO = useDefaultStateWithOverride(defaultViewMode), viewMode = _useDefaultStateWithO[0], setViewMode = _useDefaultStateWithO[1]; // // ViewTimestamp // var _useDefaultDateWithOv2 = useDefaultDateWithOverride(valueAsDate || viewDate), viewTimestamp = _useDefaultDateWithOv2[0], setViewTimestamp = _useDefaultDateWithOv2[1]; // // IsOpen // var _useState3 = React.useState(false), isOpen = _useState3[0], setIsOpen = _useState3[1]; function open() { // Don't allow opening if disabled if (isDisabled) { return; } if (!isOpen && viewMode) { setIsOpen(true); if (typeof onFocus === "function") { onFocus(); } } } function closeWith(newValue) { if (isOpen) { setIsOpen(false); if (typeof onBlur === "function") { var changedValue = getChangedValue(newValue); onBlur(changedValue); } } } function close() { return closeWith(valueAsDate); } // // SetSelectedDate // function setSelectedDate(newDate, tryClose) { if (tryClose === void 0) { tryClose = true; } var asDate = toDate(newDate); setViewDate(asDate); setViewTimestamp(asDate); // Time switches value but stays open if (viewMode === "time") { onChange(newDate); } // When view mode is the default, switch and try to close else if (viewMode === defaultViewMode) { onChange(newDate); if (tryClose) { closeWith(newDate); } } // When view mode is not the default, switch to the next view mode else { var newViewMode = viewMode ? nextViewModes[viewMode] : undefined; setViewMode(newViewMode); } } // // Trigger change when important props change // React.useEffect(function () { if (valueAsDate) { setSelectedDate(valueAsDate); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [dateTypeMode, fullFormat]); function onInputChange(e) { var newValue = e.target.value; var newValueAsDate = parse(newValue, fullFormat, formatOptions); if (newValueAsDate) { setSelectedDate(newValueAsDate, false); } else { onChange(newValue); } } function onInputKeyDown(e) { if (isOpen) { switch (e.code) { // Enter key case "Enter": // Eat enter key e.preventDefault(); if (inputRef.current) { inputRef.current.blur(); } close(); break; // Escape key case "Escape": if (inputRef.current) { inputRef.current.blur(); } close(); break; // Tab key case "Tab": close(); break; } } else { switch (e.code) { // Down arrow case "ArrowDown": open(); break; } } } var inputRef = React.useRef(null); var contentRef = React.useRef(null); useOnClickOutside(contentRef, close); var valueStr = valueAsDate && fullFormat ? format(valueAsDate, fullFormat, formatOptions) : typeof value === "string" ? value : ""; // // Input Props // var finalInputProps = _extends({}, rest, { ref: inputRef, type: "text", onClick: open, onFocus: open, onChange: onInputChange, onKeyDown: onInputKeyDown, value: valueStr }); // // Calendar props // var calendarProps = { ref: contentRef, dateFormat: dateFormat, timeFormat: timeFormat, viewDate: viewDate, setViewDate: setViewDate, selectedDate: valueAsDate, setSelectedDate: setSelectedDate, viewTimestamp: viewTimestamp, setViewTimestamp: setViewTimestamp, formatOptions: formatOptions, viewMode: viewMode, setViewMode: setViewMode, isValidDate: isValidDate, isStatic: shouldHideInput, timeConstraints: timeConstraints }; return !shouldHideInput ? React__default.createElement(React__default.Fragment, null, React__default.createElement("input", Object.assign({}, finalInputProps)), isOpen && React__default.createElement(popover.Popover, { targetRef: inputRef }, React__default.createElement(CalendarContainer, Object.assign({}, calendarProps)))) : React__default.createElement(CalendarContainer, Object.assign({}, finalInputProps, calendarProps)); }; exports.DateTime = DateTime; exports.FORMATS = FORMATS; exports.default = DateTime; Object.defineProperty(exports, '__esModule', { value: true }); }))); //# sourceMappingURL=react-datetime.umd.development.js.map