@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
274 lines • 8.51 kB
JavaScript
import _pushInstanceProperty from "core-js-pure/stable/instance/push.js";
import React, { useCallback, useMemo } from 'react';
import { pickSpacingProps } from "../../../../components/flex/utils.js";
import { useFieldProps } from "../../hooks/index.js";
import clsx from 'clsx';
import FieldBlock from "../../FieldBlock/index.js";
import SegmentedField from "../../../../components/input-masked/segmented-field/SegmentedField.js";
import { useTranslation as useSharedTranslation } from "../../../../shared/index.js";
import useTranslation from "../../hooks/useTranslation.js";
import { FormError } from "../../utils/index.js";
import { jsx as _jsx } from "react/jsx-runtime";
function Expiry(props = {}) {
const {
label: expiryLabel,
errorRequired
} = useTranslation().Expiry;
const {
DatePicker: {
placeholderCharacters: placeholders,
month: monthLabel,
year: yearLabel
}
} = useSharedTranslation();
const expiryValidator = useCallback(value => validateMonthAndYear(value, placeholders), [placeholders]);
const {
onBlurValidator = expiryValidator,
onChangeValidator,
errorMessages: propErrorMessages,
validateInitially: validateInitiallyProp,
validateContinuously,
value: valueProp,
transformIn: transformInProp,
onStatusChange
} = props;
const errorMessages = useMemo(() => ({
'Field.errorRequired': errorRequired,
...propErrorMessages
}), [errorRequired, propErrorMessages]);
const fromInput = useCallback(values => {
const monthString = expiryValueToString(stripPlaceholderChars(values.month, placeholders.month), placeholders.month);
const yearString = expiryValueToString(stripPlaceholderChars(values.year, placeholders.year), placeholders.year);
if (isFieldEmpty(monthString, placeholders.month) && isFieldEmpty(yearString, placeholders.year)) {
return undefined;
}
return `${monthString}${yearString}`;
}, [placeholders.month, placeholders.year]);
const validateRequired = useCallback((value, {
required,
error
}) => {
return required && !value ? error : undefined;
}, []);
const validateInitially = useMemo(() => {
if (validateInitiallyProp) {
return validateInitiallyProp;
}
if (valueProp) {
return true;
}
return undefined;
}, [validateInitiallyProp, valueProp]);
const fromExternal = useCallback(external => {
if (typeof external === 'string') {
const {
month,
year
} = stringToExpiryValue(external);
const monthString = expiryValueToString(month, placeholders.month);
const yearString = expiryValueToString(year, placeholders.year);
if (isFieldEmpty(monthString, placeholders.month) && isFieldEmpty(yearString, placeholders.year)) {
return undefined;
}
return `${monthString}${yearString}`;
}
return external;
}, [placeholders.month, placeholders.year]);
const transformIn = useCallback(value => {
if (transformInProp) {
const external = transformInProp(value);
if (typeof external === 'string') {
return external;
}
if (external !== null && external !== void 0 && external.year || external !== null && external !== void 0 && external.month) {
const monthString = expiryValueToString(external.month, placeholders.month);
const yearString = expiryValueToString(external.year, placeholders.year);
if (isFieldEmpty(monthString, placeholders.month) && isFieldEmpty(yearString, placeholders.year)) {
return undefined;
}
return `${monthString}${yearString}`;
}
}
return value;
}, [transformInProp, placeholders.month, placeholders.year]);
const provideAdditionalArgs = useCallback(value => {
const {
month,
year
} = stringToExpiryValue(value);
return {
month: stripPlaceholderChars(month, placeholders.month) || undefined,
year: stripPlaceholderChars(year, placeholders.year) || undefined
};
}, [placeholders.month, placeholders.year]);
const preparedProps = {
...props,
errorMessages,
validateInitially,
validateContinuously,
fromExternal,
transformIn,
fromInput,
provideAdditionalArgs,
validateRequired,
onBlurValidator: onBlurValidator,
onChangeValidator,
onStatusChange,
exportValidators: {
expiryValidator
}
};
const {
id,
path,
itemPath,
className,
label = expiryLabel,
hasError,
info,
warning,
disabled,
size,
value = '',
htmlAttributes,
handleFocus,
handleBlur,
handleChange,
setDisplayValue
} = useFieldProps(preparedProps);
const expiry = useMemo(() => {
const {
month,
year
} = stringToExpiryValue(value);
return {
month: stripPlaceholderChars(month, placeholders.month),
year: stripPlaceholderChars(year, placeholders.year)
};
}, [placeholders.month, placeholders.year, value]);
useMemo(() => {
if ((path || itemPath) && expiry.month && expiry.year) {
setDisplayValue(`${expiry.month}/${expiry.year}`);
}
}, [expiry.month, expiry.year, itemPath, path, setDisplayValue]);
const status = hasError ? 'error' : warning ? 'warning' : info ? 'information' : null;
const fieldBlockProps = {
id,
forId: `${id}-input`,
className: clsx('dnb-forms-field-expiry', className),
label,
...pickSpacingProps(props)
};
return _jsx(FieldBlock, {
...fieldBlockProps,
children: _jsx(SegmentedField, {
stretch: true,
id: `${id}-input`,
values: expiry,
status: status === 'error',
disabled: disabled,
size: size,
onChange: handleChange,
onBlur: handleBlur,
onFocus: handleFocus,
delimiter: "/",
inputMode: "numeric",
inputs: [{
id: 'month',
label: monthLabel,
mask: [/[0-9]/, /[0-9]/],
spinButton: {
min: 1,
max: 12,
getInitialValue: () => new Date().getMonth() + 1
},
placeholder: repeatPlaceholder(placeholders.month, 2),
autoComplete: 'cc-exp-month',
...htmlAttributes
}, {
id: 'year',
label: yearLabel,
mask: [/[0-9]/, /[0-9]/],
spinButton: {
min: 0,
max: 99,
getInitialValue: () => new Date().getFullYear() % 100
},
placeholder: repeatPlaceholder(placeholders.year, 2),
autoComplete: 'cc-exp-year',
...htmlAttributes
}]
})
});
}
function isFieldEmpty(value, placeholder) {
return value === `${placeholder}${placeholder}`;
}
function stringToExpiryValue(value) {
const month = typeof value === 'string' ? value === null || value === void 0 ? void 0 : value.substring(0, 2) : undefined;
const year = typeof value === 'string' ? value === null || value === void 0 ? void 0 : value.substring(2, 4) : undefined;
return {
month,
year
};
}
function expiryValueToString(value, placeholder) {
if (!value) {
return `${placeholder}${placeholder}`;
}
if (value.length === 1) {
return `${value}${placeholder}`;
}
return value;
}
function repeatPlaceholder(character, length) {
if (!character) {
return '';
}
return Array.from({
length
}, () => character).join('');
}
function stripPlaceholderChars(value, placeholder) {
if (!value) {
return '';
}
if (!placeholder) {
return value;
}
return value.split(placeholder).join('');
}
function validateMonthAndYear(date, placeholders) {
const {
month,
year
} = stringToExpiryValue(date);
const monthNumber = Number(month);
const messages = [];
const isMonthEmpty = !month || month.includes(placeholders.month) && !/\d/.test(month);
const isYearEmpty = !year || year.includes(placeholders.year) && !/\d/.test(year);
if (isMonthEmpty && isYearEmpty) {
return messages;
}
if (month.includes(placeholders.month) || monthNumber < 1 || monthNumber > 12) {
_pushInstanceProperty(messages).call(messages, new FormError('Expiry.errorMonth', {
messageValues: {
month: month
}
}));
}
if (year.includes(placeholders.year)) {
_pushInstanceProperty(messages).call(messages, new FormError('Expiry.errorYear', {
messageValues: {
year: year
}
}));
}
if (messages.length) {
return messages;
}
return undefined;
}
Expiry._supportsEufemiaSpacingProps = true;
export default Expiry;
//# sourceMappingURL=Expiry.js.map