@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
460 lines (459 loc) • 16 kB
JavaScript
"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