@geneui/components
Version:
The Gene UI components library designed for BI tools
317 lines (308 loc) • 9.73 kB
JavaScript
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 };