UNPKG

@geneui/components

Version:

The Gene UI components library designed for BI tools

317 lines (308 loc) 9.73 kB
import { _ as _extends } from '../_rollupPluginBabelHelpers-e8fb2e5c.js'; import React__default, { forwardRef, useCallback, useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import { n as noop } from '../index-a0e4e333.js'; import useMount from '../hooks/useMount.js'; import '../configs-00612ce0.js'; import DatePickerInput from '../DatePickerInput/index.js'; import { d as dayjsWithPlugins, v as validateDatePickerField } from '../dateValidation-67caec66.js'; import { c as checkTimeValidation } from '../checkTimeValidation-e56771be.js'; import { g as getBrowserDateFormat } from '../localization-4ba17032.js'; import 'react-dom'; import '../_commonjsHelpers-24198af3.js'; import '../style-inject.es-746bb8ed.js'; import '../index-031ff73c.js'; import '../hooks/useClick.js'; import '../hooks/useKeyDown.js'; import '../hooks/useDeviceType.js'; import '../hooks/useWindowSize.js'; import '../hooks/useDebounce.js'; import '../index-08898b29.js'; import '../index-122432cd.js'; import '../hooks/useClickOutside.js'; import '../Scrollbar/index.js'; import '../GeneUIProvider/index.js'; import '../debounce-4419bc2f.js'; import '../ExtendedInput/index.js'; import '../useEllipsisDetection-4d997d5d.js'; import '../Icon/index.js'; import '../SuggestionList/index.js'; import '../config-1053d64d.js'; import '../callAfterDelay-7272faca.js'; import '../index-6d7e99cd.js'; import '../tslib.es6-f211516f.js'; import '../DatePicker/index.js'; import '../guid-8ddf77b3.js'; import '../Button/index.js'; const nonLettersRegex = /[\W_]+/g; const hourFormats = ['H', 'HH', 'h', 'hh']; const minuteFormats = ['m', 'mm']; const secondFormats = ['s', 'ss']; const getFormatSeparator = format => format[format.search(nonLettersRegex)]; /* * Splitting time to { format, value } object * For checking is value fit format * Formats are taken from day.js date formats list * */ function splitTimeToObjects(dateParts, formatParts) { const hour = {}; const minute = {}; const second = {}; formatParts.forEach((item, index) => { if (hourFormats.includes(item)) { hour.value = dateParts[index]; hour.format = item; } else if (minuteFormats.includes(item)) { minute.value = dateParts[index]; minute.format = item; } else if (secondFormats.includes(item)) { second.value = dateParts[index]; second.format = item; } }); return { hour, minute, second }; } const isHourInRightFormat = _ref => { let { value, format } = _ref; return value && ((format === 'H' || format === 'h') && value.length <= 2 && Number(value[0]) !== 0 || (format === 'HH' || format === 'hh') && value.length === 2); }; const isMinuteInRightFormat = _ref2 => { let { value, format } = _ref2; return value && (format === 'm' && value.length <= 2 && (value.length !== 2 || Number(value[0]) !== 0) || format === 'mm' && value.length === 2); }; const isSecondInRightFormat = _ref3 => { let { value, format } = _ref3; return !format || value && (format === 's' && value.length <= 2 && (value.length !== 2 || Number(value[0]) !== 0) || format === 'ss' && value.length === 2); }; const checkTimeFormat = _ref4 => { let { hour, minute, second } = _ref4; return isHourInRightFormat(hour) && isMinuteInRightFormat(minute) && isSecondInRightFormat(second); }; function validateTimeField(value, required, isValid, min, max, format) { const time = value ? dayjsWithPlugins(value).format(format).split(' ')[1] : ''; const timeFormat = format ? format.split(' ')[1] : ''; const date = dayjsWithPlugins(value); const separator = getFormatSeparator(timeFormat); const dateParts = time.split(separator); const formatParts = timeFormat.split(separator); const timeObject = splitTimeToObjects(dateParts, formatParts); const isValidFormat = checkTimeFormat(timeObject); const isValidDate = checkTimeValidation(timeObject); const isBefore = !max || date.isBefore(dayjsWithPlugins(max, format)); const isAfter = !min || date.isAfter(dayjsWithPlugins(min, format)); if (!time.length) { return required ? { key: 'required', isValid: false } : { key: null, isValid: true }; } if (!isValidFormat) return { key: 'isValidFormat', isValid: false }; if (!isValidDate) return { key: 'isValidDate', isValid: false }; if (!isBefore) return { key: 'isBefore', isValid: false }; if (!isAfter) return { key: 'isAfter', isValid: false }; if (!isValid) return { key: 'customValidation', isValid: false }; return { key: null, isValid: true }; } function validateTimePickerField(required, isValid, min, max, format) { let value = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : ''; if (typeof value === 'string') { return validateTimeField(value, required, isValid, min, max, format); } const [start, end] = value; const startDateValidation = validateTimeField(start || '', required, isValid, min, max, format); const endDateValidation = validateTimeField(end || '', required, isValid, min, max, format); const isRangeInvalid = dayjsWithPlugins(start, format).isAfter(dayjsWithPlugins(end, format)); if (!startDateValidation.isValid) return startDateValidation; if (!endDateValidation.isValid) return endDateValidation; if (isRangeInvalid) return { key: 'isValidRange', isValid: false }; return { key: null, isValid: true }; } const EMPTY_OBJECT = {}; const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => { let { onChange, value, isValid, required, isFieldValid, withRange, min, max, format, withTime, onBlur, forceAllowValidation, ...restProps } = _ref; const localValue = value || (withRange ? [null, null] : null); const checkValidation = useCallback(value => { const validFormat = format || getBrowserDateFormat(!!withTime); // We need null, because other values `dayjs` turns to valid date const formatted = withRange ? [value[0] || null, value[1] || null] : value; const { isValid: isValidDate, key: dateKey } = validateDatePickerField(formatted, required, isValid, min, max, validFormat); const { isValid: isValidTime = true, key: timeKey = null } = !withTime || !validFormat.split(' ')[1] ? EMPTY_OBJECT : validateTimePickerField(required, isValid, min, max, validFormat, formatted); return { isValid: isValidDate && isValidTime, key: dateKey || timeKey || null }; }, [required, isValid, min, max, format, withTime, withRange]); const [validationState, setValidationState] = useState(true); const [allowValidation, setAllowValidation] = useState(false); const handleChange = useCallback(value => { const validation = checkValidation(value); setValidationState(validation.isValid); onChange && onChange(value, validation.isValid, validation.key); }, [checkValidation, onChange]); // we use this because need to show field validation after onBlur const onClickOutside = useCallback(() => setAllowValidation(true), []); const handleBlur = useCallback(e => { setAllowValidation(true); onBlur(e); }, [onBlur]); useEffect(() => { setValidationState(checkValidation(localValue).isValid); }, [localValue, required, min, max]); // need this for handling user's `isValid` prop useEffect(() => { setValidationState(isValid); }, [isValid]); // call function when validation state changes useEffect(() => { isFieldValid(validationState); }, [validationState]); // set Allow validation true if submit button clicked useEffect(() => { forceAllowValidation && setAllowValidation(true); }, [forceAllowValidation]); useMount(() => setValidationState(checkValidation(localValue).isValid)); return withRange ? /*#__PURE__*/React__default.createElement(DatePickerInput.WithRange, _extends({ ref: ref, min: min, max: max, value: value, isValid: !allowValidation || validationState, onChange: handleChange, format: format, onClickOutside: onClickOutside, withTime: withTime, required: required, onBlur: handleBlur }, restProps)) : /*#__PURE__*/React__default.createElement(DatePickerInput, _extends({ ref: ref, min: min, max: max, value: value, isValid: !allowValidation || validationState, onChange: handleChange, format: format, onClickOutside: onClickOutside, required: required, onBlur: handleBlur }, restProps)); }); DatePicker.propTypes = { /** * Value for date picker */ value: PropTypes.oneOfType([PropTypes.object, PropTypes.arrayOf(PropTypes.object)]), /** * Callback fires when date changes */ onChange: PropTypes.func, /** * Callback fires when input blur */ onBlur: PropTypes.func, /** * Define is field required or no. */ required: PropTypes.bool, /** * Define is range picker with time or no */ withTime: PropTypes.bool, /** * Define is single date picker or with range */ withRange: PropTypes.bool, /** * Callback fires when field validation state changes */ isFieldValid: PropTypes.func, /** * Additional validation state */ isValid: PropTypes.bool, /** * Minimum date value */ min: PropTypes.string, /** * Maximum date value */ max: PropTypes.string, /** * Date format */ format: PropTypes.string, /** * Allow validation without onBlur, validate field when mount */ forceAllowValidation: PropTypes.bool }; DatePicker.defaultProps = { isValid: true, onBlur: noop, isFieldValid: noop }; export { DatePicker as default };