UNPKG

@geneui/components

Version:

The Gene UI components library designed for BI tools

205 lines (197 loc) 6.02 kB
import { _ as _extends } from '../_rollupPluginBabelHelpers-e8fb2e5c.js'; import React__default, { forwardRef, useState, useCallback, 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 ExtendedInput from '../ExtendedInput/index.js'; import '../dateValidation-67caec66.js'; import '../_commonjsHelpers-24198af3.js'; import 'react-dom'; import '../index-031ff73c.js'; import '../hooks/useDeviceType.js'; import '../hooks/useWindowSize.js'; import '../hooks/useDebounce.js'; import '../useEllipsisDetection-4d997d5d.js'; import '../Icon/index.js'; import '../style-inject.es-746bb8ed.js'; import '../SuggestionList/index.js'; import '../hooks/useKeyDown.js'; import '../hooks/useClickOutside.js'; import '../config-1053d64d.js'; import '../Scrollbar/index.js'; import '../callAfterDelay-7272faca.js'; import '../index-6d7e99cd.js'; import '../tslib.es6-f211516f.js'; import '../GeneUIProvider/index.js'; const validateMin = (value, min) => value >= min; const validateMax = (value, max) => value <= max; const validateFloat = (value, precisionMin, precisionMax) => { const decimalPlaces = (value.split('.')[1] || []).length; if (precisionMax && decimalPlaces > precisionMax) return false; return true; }; function checkValidation(required, isValid, min, max, numberType, precisionMin, precisionMax) { let value = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : ''; const numberedValue = Number(value); if (isValid === false) return { key: 'customValidation', isValid: false }; if (numberType === 'integer' && !Number.isInteger(numberedValue)) return { key: 'isInteger', isValid: false }; if (numberType === 'float' && !validateFloat(value, precisionMin, precisionMax)) return { key: 'isFloat', isValid: false }; if (min != null && value && !validateMin(numberedValue, min)) return { key: 'min', isValid: false }; if (max != null && value && !validateMax(numberedValue, max)) return { key: 'max', isValid: false }; if (required && !value.length) return { key: 'required', isValid: false }; return { key: null, isValid: true }; } const NumberInput = /*#__PURE__*/forwardRef((props, ref) => { const { onBlur, required, isValid, numberType, precisionMin, precisionMax, min, max, onChange, value, isFieldValid, forceAllowValidation, forceValidateDuringChange, ...restProps } = props; const isControlled = 'value' in props && typeof value !== 'undefined'; const [validationState, setValidationState] = useState(true); const [allowValidation, setAllowValidation] = useState(false); const validate = useCallback(() => checkValidation(required, isValid, min, max, numberType, precisionMin, precisionMax, value || '').isValid, [required, isValid, min, max, value, numberType, precisionMin, precisionMax]); const handleChange = useCallback(e => { const { value } = e.target; const validation = checkValidation(required, isValid, min, max, numberType, precisionMin, precisionMax, value); setValidationState(validation.isValid); onChange(e, validation.isValid, validation.key); forceValidateDuringChange && setAllowValidation(true); }, [onChange, min, max, required, isValid, numberType, precisionMin, precisionMax, forceValidateDuringChange]); // we use this because need to show field validation after onBlur const handleBlur = useCallback(e => { const { value, validity } = e.target; if (validity.badInput && !value.length) { e.target.value = ''; } onBlur(e); setAllowValidation(true); }, [onBlur]); useEffect(() => { isControlled && setValidationState(validate()); }, [isControlled, validate]); // this for handling required prop changes useEffect(() => { setValidationState(validate()); }, [required]); // 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(validate())); return /*#__PURE__*/React__default.createElement(ExtendedInput, _extends({ min: min, max: max, ref: ref, value: value, isValid: !allowValidation || validationState, onChange: handleChange, onBlur: handleBlur, required: required, type: "number" }, restProps)); }); NumberInput.propTypes = { /** * Maximum value */ min: PropTypes.number, /** * Minimum value */ max: PropTypes.number, /** * Value for number field */ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), /** * Callback fires when field changes */ onChange: PropTypes.func, /** * Callback fires when input loose focus */ onBlur: PropTypes.func, /** * Callback fires when field validation state changes */ isFieldValid: PropTypes.func, /** * Additional validation state */ isValid: PropTypes.bool, /** * Allow validation without onBlur, validate field when mount */ forceAllowValidation: PropTypes.bool, /** * Define number type */ numberType: PropTypes.oneOf(['integer', 'float']), /** * Precision minimum count */ precisionMin: PropTypes.number, /** * Precision maximum count */ precisionMax: PropTypes.number, /** * We use this props if we need to show validation of a field during onChange */ forceValidateDuringChange: PropTypes.bool }; NumberInput.defaultProps = { isValid: true, precisionMin: 0, isFieldValid: noop, onChange: noop, onBlur: noop }; export { NumberInput as default };