UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

258 lines 7.62 kB
import _includesInstanceProperty from "core-js-pure/stable/instance/includes.js"; import { 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 from "../../hooks/useTranslation.js"; import { FormError } from "../../utils/index.js"; import { jsx as _jsx } from "react/jsx-runtime"; function Time(props = {}) { var _useTranslation$Time; const { label: timeLabel, errorRequired, hoursPlaceholder, minutesPlaceholder, secondsPlaceholder, hours: hoursLabel, minutes: minutesLabel, seconds: secondsLabel } = (_useTranslation$Time = useTranslation().Time) !== null && _useTranslation$Time !== void 0 ? _useTranslation$Time : {}; const { showSeconds } = props; const timeValidator = useCallback(value => validateTime(value, showSeconds), [showSeconds]); const { onBlurValidator = timeValidator, 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 { hours, minutes, seconds } = values; if (!hours && !minutes && (!showSeconds || !seconds)) { return undefined; } return showSeconds ? `${hours}:${minutes}:${seconds}` : `${hours}:${minutes}`; }, [showSeconds]); const validateRequired = useCallback((value, { required, error }) => { return required && !value ? error : undefined; }, []); const validateInitially = useMemo(() => validateInitiallyProp || (valueProp ? true : undefined), [validateInitiallyProp, valueProp]); const fromExternal = useCallback(external => { if (typeof external !== 'string') { return external; } const { hours, minutes, seconds } = stringToTimeValue(external); if (!hours && !minutes) { return undefined; } return seconds ? `${hours}:${minutes}:${seconds}` : `${hours}:${minutes}`; }, []); const transformIn = useCallback(value => { if (!transformInProp) { return value; } const external = transformInProp(value); if (typeof external === 'string') { return external; } if (!external?.hours && !external?.minutes && !external?.seconds) { return value; } const hours = external.hours; const minutes = external.minutes; if (!hours && !minutes) { return undefined; } const seconds = external.seconds; return seconds ? `${hours}:${minutes}:${seconds}` : `${hours}:${minutes}`; }, [transformInProp]); const provideAdditionalArgs = useCallback(value => { const { hours, minutes, seconds } = stringToTimeValue(value); return { hours: hours || undefined, minutes: minutes || undefined, ...(showSeconds && { seconds: seconds || undefined }) }; }, [showSeconds]); const preparedProps = { ...props, errorMessages, validateInitially, validateContinuously, fromExternal, transformIn, fromInput, provideAdditionalArgs, validateRequired, onBlurValidator: onBlurValidator, onChangeValidator, onStatusChange, exportValidators: { timeValidator } }; const { id, path, itemPath, className, label = timeLabel, hasError, info, warning, disabled, size, value = '', htmlAttributes, handleFocus, handleBlur, handleChange, setDisplayValue } = useFieldProps(preparedProps); const time = useMemo(() => { const { hours, minutes, seconds } = stringToTimeValue(value); return { hours: hours || '', minutes: minutes || '', seconds: showSeconds && seconds || '' }; }, [value, showSeconds]); useMemo(() => { if ((path || itemPath) && time.hours && time.minutes) { setDisplayValue(time.seconds ? `${time.hours}:${time.minutes}:${time.seconds}` : `${time.hours}:${time.minutes}`); } }, [time.hours, time.minutes, time.seconds, itemPath, path, setDisplayValue]); const status = hasError ? 'error' : warning ? 'warning' : info ? 'information' : null; const fieldBlockProps = { id, forId: `${id}-input`, className: clsx('dnb-forms-field-time', className), label, ...pickSpacingProps(props) }; return _jsx(FieldBlock, { ...fieldBlockProps, children: _jsx(SegmentedField, { stretch: true, id: `${id}-input`, values: time, status: status === 'error', disabled: disabled, size: size, onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, delimiter: ":", inputMode: "numeric", inputs: [{ id: 'hours', label: hoursLabel, mask: [/[0-9]/, /[0-9]/], spinButton: { min: 0, max: 24, getInitialValue: () => new Date().getHours() }, placeholder: hoursPlaceholder?.repeat(2), ...htmlAttributes }, { id: 'minutes', label: minutesLabel, mask: [/[0-9]/, /[0-9]/], spinButton: { min: 0, max: 59, getInitialValue: () => new Date().getMinutes() }, placeholder: minutesPlaceholder?.repeat(2), ...htmlAttributes }, ...(showSeconds ? [{ id: 'seconds', label: secondsLabel, mask: [/[0-9]/, /[0-9]/], spinButton: { min: 0, max: 59, getInitialValue: () => new Date().getSeconds() }, placeholder: secondsPlaceholder?.repeat(2), ...htmlAttributes }] : [])] }) }); } function stringToTimeValue(value) { if (typeof value !== 'string' || !_includesInstanceProperty(value).call(value, ':')) { return { hours: undefined, minutes: undefined, seconds: undefined }; } const [hours, minutes, seconds] = value.split(':'); return { hours, minutes, seconds }; } function validateTime(time, showSeconds) { if (!time || !_includesInstanceProperty(time).call(time, ':')) { return undefined; } const { hours, minutes, seconds } = stringToTimeValue(time); if (!hours && !minutes && (!showSeconds || !seconds)) { return []; } const hoursNumber = Number(hours); const minutesNumber = Number(minutes); const secondsNumber = Number(seconds); const hoursInvalid = !hours || hours.length !== 2 || isNaN(hoursNumber) || hoursNumber < 0 || hoursNumber > 24; const minutesInvalid = !minutes || minutes.length !== 2 || isNaN(minutesNumber) || minutesNumber < 0 || minutesNumber > 59; const secondsInvalid = showSeconds && (!seconds || seconds.length !== 2 || isNaN(secondsNumber) || secondsNumber < 0 || secondsNumber > 59); const is24WithNonZero = hoursNumber === 24 && (minutesNumber !== 0 || showSeconds && secondsNumber !== 0); if (hoursInvalid || minutesInvalid || secondsInvalid || is24WithNonZero) { return new FormError('Time.errorInvalidTime'); } return undefined; } Time._supportsEufemiaSpacingProps = true; export default Time; //# sourceMappingURL=Time.js.map