UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

460 lines (459 loc) 16 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; exports.parseRangeValue = parseRangeValue; var _push = _interopRequireDefault(require("core-js-pure/stable/instance/push.js")); var _react = _interopRequireWildcard(require("react")); var z = _interopRequireWildcard(require("zod")); var _index = require("../../../../components/index.js"); var _index2 = require("../../hooks/index.js"); var _utils = require("../../../../components/flex/utils.js"); var _classnames = _interopRequireDefault(require("classnames")); var _index3 = _interopRequireDefault(require("../../FieldBlock/index.js")); var _Context = _interopRequireDefault(require("../../../../shared/Context.js")); var _dateFns = require("date-fns"); var _useTranslation = _interopRequireDefault(require("../../hooks/useTranslation.js")); var _DatePickerCalc = require("../../../../components/date-picker/DatePickerCalc.js"); var _index4 = require("../../utils/index.js"); var _useInvalidDates = _interopRequireDefault(require("./hooks/useInvalidDates.js")); var _DateFormatUtils = require("../../../../components/date-format/DateFormatUtils.js"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } function DateComponent(props) { var _props$value; const { errorRequired, label: defaultLabel } = (0, _useTranslation.default)().Date; const { locale } = (0, _react.useContext)(_Context.default); const { invalidDatesRef, setInvalidDates } = (0, _useInvalidDates.default)(); const lastEditedRangeDateRef = (0, _react.useRef)('start'); const errorMessages = (0, _react.useMemo)(() => { return { 'Field.errorRequired': errorRequired, 'Field.errorPattern': errorRequired, ...props.errorMessages }; }, [props.errorMessages, errorRequired]); const schema = (0, _react.useMemo)(() => { if (props.schema) { return props.schema; } return p => { let s = z.string(); if (p !== null && p !== void 0 && p.pattern) { try { s = s.regex(new RegExp(p.pattern, 'u')); } catch (_e) {} } return s; }; }, [props.schema, props.pattern]); const validateRequired = (0, _react.useCallback)((value, { required, error }) => { if (!required) { return undefined; } if (props.range) { if (value) { const [startDate, endDate] = parseRangeValue(value); if (startDate && endDate) { return undefined; } } return new _index4.FormError('Date.errorRequiredRange'); } return !value || !(0, _dateFns.isValid)((0, _dateFns.parseISO)(value)) ? error : undefined; }, [props.range]); const dateValidator = (0, _react.useCallback)(value => { const invalidDateErrors = validateDate(invalidDatesRef.current); const rangeOrderErrors = validateRangeOrder({ value, isRange: props.range, lastEditedDate: lastEditedRangeDateRef.current, locale }); if (!props.minDate && !props.maxDate) { return [...invalidDateErrors, ...rangeOrderErrors]; } const dateLimitErrors = validateDateLimit({ value, locale, minDate: props.minDate, maxDate: props.maxDate, isRange: props.range }); return [...invalidDateErrors, ...dateLimitErrors, ...(dateLimitErrors.length > 0 ? [] : rangeOrderErrors)]; }, [props.maxDate, props.minDate, props.range, invalidDatesRef, locale]); const { onBlurValidator: propOnBlurValidator, onChangeValidator, ...restProps } = props; const onBlurValidator = (0, _react.useMemo)(() => { if (propOnBlurValidator === false) { return undefined; } if (propOnBlurValidator) { return propOnBlurValidator; } return dateValidator; }, [propOnBlurValidator, dateValidator]); const fromInput = (0, _react.useCallback)(({ date, start_date, end_date, invalidDate, invalidStartDate, invalidEndDate }) => { setInvalidDates({ invalidDate, invalidStartDate, invalidEndDate }); return props.range ? `${start_date}|${end_date}` : date; }, [props.range, setInvalidDates]); const preparedProps = { ...restProps, errorMessages, schema, fromInput, validateRequired, onBlurValidator, onChangeValidator, exportValidators: { dateValidator }, invalidDatesRef }; const { id, path, itemPath, className, label, value: internalValue, hasError, disabled, htmlAttributes, handleError, handleFocus, handleBlur, handleChange, setChanged, setDisplayValue, range, showCancelButton = true, showResetButton = true, showInput = true, onReset, minDate, maxDate, width, ...rest } = (0, _index2.useFieldProps)(preparedProps); const datePickerProps = pickDatePickerProps(rest); const initialValueRef = (0, _react.useRef)((_props$value = props.value) !== null && _props$value !== void 0 ? _props$value : props.defaultValue); const handleReset = (0, _react.useCallback)(event => { const initialValue = initialValueRef.current; if (initialValue) { if (range) { const [startDate, endDate] = parseRangeValue(initialValue); handleChange({ start_date: startDate !== null && startDate !== void 0 ? startDate : undefined, end_date: endDate !== null && endDate !== void 0 ? endDate : undefined }); } else { handleChange({ date: initialValue }); } onReset === null || onReset === void 0 || onReset(event); return; } const reset = { date: undefined, start_date: undefined, end_date: undefined, is_valid: false }; handleChange(reset); setDisplayValue(undefined); onReset === null || onReset === void 0 || onReset({ ...event, ...reset }); }, [handleChange, onReset, setDisplayValue, range]); const onFocus = (0, _react.useCallback)(() => { handleFocus(); handleError(); }, [handleFocus, handleError]); const onType = (0, _react.useCallback)(event => { const { date, start_date, end_date, ...rest } = event; if (props.range) { const [prevStart, prevEnd] = parseRangeValue(internalValue); if (start_date !== prevStart) { lastEditedRangeDateRef.current = 'start'; } else if (end_date !== prevEnd) { lastEditedRangeDateRef.current = 'end'; } const parsedStartDate = (0, _dateFns.parseISO)(start_date); const parsedEndDate = (0, _dateFns.parseISO)(end_date); if ((0, _dateFns.isValid)(parsedStartDate) || (0, _dateFns.isValid)(parsedEndDate)) { handleChange({ ...((0, _dateFns.isValid)(parsedStartDate) && { start_date }), ...((0, _dateFns.isValid)(parsedEndDate) && { end_date }), ...rest }); } else { handleChange(rest); } } else if ((0, _dateFns.isValid)((0, _dateFns.parseISO)(date))) { handleChange({ date, ...rest }); } else { handleChange(rest); } setChanged(true); }, [handleChange, props.range, setChanged, internalValue]); const { value, startDate, endDate } = (0, _react.useMemo)(() => { if (!range || !internalValue) { return { value: internalValue !== null && internalValue !== void 0 ? internalValue : null, startDate: undefined, endDate: undefined }; } const [startDate, endDate] = parseRangeValue(internalValue); return { value: undefined, startDate, endDate }; }, [range, internalValue]); (0, _react.useMemo)(() => { if ((path || itemPath) && value) { setDisplayValue((0, _DateFormatUtils.formatDate)(value, { locale })); } }, [itemPath, locale, path, setDisplayValue, value]); const fieldBlockProps = { forId: id, label: label !== null && label !== void 0 ? label : defaultLabel, className: (0, _classnames.default)('dnb-forms-field-string', className), width, ...(0, _utils.pickSpacingProps)(props) }; return _react.default.createElement(_index3.default, fieldBlockProps, _react.default.createElement(_index.DatePicker, _extends({ id: id, date: value, disabled: disabled, showInput: showInput, alignPicker: showInput && (width === 'large' || width === 'stretch') ? 'right' : undefined, showCancelButton: showCancelButton, showResetButton: showResetButton, stretch: width !== undefined, startDate: startDate, endDate: endDate, minDate: minDate, maxDate: maxDate, status: hasError ? 'error' : undefined, range: range, onReset: handleReset, onType: onType, onChange: handleChange, onFocus: onFocus, onBlur: handleBlur }, datePickerProps, htmlAttributes))); } function parseRangeValue(value) { return String(value).split('|').map(value => /(undefined|null)/.test(value) ? null : value); } function validateDateLimit({ value, isRange, locale, ...dates }) { if (!dates.minDate && !dates.maxDate || !value) { return []; } const [startDateParsed, endDateParsed] = parseRangeValue(value); const convertedMinDate = (0, _DatePickerCalc.convertStringToDate)(dates.minDate); const convertedMaxDate = (0, _DatePickerCalc.convertStringToDate)(dates.maxDate); const convertedStartDate = (0, _DatePickerCalc.convertStringToDate)(startDateParsed); const convertedEndDate = (0, _DatePickerCalc.convertStringToDate)(endDateParsed); const minDate = convertedMinDate ? (0, _dateFns.startOfDay)(convertedMinDate) : undefined; const maxDate = convertedMaxDate ? (0, _dateFns.startOfDay)(convertedMaxDate) : undefined; const startDate = convertedStartDate ? (0, _dateFns.startOfDay)(convertedStartDate) : undefined; const endDate = convertedEndDate ? (0, _dateFns.startOfDay)(convertedEndDate) : undefined; const isoDates = { minDate: dates.minDate instanceof Date ? dates.minDate.toISOString() : dates.minDate, maxDate: dates.maxDate instanceof Date ? dates.maxDate.toISOString() : dates.maxDate }; const options = { locale, options: { dateStyle: 'long' } }; const messages = []; if (!isRange) { if ((0, _dateFns.isBefore)(startDate, minDate)) { (0, _push.default)(messages).call(messages, new _index4.FormError('Date.errorMinDate', { messageValues: { date: (0, _DateFormatUtils.formatDate)(isoDates.minDate, options) } })); } if ((0, _dateFns.isAfter)(startDate, maxDate)) { (0, _push.default)(messages).call(messages, new _index4.FormError('Date.errorMaxDate', { messageValues: { date: (0, _DateFormatUtils.formatDate)(isoDates.maxDate, options) } })); } return messages; } if ((0, _dateFns.isBefore)(startDate, minDate)) { (0, _push.default)(messages).call(messages, new _index4.FormError('Date.errorStartDateMinDate', { messageValues: { date: (0, _DateFormatUtils.formatDate)(isoDates.minDate, options) } })); } if ((0, _dateFns.isAfter)(startDate, maxDate)) { (0, _push.default)(messages).call(messages, new _index4.FormError('Date.errorStartDateMaxDate', { messageValues: { date: (0, _DateFormatUtils.formatDate)(isoDates.maxDate, options) } })); } if ((0, _dateFns.isBefore)(endDate, minDate)) { (0, _push.default)(messages).call(messages, new _index4.FormError('Date.errorEndDateMinDate', { messageValues: { date: (0, _DateFormatUtils.formatDate)(isoDates.minDate, options) } })); } if ((0, _dateFns.isAfter)(endDate, maxDate)) { (0, _push.default)(messages).call(messages, new _index4.FormError('Date.errorEndDateMaxDate', { messageValues: { date: (0, _DateFormatUtils.formatDate)(isoDates.maxDate, options) } })); } return messages; } function validateRangeOrder({ value, isRange, lastEditedDate, locale }) { if (!isRange || !value) { return []; } const [startDateParsed, endDateParsed] = parseRangeValue(value); const convertedStartDate = (0, _DatePickerCalc.convertStringToDate)(startDateParsed); const convertedEndDate = (0, _DatePickerCalc.convertStringToDate)(endDateParsed); const startDate = convertedStartDate ? (0, _dateFns.startOfDay)(convertedStartDate) : undefined; const endDate = convertedEndDate ? (0, _dateFns.startOfDay)(convertedEndDate) : undefined; if (startDate && endDate && (0, _dateFns.isAfter)(startDate, endDate)) { const options = { locale, options: { dateStyle: 'long' } }; if (lastEditedDate === 'end') { return [new _index4.FormError('Date.errorEndDateMinDate', { messageValues: { date: (0, _DateFormatUtils.formatDate)(startDateParsed, options) } })]; } return [new _index4.FormError('Date.errorStartDateMaxDate', { messageValues: { date: (0, _DateFormatUtils.formatDate)(endDateParsed, options) } })]; } return []; } function validateDate({ invalidDate, invalidStartDate, invalidEndDate }) { if (invalidDate && !isEmptyOrPlaceholder(invalidDate)) { return [new _index4.FormError('Date.errorInvalidDate', { messageValues: { date: invalidDate } })]; } const errors = []; if (invalidStartDate && !isEmptyOrPlaceholder(invalidStartDate)) { (0, _push.default)(errors).call(errors, new _index4.FormError('Date.errorInvalidStartDate', { messageValues: { date: invalidStartDate } })); } if (invalidEndDate && !isEmptyOrPlaceholder(invalidEndDate)) { (0, _push.default)(errors).call(errors, new _index4.FormError('Date.errorInvalidEndDate', { messageValues: { date: invalidEndDate } })); } return errors; } function isEmptyOrPlaceholder(date) { if (!date) { return true; } return !/\d/.test(date); } const datePickerPropKeys = ['month', 'startMonth', 'endMonth', 'minDate', 'maxDate', 'correctInvalidDate', 'maskOrder', 'maskPlaceholder', 'dateFormat', 'returnFormat', 'hideNavigation', 'hideDays', 'onlyMonth', 'hideLastWeek', 'disableAutofocus', 'showSubmitButton', 'submitButtonText', 'cancelButtonText', 'resetButtonText', 'firstDay', 'link', 'size', 'sync', 'addonElement', 'shortcuts', 'opened', 'direction', 'alignPicker', 'onDaysRender', 'showInput', 'onDaysRender', 'onType', 'onShow', 'onHide', 'onSubmit', 'onCancel', 'onReset', 'skipPortal', 'yearNavigation', 'tooltip']; function pickDatePickerProps(props) { const datePickerProps = Object.keys(props).reduce((datePickerProps, key) => { if (datePickerPropKeys.includes(key)) { datePickerProps[key] = props[key]; } return datePickerProps; }, {}); return datePickerProps; } DateComponent._supportsSpacingProps = true; var _default = exports.default = DateComponent; //# sourceMappingURL=Date.js.map