UNPKG

@navikt/ds-react

Version:

React components from the Norwegian Labour and Welfare Administration.

164 lines 7.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useDatepicker = void 0; const date_fns_1 = require("date-fns"); const react_1 = require("react"); const react_day_picker_1 = require("react-day-picker"); const i18n_hooks_1 = require("../../../util/i18n/i18n.hooks"); const Date_locale_1 = require("../../Date.locale"); const date_utils_1 = require("../../date-utils"); const getValidationMessage = (val = {}) => (Object.assign({ isDisabled: false, isWeekend: false, isEmpty: false, isInvalid: false, isBefore: false, isAfter: false, isValidDate: true }, val)); /** * * @see 🏷️ {@link UseDatepickerOptions} * @see 🏷️ {@link UseDatepickerValue} * @see 🏷️ {@link DateValidationT} * @example * const { datepickerProps, inputProps } = useDatepicker({ * fromDate: new Date("Aug 23 2019"), * toDate: new Date("Feb 23 2024"), * onDateChange: console.log, * onValidate: console.log, * }); */ const useDatepicker = (opt = {}) => { var _a; const { locale: _locale, required, defaultSelected: _defaultSelected, today = new Date(), fromDate, toDate, disabled, disableWeekends, onDateChange, inputFormat, onValidate, defaultMonth, allowTwoDigitYear = true, } = opt; const [anchorRef, setAnchorRef] = (0, react_1.useState)(null); const localeFromProvider = (0, i18n_hooks_1.useDateLocale)(); const locale = _locale ? (0, Date_locale_1.getLocaleFromString)(_locale) : localeFromProvider; const [defaultSelected, setDefaultSelected] = (0, react_1.useState)(_defaultSelected); // Initialize states const [month, setMonth] = (0, react_1.useState)((_a = defaultSelected !== null && defaultSelected !== void 0 ? defaultSelected : defaultMonth) !== null && _a !== void 0 ? _a : today); const [selectedDay, setSelectedDay] = (0, react_1.useState)(defaultSelected); const [open, setOpen] = (0, react_1.useState)(false); const defaultInputValue = defaultSelected ? (0, date_utils_1.formatDateForInput)(defaultSelected, locale, "date", inputFormat) : ""; const [inputValue, setInputValue] = (0, react_1.useState)(defaultInputValue); const handleOpen = (0, react_1.useCallback)((newOpen) => { var _a, _b; setOpen(newOpen); newOpen && setMonth((_b = (_a = selectedDay !== null && selectedDay !== void 0 ? selectedDay : defaultSelected) !== null && _a !== void 0 ? _a : defaultMonth) !== null && _b !== void 0 ? _b : today); }, [defaultMonth, defaultSelected, selectedDay, today]); const updateDate = (date) => { onDateChange === null || onDateChange === void 0 ? void 0 : onDateChange(date); setSelectedDay(date); }; const updateValidation = (val = {}) => onValidate === null || onValidate === void 0 ? void 0 : onValidate(getValidationMessage(val)); const reset = () => { var _a; updateDate(defaultSelected); setMonth((_a = defaultSelected !== null && defaultSelected !== void 0 ? defaultSelected : defaultMonth) !== null && _a !== void 0 ? _a : today); setInputValue(defaultInputValue !== null && defaultInputValue !== void 0 ? defaultInputValue : ""); setDefaultSelected(_defaultSelected); }; const setSelected = (date) => { var _a; updateDate(date); setMonth((_a = date !== null && date !== void 0 ? date : defaultMonth) !== null && _a !== void 0 ? _a : today); setInputValue(date ? (0, date_utils_1.formatDateForInput)(date, locale, "date", inputFormat) : ""); }; const handleFocus = (e) => { if (e.target.readOnly) { return; } const day = (0, date_utils_1.parseDate)(e.target.value, today, locale, "date", allowTwoDigitYear); if ((0, date_utils_1.isValidDate)(day)) { setInputValue((0, date_utils_1.formatDateForInput)(day, locale, "date", inputFormat)); const isBefore = fromDate && day && (0, date_fns_1.differenceInCalendarDays)(fromDate, day) > 0; const isAfter = toDate && day && (0, date_fns_1.differenceInCalendarDays)(day, toDate) > 0; !isBefore && !isAfter && setMonth(day); } }; const handleBlur = (e) => { const day = (0, date_utils_1.parseDate)(e.target.value, today, locale, "date", allowTwoDigitYear); (0, date_utils_1.isValidDate)(day) && setInputValue((0, date_utils_1.formatDateForInput)(day, locale, "date", inputFormat)); }; /* Only allow de-selecting if not required */ const handleDayClick = (day, { selected }) => { if (selected && required) { return; } if (day && !selected) { handleOpen(false); anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.focus(); } if (selected) { updateDate(undefined); setInputValue(""); updateValidation({ isValidDate: false, isEmpty: true }); return; } updateDate(day); updateValidation(); setMonth(day); setInputValue(day ? (0, date_utils_1.formatDateForInput)(day, locale, "date", inputFormat) : ""); }; // When changing the input field, save its value in state and check if the // string is a valid date. If it is a valid day, set it as selected and update // the calendar’s month. const handleChange = (e) => { setInputValue(e.target.value); const day = (0, date_utils_1.parseDate)(e.target.value, today, locale, "date", allowTwoDigitYear); const isBefore = fromDate && day && (0, date_fns_1.differenceInCalendarDays)(fromDate, day) > 0; const isAfter = toDate && day && (0, date_fns_1.differenceInCalendarDays)(day, toDate) > 0; if (!(0, date_utils_1.isValidDate)(day) || (disableWeekends && (0, date_fns_1.isWeekend)(day)) || (disabled && (0, react_day_picker_1.dateMatchModifiers)(day, disabled))) { updateDate(undefined); updateValidation({ isInvalid: !(0, date_utils_1.isValidDate)(day), isWeekend: disableWeekends && (0, date_fns_1.isWeekend)(day), isDisabled: disabled && (0, react_day_picker_1.dateMatchModifiers)(day, disabled), isValidDate: false, isEmpty: !e.target.value, isBefore: isBefore !== null && isBefore !== void 0 ? isBefore : false, isAfter: isAfter !== null && isAfter !== void 0 ? isAfter : false, }); return; } if (isBefore || isAfter) { updateDate(undefined); updateValidation({ isValidDate: false, isBefore: isBefore !== null && isBefore !== void 0 ? isBefore : false, isAfter: isAfter !== null && isAfter !== void 0 ? isAfter : false, }); return; } updateDate(day); updateValidation(); setMonth(defaultMonth !== null && defaultMonth !== void 0 ? defaultMonth : day); }; const datepickerProps = { month, onMonthChange: setMonth, onDayClick: handleDayClick, selected: selectedDay !== null && selectedDay !== void 0 ? selectedDay : new Date("Invalid date"), locale: _locale, fromDate, toDate, today, open, onClose: () => { handleOpen(false); anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.focus(); }, onOpenToggle: () => handleOpen(!open), disabled, disableWeekends, }; const inputProps = { onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, value: inputValue, setAnchorRef, }; return { datepickerProps, inputProps, reset, selectedDay, setSelected }; }; exports.useDatepicker = useDatepicker; //# sourceMappingURL=useDatepicker.js.map