@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
235 lines • 7.09 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 classnames from 'classnames';
import FieldBlock from "../../FieldBlock/index.js";
import { MultiInputMask } from "../../../../components/input-masked/index.js";
import { useTranslation as useSharedTranslation } from "../../../../shared/index.js";
import useTranslation from "../../hooks/useTranslation.js";
import { FormError } from "../../utils/index.js";
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 month = expiryValueToString(values.month, placeholders.month);
const year = expiryValueToString(values.year, placeholders.year);
if (isFieldEmpty(month, placeholders.month) && isFieldEmpty(year, placeholders.year)) {
return undefined;
}
return `${month}${year}`;
}, [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) {
return `${external.month}${external.year}`;
}
}
return value;
}, [transformInProp]);
const provideAdditionalArgs = useCallback(value => {
let {
month,
year
} = stringToExpiryValue(value);
if (isNaN(Number(month))) {
month = undefined;
}
if (isNaN(Number(year))) {
year = undefined;
}
return {
month,
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(() => stringToExpiryValue(value), [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 ? 'warn' : info ? 'info' : null;
const fieldBlockProps = {
id,
forId: `${id}-input-month`,
className: classnames('dnb-forms-field-expiry', className),
label,
...pickSpacingProps(props)
};
return React.createElement(FieldBlock, fieldBlockProps, React.createElement(MultiInputMask, {
stretch: true,
id: `${id}-input`,
values: expiry,
status: status === 'error',
statusState: disabled ? 'disabled' : undefined,
disabled: disabled,
size: size,
onChange: handleChange,
onBlur: handleBlur,
onFocus: handleFocus,
delimiter: "/",
inputMode: "numeric",
inputs: [{
id: 'month',
label: monthLabel,
mask: [/[0-9]/, /[0-9]/],
placeholderCharacter: placeholders['month'],
autoComplete: 'cc-exp-month',
...htmlAttributes
}, {
id: 'year',
label: yearLabel,
mask: [/[0-9]/, /[0-9]/],
placeholderCharacter: placeholders['year'],
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 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;
}
}
Expiry._supportsEufemiaSpacingProps = true;
export default Expiry;
//# sourceMappingURL=Expiry.js.map