envoc-form 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/AddressInput/index.js +2 -1
- package/es/DatePickerInput/DatePickerInput.js +1 -1
- package/es/FileInput/index.js +2 -1
- package/es/Form/index.js +3 -1
- package/es/FormInput/FormInput.js +6 -0
- package/es/MoneyFormattedInput/MoneyFormattedInput.js +106 -0
- package/es/MoneyFormattedInput/index.js +2 -0
- package/es/index.js +8 -3
- package/es/validators/validators.js +2 -2
- package/lib/AddressInput/index.js +13 -3
- package/lib/DatePickerInput/DatePickerInput.js +2 -2
- package/lib/FileInput/index.js +9 -1
- package/lib/Form/index.js +16 -0
- package/lib/FormInput/FormInput.js +7 -0
- package/lib/MoneyFormattedInput/MoneyFormattedInput.js +126 -0
- package/lib/MoneyFormattedInput/index.js +15 -0
- package/lib/index.js +90 -2
- package/lib/validators/validators.js +2 -2
- package/package.json +3 -2
- package/src/AddressInput/index.js +2 -1
- package/src/DatePickerInput/DatePickerInput.js +1 -1
- package/src/FileInput/index.js +2 -1
- package/src/Form/index.js +9 -1
- package/src/FormInput/FormInput.js +3 -0
- package/src/MoneyFormattedInput/MoneyFormattedInput.js +115 -0
- package/src/MoneyFormattedInput/index.js +3 -0
- package/src/index.js +27 -2
- package/src/validators/validators.js +2 -2
package/es/AddressInput/index.js
CHANGED
@@ -14,7 +14,7 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
|
|
14
14
|
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
15
15
|
|
16
16
|
import React from 'react';
|
17
|
-
import DatePicker from 'react-date-picker';
|
17
|
+
import DatePicker from 'react-date-picker/dist/entry.nostyle';
|
18
18
|
import parseISO from 'date-fns/parseISO';
|
19
19
|
import classnames from 'classnames';
|
20
20
|
var dateOnlyRegex = /^\d{4}-\d{2}-\d{2}$/;
|
package/es/FileInput/index.js
CHANGED
package/es/Form/index.js
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
import FocusError from './FocusError';
|
1
2
|
import Form from './Form';
|
3
|
+
import FormBasedPreventNavigation from './FormBasedPreventNavigation';
|
2
4
|
import ServerErrorContext from './ServerErrorContext';
|
3
|
-
export { Form as default, ServerErrorContext };
|
5
|
+
export { Form as default, ServerErrorContext, FocusError, FormBasedPreventNavigation };
|
@@ -19,6 +19,7 @@ import FormGroupWrapper from '../FormGroupWrapper';
|
|
19
19
|
import DatePickerInput from '../DatePickerInput';
|
20
20
|
import ReactSelectField from '../ReactSelectField';
|
21
21
|
import useStandardFormInput from '../useStandardFormInput';
|
22
|
+
import { MoneyFormattedInput } from '../MoneyFormattedInput';
|
22
23
|
import { FileInput, DropzoneFileInput } from '../FileInput';
|
23
24
|
export default function FormInput(props) {
|
24
25
|
var _useStandardFormInput = useStandardFormInput(props),
|
@@ -81,6 +82,11 @@ function StandardFieldGroup(props) {
|
|
81
82
|
Component: TextAreaInput
|
82
83
|
}));
|
83
84
|
|
85
|
+
case 'moneyFormatted':
|
86
|
+
return /*#__PURE__*/React.createElement(FormGroupWrapper, _extends({}, props, {
|
87
|
+
Component: MoneyFormattedInput
|
88
|
+
}));
|
89
|
+
|
84
90
|
default:
|
85
91
|
return /*#__PURE__*/React.createElement(FormGroupWrapper, _extends({}, props, {
|
86
92
|
Component: DefaultInput
|
@@ -0,0 +1,106 @@
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
2
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
3
|
+
import { useField } from 'formik';
|
4
|
+
import debounce from 'lodash/debounce';
|
5
|
+
import classNames from 'classnames'; // Money input that will format the value to always have commas, a single decimal, and
|
6
|
+
// exactly two digits after the decimal. This happens after a delay (using debounce).
|
7
|
+
|
8
|
+
export default function MoneyFormattedInput(_ref) {
|
9
|
+
var name = _ref.name,
|
10
|
+
onBlur = _ref.onBlur,
|
11
|
+
onChange = _ref.onChange,
|
12
|
+
classname = _ref.classname,
|
13
|
+
_ref$disabled = _ref.disabled,
|
14
|
+
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
15
|
+
_ref$debounceTimer = _ref.debounceTimer,
|
16
|
+
debounceTimer = _ref$debounceTimer === void 0 ? 1500 : _ref$debounceTimer,
|
17
|
+
meta = _ref.meta;
|
18
|
+
|
19
|
+
// The displayed state and formik state are two seperate values that we handle
|
20
|
+
var _useState = useState(''),
|
21
|
+
_useState2 = _slicedToArray(_useState, 2),
|
22
|
+
inputValue = _useState2[0],
|
23
|
+
setInputValue = _useState2[1];
|
24
|
+
|
25
|
+
var _useField = useField(name),
|
26
|
+
_useField2 = _slicedToArray(_useField, 1),
|
27
|
+
formikValue = _useField2[0].value;
|
28
|
+
|
29
|
+
var handleChangeDebounce = useMemo(function () {
|
30
|
+
return debounce(debouncedUpdateInput, debounceTimer);
|
31
|
+
|
32
|
+
function debouncedUpdateInput(value) {
|
33
|
+
var result = formatToCurrency(value);
|
34
|
+
setInputValue(result !== null && result !== void 0 ? result : ''); // sets value in formik
|
35
|
+
|
36
|
+
onChange(result !== null && result !== void 0 ? result : '');
|
37
|
+
onBlur();
|
38
|
+
}
|
39
|
+
}, [onBlur, onChange]); // Format first render
|
40
|
+
|
41
|
+
useEffect(function () {
|
42
|
+
var formattedFormikValue = formatToCurrency(formikValue);
|
43
|
+
setInputValue(formattedFormikValue !== null && formattedFormikValue !== void 0 ? formattedFormikValue : '');
|
44
|
+
}, [formikValue]);
|
45
|
+
|
46
|
+
function handleChange(e) {
|
47
|
+
var onlyNumbersDecimalComma = e.target.value.toString().replace(/[^.,0-9]/g, '');
|
48
|
+
setInputValue(onlyNumbersDecimalComma);
|
49
|
+
handleChangeDebounce(onlyNumbersDecimalComma);
|
50
|
+
}
|
51
|
+
|
52
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
53
|
+
className: "input-group"
|
54
|
+
}, /*#__PURE__*/React.createElement("div", {
|
55
|
+
className: "input-group-prepend"
|
56
|
+
}, /*#__PURE__*/React.createElement("span", {
|
57
|
+
className: "input-group-text"
|
58
|
+
}, "$")), /*#__PURE__*/React.createElement("input", {
|
59
|
+
name: name,
|
60
|
+
type: "text",
|
61
|
+
value: inputValue,
|
62
|
+
onChange: handleChange,
|
63
|
+
onBlur: onBlur,
|
64
|
+
disabled: disabled,
|
65
|
+
className: classNames(classname, meta.error === 'Required' ? 'is-invalid' : '', 'react-select-input money-input form-control')
|
66
|
+
})));
|
67
|
+
}
|
68
|
+
|
69
|
+
function formatToCurrency(value) {
|
70
|
+
if (value === null || value === undefined) {
|
71
|
+
return null;
|
72
|
+
} // 'value' is sometimes a number on first render
|
73
|
+
|
74
|
+
|
75
|
+
var onlyNumbersDecimal = value.toString().replace(/[^.0-9]/g, '');
|
76
|
+
|
77
|
+
if (!onlyNumbersDecimal) {
|
78
|
+
return null;
|
79
|
+
}
|
80
|
+
|
81
|
+
var result = new Intl.NumberFormat('en-US', {
|
82
|
+
style: 'decimal',
|
83
|
+
minimumSignificantDigits: 2,
|
84
|
+
minimumFractionDigits: 2
|
85
|
+
}).format(parseFloat(onlyNumbersDecimal));
|
86
|
+
result = formatTwoDecimalPlaces(result);
|
87
|
+
return result;
|
88
|
+
}
|
89
|
+
|
90
|
+
function formatTwoDecimalPlaces(value) {
|
91
|
+
var decimalIndex = value.indexOf('.'); // If the string doesn't contain a decimal OR
|
92
|
+
// the string contains a single '.' with nothing to the right of the decimal -> append '.00'
|
93
|
+
// Reason: parseFloat will remove '.00' from whole numbers (ex. 350.00 -> 350)
|
94
|
+
|
95
|
+
if (!value.includes('.')) {
|
96
|
+
return value.concat('.00');
|
97
|
+
} // If 2 or more characters to the right of the decimal
|
98
|
+
else if (!!value.charAt(decimalIndex + 2)) {
|
99
|
+
return value.substring(0, decimalIndex + 3);
|
100
|
+
} // If only 1 character to the right of the decimal
|
101
|
+
else if (!!value.charAt(decimalIndex + 1)) {
|
102
|
+
return value.substring(0, decimalIndex + 2).concat('0');
|
103
|
+
}
|
104
|
+
|
105
|
+
return value;
|
106
|
+
}
|
package/es/index.js
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
import * as normalizers from './normalizers';
|
2
2
|
import { BoolInput, InlineBoolInput } from './BoolInput';
|
3
3
|
import { InlineMoneyInput, MoneyInput } from './MoneyInput';
|
4
|
-
import
|
4
|
+
import { MoneyFormattedInput } from './MoneyFormattedInput';
|
5
|
+
import AddressInput, { UsStates } from './AddressInput';
|
5
6
|
import ConfirmBaseForm from './ConfirmBaseForm';
|
6
7
|
import ConfirmDeleteForm from './ConfirmDeleteForm';
|
8
|
+
import DatePickerInput from './DatePickerInput';
|
7
9
|
import ErrorScrollTarget from './ErrorScrollTarget';
|
8
|
-
import
|
10
|
+
import { FileInput, DropzoneFileInput, DefaultFileList } from './FileInput';
|
11
|
+
import Form, { ServerErrorContext, FocusError, FormBasedPreventNavigation } from './Form';
|
9
12
|
import FormGroup from './FormGroup';
|
10
13
|
import FormGroupWrapper from './FormGroupWrapper';
|
11
14
|
import FormInput from './FormInput';
|
@@ -17,4 +20,6 @@ import StandardFormActions from './StandardFormActions';
|
|
17
20
|
import SubmitFormButton from './SubmitFormButton';
|
18
21
|
import useStandardFormInput from './useStandardFormInput';
|
19
22
|
import validators from './validators';
|
20
|
-
|
23
|
+
import ReactSelectField, { customStyles as customReactSelectFieldStyles, overrideTheme as overrideReactSelectFieldStyles } from './ReactSelectField';
|
24
|
+
import NestedFormFieldContext from './NestedFormFieldContext';
|
25
|
+
export { AddressInput, UsStates, BoolInput, ConfirmBaseForm, ConfirmDeleteForm, DatePickerInput, ErrorScrollTarget, FileInput, DropzoneFileInput, DefaultFileList, Form, FormGroup, FormGroupWrapper, FormInput, FormInputArray, FormSection, IconInput, InlineBoolInput, InlineFormInput, InlineMoneyInput, MoneyInput, MoneyFormattedInput, normalizers, StandardFormActions, SubmitFormButton, useStandardFormInput, validators, ServerErrorContext, FocusError, FormBasedPreventNavigation, ReactSelectField, customReactSelectFieldStyles, overrideReactSelectFieldStyles, NestedFormFieldContext };
|
@@ -57,7 +57,7 @@ export function minCount(count) {
|
|
57
57
|
}
|
58
58
|
export var maxValue = function maxValue(value) {
|
59
59
|
return function (inputValue) {
|
60
|
-
if (inputValue && value) {
|
60
|
+
if (inputValue != null && value != null) {
|
61
61
|
return inputValue <= value ? undefined : "Maximum value ".concat(value, " exceeded");
|
62
62
|
} else {
|
63
63
|
return undefined;
|
@@ -66,7 +66,7 @@ export var maxValue = function maxValue(value) {
|
|
66
66
|
};
|
67
67
|
export var minValue = function minValue(value) {
|
68
68
|
return function (inputValue) {
|
69
|
-
if (inputValue && value) {
|
69
|
+
if (inputValue != null && value != null) {
|
70
70
|
return inputValue >= value ? undefined : "Minimum value ".concat(value, " not met");
|
71
71
|
} else {
|
72
72
|
return undefined;
|
@@ -5,9 +5,19 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
6
6
|
value: true
|
7
7
|
});
|
8
|
-
exports
|
8
|
+
Object.defineProperty(exports, "default", {
|
9
|
+
enumerable: true,
|
10
|
+
get: function get() {
|
11
|
+
return _AddressInput["default"];
|
12
|
+
}
|
13
|
+
});
|
14
|
+
Object.defineProperty(exports, "UsStates", {
|
15
|
+
enumerable: true,
|
16
|
+
get: function get() {
|
17
|
+
return _UsStates["default"];
|
18
|
+
}
|
19
|
+
});
|
9
20
|
|
10
21
|
var _AddressInput = _interopRequireDefault(require("./AddressInput"));
|
11
22
|
|
12
|
-
var
|
13
|
-
exports["default"] = _default;
|
23
|
+
var _UsStates = _interopRequireDefault(require("./UsStates"));
|
@@ -27,7 +27,7 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
|
|
27
27
|
|
28
28
|
var _react = _interopRequireDefault(require("react"));
|
29
29
|
|
30
|
-
var
|
30
|
+
var _entry = _interopRequireDefault(require("react-date-picker/dist/entry.nostyle"));
|
31
31
|
|
32
32
|
var _parseISO = _interopRequireDefault(require("date-fns/parseISO"));
|
33
33
|
|
@@ -96,7 +96,7 @@ var DatePickerInput = /*#__PURE__*/function (_React$Component) {
|
|
96
96
|
}
|
97
97
|
|
98
98
|
var parsedValue = value ? (0, _parseISO["default"])(value) : null;
|
99
|
-
return /*#__PURE__*/_react["default"].createElement(
|
99
|
+
return /*#__PURE__*/_react["default"].createElement(_entry["default"], (0, _extends2["default"])({
|
100
100
|
className: (0, _classnames["default"])('form-control', className),
|
101
101
|
onCalendarOpen: this.onCalendarOpen
|
102
102
|
}, rest, {
|
package/lib/FileInput/index.js
CHANGED
@@ -17,7 +17,15 @@ Object.defineProperty(exports, "DropzoneFileInput", {
|
|
17
17
|
return _DropzoneFileInput["default"];
|
18
18
|
}
|
19
19
|
});
|
20
|
+
Object.defineProperty(exports, "DefaultFileList", {
|
21
|
+
enumerable: true,
|
22
|
+
get: function get() {
|
23
|
+
return _DefaultFileList["default"];
|
24
|
+
}
|
25
|
+
});
|
20
26
|
|
21
27
|
var _FileInput = _interopRequireDefault(require("./FileInput"));
|
22
28
|
|
23
|
-
var _DropzoneFileInput = _interopRequireDefault(require("./DropzoneFileInput"));
|
29
|
+
var _DropzoneFileInput = _interopRequireDefault(require("./DropzoneFileInput"));
|
30
|
+
|
31
|
+
var _DefaultFileList = _interopRequireDefault(require("./DefaultFileList"));
|
package/lib/Form/index.js
CHANGED
@@ -5,12 +5,24 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
6
6
|
value: true
|
7
7
|
});
|
8
|
+
Object.defineProperty(exports, "FocusError", {
|
9
|
+
enumerable: true,
|
10
|
+
get: function get() {
|
11
|
+
return _FocusError["default"];
|
12
|
+
}
|
13
|
+
});
|
8
14
|
Object.defineProperty(exports, "default", {
|
9
15
|
enumerable: true,
|
10
16
|
get: function get() {
|
11
17
|
return _Form["default"];
|
12
18
|
}
|
13
19
|
});
|
20
|
+
Object.defineProperty(exports, "FormBasedPreventNavigation", {
|
21
|
+
enumerable: true,
|
22
|
+
get: function get() {
|
23
|
+
return _FormBasedPreventNavigation["default"];
|
24
|
+
}
|
25
|
+
});
|
14
26
|
Object.defineProperty(exports, "ServerErrorContext", {
|
15
27
|
enumerable: true,
|
16
28
|
get: function get() {
|
@@ -18,6 +30,10 @@ Object.defineProperty(exports, "ServerErrorContext", {
|
|
18
30
|
}
|
19
31
|
});
|
20
32
|
|
33
|
+
var _FocusError = _interopRequireDefault(require("./FocusError"));
|
34
|
+
|
21
35
|
var _Form = _interopRequireDefault(require("./Form"));
|
22
36
|
|
37
|
+
var _FormBasedPreventNavigation = _interopRequireDefault(require("./FormBasedPreventNavigation"));
|
38
|
+
|
23
39
|
var _ServerErrorContext = _interopRequireDefault(require("./ServerErrorContext"));
|
@@ -38,6 +38,8 @@ var _ReactSelectField = _interopRequireDefault(require("../ReactSelectField"));
|
|
38
38
|
|
39
39
|
var _useStandardFormInput3 = _interopRequireDefault(require("../useStandardFormInput"));
|
40
40
|
|
41
|
+
var _MoneyFormattedInput = require("../MoneyFormattedInput");
|
42
|
+
|
41
43
|
var _FileInput = require("../FileInput");
|
42
44
|
|
43
45
|
var _excluded = ["className", "meta", "helpText"],
|
@@ -109,6 +111,11 @@ function StandardFieldGroup(props) {
|
|
109
111
|
Component: TextAreaInput
|
110
112
|
}));
|
111
113
|
|
114
|
+
case 'moneyFormatted':
|
115
|
+
return /*#__PURE__*/_react["default"].createElement(_FormGroupWrapper["default"], (0, _extends2["default"])({}, props, {
|
116
|
+
Component: _MoneyFormattedInput.MoneyFormattedInput
|
117
|
+
}));
|
118
|
+
|
112
119
|
default:
|
113
120
|
return /*#__PURE__*/_react["default"].createElement(_FormGroupWrapper["default"], (0, _extends2["default"])({}, props, {
|
114
121
|
Component: DefaultInput
|
@@ -0,0 +1,126 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
4
|
+
|
5
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
6
|
+
|
7
|
+
Object.defineProperty(exports, "__esModule", {
|
8
|
+
value: true
|
9
|
+
});
|
10
|
+
exports["default"] = MoneyFormattedInput;
|
11
|
+
|
12
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
13
|
+
|
14
|
+
var _react = _interopRequireWildcard(require("react"));
|
15
|
+
|
16
|
+
var _formik = require("formik");
|
17
|
+
|
18
|
+
var _debounce = _interopRequireDefault(require("lodash/debounce"));
|
19
|
+
|
20
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
21
|
+
|
22
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
23
|
+
|
24
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
25
|
+
|
26
|
+
// Money input that will format the value to always have commas, a single decimal, and
|
27
|
+
// exactly two digits after the decimal. This happens after a delay (using debounce).
|
28
|
+
function MoneyFormattedInput(_ref) {
|
29
|
+
var name = _ref.name,
|
30
|
+
onBlur = _ref.onBlur,
|
31
|
+
onChange = _ref.onChange,
|
32
|
+
classname = _ref.classname,
|
33
|
+
_ref$disabled = _ref.disabled,
|
34
|
+
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
35
|
+
_ref$debounceTimer = _ref.debounceTimer,
|
36
|
+
debounceTimer = _ref$debounceTimer === void 0 ? 1500 : _ref$debounceTimer,
|
37
|
+
meta = _ref.meta;
|
38
|
+
|
39
|
+
// The displayed state and formik state are two seperate values that we handle
|
40
|
+
var _useState = (0, _react.useState)(''),
|
41
|
+
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
|
42
|
+
inputValue = _useState2[0],
|
43
|
+
setInputValue = _useState2[1];
|
44
|
+
|
45
|
+
var _useField = (0, _formik.useField)(name),
|
46
|
+
_useField2 = (0, _slicedToArray2["default"])(_useField, 1),
|
47
|
+
formikValue = _useField2[0].value;
|
48
|
+
|
49
|
+
var handleChangeDebounce = (0, _react.useMemo)(function () {
|
50
|
+
return (0, _debounce["default"])(debouncedUpdateInput, debounceTimer);
|
51
|
+
|
52
|
+
function debouncedUpdateInput(value) {
|
53
|
+
var result = formatToCurrency(value);
|
54
|
+
setInputValue(result !== null && result !== void 0 ? result : ''); // sets value in formik
|
55
|
+
|
56
|
+
onChange(result !== null && result !== void 0 ? result : '');
|
57
|
+
onBlur();
|
58
|
+
}
|
59
|
+
}, [onBlur, onChange]); // Format first render
|
60
|
+
|
61
|
+
(0, _react.useEffect)(function () {
|
62
|
+
var formattedFormikValue = formatToCurrency(formikValue);
|
63
|
+
setInputValue(formattedFormikValue !== null && formattedFormikValue !== void 0 ? formattedFormikValue : '');
|
64
|
+
}, [formikValue]);
|
65
|
+
|
66
|
+
function handleChange(e) {
|
67
|
+
var onlyNumbersDecimalComma = e.target.value.toString().replace(/[^.,0-9]/g, '');
|
68
|
+
setInputValue(onlyNumbersDecimalComma);
|
69
|
+
handleChangeDebounce(onlyNumbersDecimalComma);
|
70
|
+
}
|
71
|
+
|
72
|
+
return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("div", {
|
73
|
+
className: "input-group"
|
74
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
75
|
+
className: "input-group-prepend"
|
76
|
+
}, /*#__PURE__*/_react["default"].createElement("span", {
|
77
|
+
className: "input-group-text"
|
78
|
+
}, "$")), /*#__PURE__*/_react["default"].createElement("input", {
|
79
|
+
name: name,
|
80
|
+
type: "text",
|
81
|
+
value: inputValue,
|
82
|
+
onChange: handleChange,
|
83
|
+
onBlur: onBlur,
|
84
|
+
disabled: disabled,
|
85
|
+
className: (0, _classnames["default"])(classname, meta.error === 'Required' ? 'is-invalid' : '', 'react-select-input money-input form-control')
|
86
|
+
})));
|
87
|
+
}
|
88
|
+
|
89
|
+
function formatToCurrency(value) {
|
90
|
+
if (value === null || value === undefined) {
|
91
|
+
return null;
|
92
|
+
} // 'value' is sometimes a number on first render
|
93
|
+
|
94
|
+
|
95
|
+
var onlyNumbersDecimal = value.toString().replace(/[^.0-9]/g, '');
|
96
|
+
|
97
|
+
if (!onlyNumbersDecimal) {
|
98
|
+
return null;
|
99
|
+
}
|
100
|
+
|
101
|
+
var result = new Intl.NumberFormat('en-US', {
|
102
|
+
style: 'decimal',
|
103
|
+
minimumSignificantDigits: 2,
|
104
|
+
minimumFractionDigits: 2
|
105
|
+
}).format(parseFloat(onlyNumbersDecimal));
|
106
|
+
result = formatTwoDecimalPlaces(result);
|
107
|
+
return result;
|
108
|
+
}
|
109
|
+
|
110
|
+
function formatTwoDecimalPlaces(value) {
|
111
|
+
var decimalIndex = value.indexOf('.'); // If the string doesn't contain a decimal OR
|
112
|
+
// the string contains a single '.' with nothing to the right of the decimal -> append '.00'
|
113
|
+
// Reason: parseFloat will remove '.00' from whole numbers (ex. 350.00 -> 350)
|
114
|
+
|
115
|
+
if (!value.includes('.')) {
|
116
|
+
return value.concat('.00');
|
117
|
+
} // If 2 or more characters to the right of the decimal
|
118
|
+
else if (!!value.charAt(decimalIndex + 2)) {
|
119
|
+
return value.substring(0, decimalIndex + 3);
|
120
|
+
} // If only 1 character to the right of the decimal
|
121
|
+
else if (!!value.charAt(decimalIndex + 1)) {
|
122
|
+
return value.substring(0, decimalIndex + 2).concat('0');
|
123
|
+
}
|
124
|
+
|
125
|
+
return value;
|
126
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
4
|
+
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
6
|
+
value: true
|
7
|
+
});
|
8
|
+
Object.defineProperty(exports, "MoneyFormattedInput", {
|
9
|
+
enumerable: true,
|
10
|
+
get: function get() {
|
11
|
+
return _MoneyFormattedInput["default"];
|
12
|
+
}
|
13
|
+
});
|
14
|
+
|
15
|
+
var _MoneyFormattedInput = _interopRequireDefault(require("./MoneyFormattedInput"));
|
package/lib/index.js
CHANGED
@@ -31,12 +31,24 @@ Object.defineProperty(exports, "MoneyInput", {
|
|
31
31
|
return _MoneyInput.MoneyInput;
|
32
32
|
}
|
33
33
|
});
|
34
|
+
Object.defineProperty(exports, "MoneyFormattedInput", {
|
35
|
+
enumerable: true,
|
36
|
+
get: function get() {
|
37
|
+
return _MoneyFormattedInput.MoneyFormattedInput;
|
38
|
+
}
|
39
|
+
});
|
34
40
|
Object.defineProperty(exports, "AddressInput", {
|
35
41
|
enumerable: true,
|
36
42
|
get: function get() {
|
37
43
|
return _AddressInput["default"];
|
38
44
|
}
|
39
45
|
});
|
46
|
+
Object.defineProperty(exports, "UsStates", {
|
47
|
+
enumerable: true,
|
48
|
+
get: function get() {
|
49
|
+
return _AddressInput.UsStates;
|
50
|
+
}
|
51
|
+
});
|
40
52
|
Object.defineProperty(exports, "ConfirmBaseForm", {
|
41
53
|
enumerable: true,
|
42
54
|
get: function get() {
|
@@ -49,18 +61,60 @@ Object.defineProperty(exports, "ConfirmDeleteForm", {
|
|
49
61
|
return _ConfirmDeleteForm["default"];
|
50
62
|
}
|
51
63
|
});
|
64
|
+
Object.defineProperty(exports, "DatePickerInput", {
|
65
|
+
enumerable: true,
|
66
|
+
get: function get() {
|
67
|
+
return _DatePickerInput["default"];
|
68
|
+
}
|
69
|
+
});
|
52
70
|
Object.defineProperty(exports, "ErrorScrollTarget", {
|
53
71
|
enumerable: true,
|
54
72
|
get: function get() {
|
55
73
|
return _ErrorScrollTarget["default"];
|
56
74
|
}
|
57
75
|
});
|
76
|
+
Object.defineProperty(exports, "FileInput", {
|
77
|
+
enumerable: true,
|
78
|
+
get: function get() {
|
79
|
+
return _FileInput.FileInput;
|
80
|
+
}
|
81
|
+
});
|
82
|
+
Object.defineProperty(exports, "DropzoneFileInput", {
|
83
|
+
enumerable: true,
|
84
|
+
get: function get() {
|
85
|
+
return _FileInput.DropzoneFileInput;
|
86
|
+
}
|
87
|
+
});
|
88
|
+
Object.defineProperty(exports, "DefaultFileList", {
|
89
|
+
enumerable: true,
|
90
|
+
get: function get() {
|
91
|
+
return _FileInput.DefaultFileList;
|
92
|
+
}
|
93
|
+
});
|
58
94
|
Object.defineProperty(exports, "Form", {
|
59
95
|
enumerable: true,
|
60
96
|
get: function get() {
|
61
97
|
return _Form["default"];
|
62
98
|
}
|
63
99
|
});
|
100
|
+
Object.defineProperty(exports, "ServerErrorContext", {
|
101
|
+
enumerable: true,
|
102
|
+
get: function get() {
|
103
|
+
return _Form.ServerErrorContext;
|
104
|
+
}
|
105
|
+
});
|
106
|
+
Object.defineProperty(exports, "FocusError", {
|
107
|
+
enumerable: true,
|
108
|
+
get: function get() {
|
109
|
+
return _Form.FocusError;
|
110
|
+
}
|
111
|
+
});
|
112
|
+
Object.defineProperty(exports, "FormBasedPreventNavigation", {
|
113
|
+
enumerable: true,
|
114
|
+
get: function get() {
|
115
|
+
return _Form.FormBasedPreventNavigation;
|
116
|
+
}
|
117
|
+
});
|
64
118
|
Object.defineProperty(exports, "FormGroup", {
|
65
119
|
enumerable: true,
|
66
120
|
get: function get() {
|
@@ -127,6 +181,30 @@ Object.defineProperty(exports, "validators", {
|
|
127
181
|
return _validators["default"];
|
128
182
|
}
|
129
183
|
});
|
184
|
+
Object.defineProperty(exports, "ReactSelectField", {
|
185
|
+
enumerable: true,
|
186
|
+
get: function get() {
|
187
|
+
return _ReactSelectField["default"];
|
188
|
+
}
|
189
|
+
});
|
190
|
+
Object.defineProperty(exports, "customReactSelectFieldStyles", {
|
191
|
+
enumerable: true,
|
192
|
+
get: function get() {
|
193
|
+
return _ReactSelectField.customStyles;
|
194
|
+
}
|
195
|
+
});
|
196
|
+
Object.defineProperty(exports, "overrideReactSelectFieldStyles", {
|
197
|
+
enumerable: true,
|
198
|
+
get: function get() {
|
199
|
+
return _ReactSelectField.overrideTheme;
|
200
|
+
}
|
201
|
+
});
|
202
|
+
Object.defineProperty(exports, "NestedFormFieldContext", {
|
203
|
+
enumerable: true,
|
204
|
+
get: function get() {
|
205
|
+
return _NestedFormFieldContext["default"];
|
206
|
+
}
|
207
|
+
});
|
130
208
|
exports.normalizers = void 0;
|
131
209
|
|
132
210
|
var normalizers = _interopRequireWildcard(require("./normalizers"));
|
@@ -137,15 +215,21 @@ var _BoolInput = require("./BoolInput");
|
|
137
215
|
|
138
216
|
var _MoneyInput = require("./MoneyInput");
|
139
217
|
|
140
|
-
var
|
218
|
+
var _MoneyFormattedInput = require("./MoneyFormattedInput");
|
219
|
+
|
220
|
+
var _AddressInput = _interopRequireWildcard(require("./AddressInput"));
|
141
221
|
|
142
222
|
var _ConfirmBaseForm = _interopRequireDefault(require("./ConfirmBaseForm"));
|
143
223
|
|
144
224
|
var _ConfirmDeleteForm = _interopRequireDefault(require("./ConfirmDeleteForm"));
|
145
225
|
|
226
|
+
var _DatePickerInput = _interopRequireDefault(require("./DatePickerInput"));
|
227
|
+
|
146
228
|
var _ErrorScrollTarget = _interopRequireDefault(require("./ErrorScrollTarget"));
|
147
229
|
|
148
|
-
var
|
230
|
+
var _FileInput = require("./FileInput");
|
231
|
+
|
232
|
+
var _Form = _interopRequireWildcard(require("./Form"));
|
149
233
|
|
150
234
|
var _FormGroup = _interopRequireDefault(require("./FormGroup"));
|
151
235
|
|
@@ -169,6 +253,10 @@ var _useStandardFormInput = _interopRequireDefault(require("./useStandardFormInp
|
|
169
253
|
|
170
254
|
var _validators = _interopRequireDefault(require("./validators"));
|
171
255
|
|
256
|
+
var _ReactSelectField = _interopRequireWildcard(require("./ReactSelectField"));
|
257
|
+
|
258
|
+
var _NestedFormFieldContext = _interopRequireDefault(require("./NestedFormFieldContext"));
|
259
|
+
|
172
260
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
173
261
|
|
174
262
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
@@ -82,7 +82,7 @@ function minCount(count) {
|
|
82
82
|
|
83
83
|
var maxValue = function maxValue(value) {
|
84
84
|
return function (inputValue) {
|
85
|
-
if (inputValue && value) {
|
85
|
+
if (inputValue != null && value != null) {
|
86
86
|
return inputValue <= value ? undefined : "Maximum value ".concat(value, " exceeded");
|
87
87
|
} else {
|
88
88
|
return undefined;
|
@@ -94,7 +94,7 @@ exports.maxValue = maxValue;
|
|
94
94
|
|
95
95
|
var minValue = function minValue(value) {
|
96
96
|
return function (inputValue) {
|
97
|
-
if (inputValue && value) {
|
97
|
+
if (inputValue != null && value != null) {
|
98
98
|
return inputValue >= value ? undefined : "Minimum value ".concat(value, " not met");
|
99
99
|
} else {
|
100
100
|
return undefined;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "envoc-form",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.3.0",
|
4
4
|
"description": "Envoc form components",
|
5
5
|
"keywords": [
|
6
6
|
"react-component",
|
@@ -26,7 +26,8 @@
|
|
26
26
|
"axios": "^0.21.1",
|
27
27
|
"classnames": "^2.3.1",
|
28
28
|
"date-fns": "^2.22.1",
|
29
|
-
"envoc-request": "^3.
|
29
|
+
"envoc-request": "^3.3.0",
|
30
|
+
"lodash": "^4.17.21",
|
30
31
|
"lru-cache": "^6.0.0",
|
31
32
|
"prop-types": "^15.7.2",
|
32
33
|
"react-date-picker": "^8.2.0",
|
package/src/FileInput/index.js
CHANGED
package/src/Form/index.js
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
import FocusError from './FocusError';
|
1
2
|
import Form from './Form';
|
3
|
+
import FormBasedPreventNavigation from './FormBasedPreventNavigation';
|
2
4
|
import ServerErrorContext from './ServerErrorContext';
|
3
|
-
|
5
|
+
|
6
|
+
export {
|
7
|
+
Form as default,
|
8
|
+
ServerErrorContext,
|
9
|
+
FocusError,
|
10
|
+
FormBasedPreventNavigation,
|
11
|
+
};
|
@@ -15,6 +15,7 @@ import FormGroupWrapper from '../FormGroupWrapper';
|
|
15
15
|
import DatePickerInput from '../DatePickerInput';
|
16
16
|
import ReactSelectField from '../ReactSelectField';
|
17
17
|
import useStandardFormInput from '../useStandardFormInput';
|
18
|
+
import { MoneyFormattedInput } from '../MoneyFormattedInput';
|
18
19
|
import { FileInput, DropzoneFileInput } from '../FileInput';
|
19
20
|
|
20
21
|
export default function FormInput(props) {
|
@@ -57,6 +58,8 @@ function StandardFieldGroup(props) {
|
|
57
58
|
return <FormGroupWrapper {...props} Component={FileInput} />;
|
58
59
|
case 'textarea':
|
59
60
|
return <FormGroupWrapper {...props} Component={TextAreaInput} />;
|
61
|
+
case 'moneyFormatted':
|
62
|
+
return <FormGroupWrapper {...props} Component={MoneyFormattedInput} />;
|
60
63
|
default:
|
61
64
|
return <FormGroupWrapper {...props} Component={DefaultInput} />;
|
62
65
|
}
|
@@ -0,0 +1,115 @@
|
|
1
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
2
|
+
import { useField } from 'formik';
|
3
|
+
import debounce from 'lodash/debounce';
|
4
|
+
import classNames from 'classnames';
|
5
|
+
|
6
|
+
// Money input that will format the value to always have commas, a single decimal, and
|
7
|
+
// exactly two digits after the decimal. This happens after a delay (using debounce).
|
8
|
+
export default function MoneyFormattedInput({
|
9
|
+
name,
|
10
|
+
onBlur,
|
11
|
+
onChange,
|
12
|
+
classname,
|
13
|
+
disabled = false,
|
14
|
+
debounceTimer = 1500,
|
15
|
+
meta,
|
16
|
+
}) {
|
17
|
+
// The displayed state and formik state are two seperate values that we handle
|
18
|
+
const [inputValue, setInputValue] = useState('');
|
19
|
+
const [{ value: formikValue }] = useField(name);
|
20
|
+
|
21
|
+
const handleChangeDebounce = useMemo(() => {
|
22
|
+
return debounce(debouncedUpdateInput, debounceTimer);
|
23
|
+
|
24
|
+
function debouncedUpdateInput(value) {
|
25
|
+
var result = formatToCurrency(value);
|
26
|
+
|
27
|
+
setInputValue(result ?? '');
|
28
|
+
|
29
|
+
// sets value in formik
|
30
|
+
onChange(result ?? '');
|
31
|
+
onBlur();
|
32
|
+
}
|
33
|
+
}, [onBlur, onChange]);
|
34
|
+
|
35
|
+
// Format first render
|
36
|
+
useEffect(() => {
|
37
|
+
var formattedFormikValue = formatToCurrency(formikValue);
|
38
|
+
setInputValue(formattedFormikValue ?? '');
|
39
|
+
}, [formikValue]);
|
40
|
+
|
41
|
+
function handleChange(e) {
|
42
|
+
const onlyNumbersDecimalComma = e.target.value
|
43
|
+
.toString()
|
44
|
+
.replace(/[^.,0-9]/g, '');
|
45
|
+
|
46
|
+
setInputValue(onlyNumbersDecimalComma);
|
47
|
+
handleChangeDebounce(onlyNumbersDecimalComma);
|
48
|
+
}
|
49
|
+
|
50
|
+
return (
|
51
|
+
<>
|
52
|
+
<div className="input-group">
|
53
|
+
<div className="input-group-prepend">
|
54
|
+
<span className="input-group-text">$</span>
|
55
|
+
</div>
|
56
|
+
<input
|
57
|
+
name={name}
|
58
|
+
type="text"
|
59
|
+
value={inputValue}
|
60
|
+
onChange={handleChange}
|
61
|
+
onBlur={onBlur}
|
62
|
+
disabled={disabled}
|
63
|
+
className={classNames(
|
64
|
+
classname,
|
65
|
+
meta.error === 'Required' ? 'is-invalid' : '',
|
66
|
+
'react-select-input money-input form-control'
|
67
|
+
)}
|
68
|
+
/>
|
69
|
+
</div>
|
70
|
+
</>
|
71
|
+
);
|
72
|
+
}
|
73
|
+
|
74
|
+
function formatToCurrency(value) {
|
75
|
+
if (value === null || value === undefined) {
|
76
|
+
return null;
|
77
|
+
}
|
78
|
+
|
79
|
+
// 'value' is sometimes a number on first render
|
80
|
+
const onlyNumbersDecimal = value.toString().replace(/[^.0-9]/g, '');
|
81
|
+
|
82
|
+
if (!onlyNumbersDecimal) {
|
83
|
+
return null;
|
84
|
+
}
|
85
|
+
|
86
|
+
var result = new Intl.NumberFormat('en-US', {
|
87
|
+
style: 'decimal',
|
88
|
+
minimumSignificantDigits: 2,
|
89
|
+
minimumFractionDigits: 2,
|
90
|
+
}).format(parseFloat(onlyNumbersDecimal));
|
91
|
+
|
92
|
+
result = formatTwoDecimalPlaces(result);
|
93
|
+
return result;
|
94
|
+
}
|
95
|
+
|
96
|
+
function formatTwoDecimalPlaces(value) {
|
97
|
+
const decimalIndex = value.indexOf('.');
|
98
|
+
|
99
|
+
// If the string doesn't contain a decimal OR
|
100
|
+
// the string contains a single '.' with nothing to the right of the decimal -> append '.00'
|
101
|
+
// Reason: parseFloat will remove '.00' from whole numbers (ex. 350.00 -> 350)
|
102
|
+
if (!value.includes('.')) {
|
103
|
+
return value.concat('.00');
|
104
|
+
}
|
105
|
+
// If 2 or more characters to the right of the decimal
|
106
|
+
else if (!!value.charAt(decimalIndex + 2)) {
|
107
|
+
return value.substring(0, decimalIndex + 3);
|
108
|
+
}
|
109
|
+
// If only 1 character to the right of the decimal
|
110
|
+
else if (!!value.charAt(decimalIndex + 1)) {
|
111
|
+
return value.substring(0, decimalIndex + 2).concat('0');
|
112
|
+
}
|
113
|
+
|
114
|
+
return value;
|
115
|
+
}
|
package/src/index.js
CHANGED
@@ -2,12 +2,19 @@ import * as normalizers from './normalizers';
|
|
2
2
|
|
3
3
|
import { BoolInput, InlineBoolInput } from './BoolInput';
|
4
4
|
import { InlineMoneyInput, MoneyInput } from './MoneyInput';
|
5
|
+
import { MoneyFormattedInput } from './MoneyFormattedInput';
|
5
6
|
|
6
|
-
import AddressInput from './AddressInput';
|
7
|
+
import AddressInput, { UsStates } from './AddressInput';
|
7
8
|
import ConfirmBaseForm from './ConfirmBaseForm';
|
8
9
|
import ConfirmDeleteForm from './ConfirmDeleteForm';
|
10
|
+
import DatePickerInput from './DatePickerInput';
|
9
11
|
import ErrorScrollTarget from './ErrorScrollTarget';
|
10
|
-
import
|
12
|
+
import { FileInput, DropzoneFileInput, DefaultFileList } from './FileInput';
|
13
|
+
import Form, {
|
14
|
+
ServerErrorContext,
|
15
|
+
FocusError,
|
16
|
+
FormBasedPreventNavigation,
|
17
|
+
} from './Form';
|
11
18
|
import FormGroup from './FormGroup';
|
12
19
|
import FormGroupWrapper from './FormGroupWrapper';
|
13
20
|
import FormInput from './FormInput';
|
@@ -19,13 +26,23 @@ import StandardFormActions from './StandardFormActions';
|
|
19
26
|
import SubmitFormButton from './SubmitFormButton';
|
20
27
|
import useStandardFormInput from './useStandardFormInput';
|
21
28
|
import validators from './validators';
|
29
|
+
import ReactSelectField, {
|
30
|
+
customStyles as customReactSelectFieldStyles,
|
31
|
+
overrideTheme as overrideReactSelectFieldStyles,
|
32
|
+
} from './ReactSelectField';
|
33
|
+
import NestedFormFieldContext from './NestedFormFieldContext';
|
22
34
|
|
23
35
|
export {
|
24
36
|
AddressInput,
|
37
|
+
UsStates,
|
25
38
|
BoolInput,
|
26
39
|
ConfirmBaseForm,
|
27
40
|
ConfirmDeleteForm,
|
41
|
+
DatePickerInput,
|
28
42
|
ErrorScrollTarget,
|
43
|
+
FileInput,
|
44
|
+
DropzoneFileInput,
|
45
|
+
DefaultFileList,
|
29
46
|
Form,
|
30
47
|
FormGroup,
|
31
48
|
FormGroupWrapper,
|
@@ -37,9 +54,17 @@ export {
|
|
37
54
|
InlineFormInput,
|
38
55
|
InlineMoneyInput,
|
39
56
|
MoneyInput,
|
57
|
+
MoneyFormattedInput,
|
40
58
|
normalizers,
|
41
59
|
StandardFormActions,
|
42
60
|
SubmitFormButton,
|
43
61
|
useStandardFormInput,
|
44
62
|
validators,
|
63
|
+
ServerErrorContext,
|
64
|
+
FocusError,
|
65
|
+
FormBasedPreventNavigation,
|
66
|
+
ReactSelectField,
|
67
|
+
customReactSelectFieldStyles,
|
68
|
+
overrideReactSelectFieldStyles,
|
69
|
+
NestedFormFieldContext,
|
45
70
|
};
|
@@ -55,7 +55,7 @@ export function minCount(count) {
|
|
55
55
|
|
56
56
|
export const maxValue = function maxValue(value) {
|
57
57
|
return (inputValue) => {
|
58
|
-
if (inputValue && value) {
|
58
|
+
if (inputValue != null && value != null) {
|
59
59
|
return inputValue <= value
|
60
60
|
? undefined
|
61
61
|
: `Maximum value ${value} exceeded`;
|
@@ -67,7 +67,7 @@ export const maxValue = function maxValue(value) {
|
|
67
67
|
|
68
68
|
export const minValue = function minValue(value) {
|
69
69
|
return (inputValue) => {
|
70
|
-
if (inputValue && value) {
|
70
|
+
if (inputValue != null && value != null) {
|
71
71
|
return inputValue >= value ? undefined : `Minimum value ${value} not met`;
|
72
72
|
} else {
|
73
73
|
return undefined;
|