envoc-form 3.0.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/ReactSelectField/ReactSelectField.js +36 -2
- package/es/index.js +20 -10
- 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/ReactSelectField/ReactSelectField.js +37 -2
- package/lib/index.js +166 -38
- package/lib/validators/validators.js +2 -2
- package/package.json +3 -2
- package/src/AddressInput/__snapshots__/AddesssInput.test.js.snap +1 -1
- package/src/AddressInput/index.js +2 -1
- package/src/BoolInput/__snapshots__/BoolInput.test.js.snap +1 -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/FormInput/__snapshots__/FormInput.test.js.snap +1 -1
- package/src/MoneyFormattedInput/MoneyFormattedInput.js +115 -0
- package/src/MoneyFormattedInput/index.js +3 -0
- package/src/ReactSelectField/ReactSelectField.js +34 -1
- package/src/index.js +54 -17
- 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
|
+
}
|
@@ -7,6 +7,7 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
|
|
7
7
|
|
8
8
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
9
9
|
|
10
|
+
import classNames from 'classnames';
|
10
11
|
import React, { useEffect, useRef } from 'react';
|
11
12
|
import { default as ReactSelect } from 'react-select';
|
12
13
|
export var overrideTheme = function overrideTheme(theme) {
|
@@ -22,6 +23,8 @@ var red = '#f86c6b';
|
|
22
23
|
var inputBorderColor = '#c2cfd6';
|
23
24
|
var inputBorderColorFocused = '#8ad4ee';
|
24
25
|
var inputBoxShadowFocused = '0 0 0 0.2rem rgba(32, 168, 216, 0.25)';
|
26
|
+
var placeholderColor = '#9ca3af';
|
27
|
+
var disabledSingleValueColor = '#4b5563';
|
25
28
|
export var customStyles = {
|
26
29
|
control: function control(provided, _ref) {
|
27
30
|
var isFocused = _ref.isFocused,
|
@@ -39,6 +42,17 @@ export var customStyles = {
|
|
39
42
|
return _objectSpread(_objectSpread({}, provided), {}, {
|
40
43
|
zIndex: 3
|
41
44
|
});
|
45
|
+
},
|
46
|
+
singleValue: function singleValue(provided, state) {
|
47
|
+
var color = state.isDisabled ? disabledSingleValueColor : '';
|
48
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
49
|
+
color: color
|
50
|
+
});
|
51
|
+
},
|
52
|
+
placeholder: function placeholder(defaultStyles) {
|
53
|
+
return _objectSpread(_objectSpread({}, defaultStyles), {}, {
|
54
|
+
color: placeholderColor
|
55
|
+
});
|
42
56
|
}
|
43
57
|
}; // internal to forms use only
|
44
58
|
|
@@ -48,7 +62,7 @@ export default function ReactSelectInput(_ref2) {
|
|
48
62
|
disabled = _ref2.disabled,
|
49
63
|
onSelected = _ref2.onSelected,
|
50
64
|
onChange = _ref2.onChange,
|
51
|
-
|
65
|
+
_onBlur = _ref2.onBlur,
|
52
66
|
value = _ref2.value,
|
53
67
|
options = _ref2.options,
|
54
68
|
defaultValue = _ref2.defaultValue,
|
@@ -61,6 +75,23 @@ export default function ReactSelectInput(_ref2) {
|
|
61
75
|
useEffect(function () {
|
62
76
|
onSelectedRef.current && onSelectedRef.current(selectedItems);
|
63
77
|
}, [selectedItems]);
|
78
|
+
var onBlurRef = useRef(_onBlur);
|
79
|
+
onBlurRef.current = _onBlur;
|
80
|
+
var touched = meta.touched;
|
81
|
+
useEffect(function () {
|
82
|
+
if (!touched) return; // without the timer set to 0, if the empty option is selected the required message doesn't appear until clicked away from the select input
|
83
|
+
|
84
|
+
var timerRef = setTimeout(function () {
|
85
|
+
onBlurRef.current && onBlurRef.current();
|
86
|
+
}, 0);
|
87
|
+
return function () {
|
88
|
+
clearTimeout(timerRef);
|
89
|
+
};
|
90
|
+
}, [value, touched]);
|
91
|
+
var classes = classNames(className, 'react-select-input', {
|
92
|
+
'is-invalid': !!meta.error,
|
93
|
+
disabled: disabled
|
94
|
+
});
|
64
95
|
return /*#__PURE__*/React.createElement(ReactSelect, _extends({}, props, {
|
65
96
|
options: options,
|
66
97
|
isDisabled: disabled,
|
@@ -71,7 +102,10 @@ export default function ReactSelectInput(_ref2) {
|
|
71
102
|
getOptionValue: getOptionValue,
|
72
103
|
value: selectedItems,
|
73
104
|
onChange: handleChange,
|
74
|
-
|
105
|
+
onBlur: function onBlur() {
|
106
|
+
return _onBlur();
|
107
|
+
},
|
108
|
+
className: classes,
|
75
109
|
theme: overrideTheme,
|
76
110
|
styles: customStyles,
|
77
111
|
menuPortalTarget: document.body,
|
package/es/index.js
CHANGED
@@ -1,15 +1,25 @@
|
|
1
|
-
import
|
1
|
+
import * as normalizers from './normalizers';
|
2
|
+
import { BoolInput, InlineBoolInput } from './BoolInput';
|
3
|
+
import { InlineMoneyInput, MoneyInput } from './MoneyInput';
|
4
|
+
import { MoneyFormattedInput } from './MoneyFormattedInput';
|
5
|
+
import AddressInput, { UsStates } from './AddressInput';
|
6
|
+
import ConfirmBaseForm from './ConfirmBaseForm';
|
7
|
+
import ConfirmDeleteForm from './ConfirmDeleteForm';
|
8
|
+
import DatePickerInput from './DatePickerInput';
|
9
|
+
import ErrorScrollTarget from './ErrorScrollTarget';
|
10
|
+
import { FileInput, DropzoneFileInput, DefaultFileList } from './FileInput';
|
11
|
+
import Form, { ServerErrorContext, FocusError, FormBasedPreventNavigation } from './Form';
|
12
|
+
import FormGroup from './FormGroup';
|
13
|
+
import FormGroupWrapper from './FormGroupWrapper';
|
2
14
|
import FormInput from './FormInput';
|
3
|
-
import InlineFormInput from './InlineFormInput';
|
4
15
|
import FormInputArray from './FormInputArray';
|
16
|
+
import FormSection from './FormSection';
|
5
17
|
import IconInput from './IconInput';
|
6
|
-
import
|
18
|
+
import InlineFormInput from './InlineFormInput';
|
7
19
|
import StandardFormActions from './StandardFormActions';
|
8
|
-
import validators from './validators';
|
9
|
-
import * as normalizers from './normalizers';
|
10
|
-
import ConfirmBaseForm from './ConfirmBaseForm';
|
11
|
-
import ConfirmDeleteForm from './ConfirmDeleteForm';
|
12
20
|
import SubmitFormButton from './SubmitFormButton';
|
13
|
-
import
|
14
|
-
import
|
15
|
-
|
21
|
+
import useStandardFormInput from './useStandardFormInput';
|
22
|
+
import validators from './validators';
|
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"));
|
@@ -16,6 +16,8 @@ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/h
|
|
16
16
|
|
17
17
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
18
18
|
|
19
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
20
|
+
|
19
21
|
var _react = _interopRequireWildcard(require("react"));
|
20
22
|
|
21
23
|
var _reactSelect = _interopRequireDefault(require("react-select"));
|
@@ -45,6 +47,8 @@ var red = '#f86c6b';
|
|
45
47
|
var inputBorderColor = '#c2cfd6';
|
46
48
|
var inputBorderColorFocused = '#8ad4ee';
|
47
49
|
var inputBoxShadowFocused = '0 0 0 0.2rem rgba(32, 168, 216, 0.25)';
|
50
|
+
var placeholderColor = '#9ca3af';
|
51
|
+
var disabledSingleValueColor = '#4b5563';
|
48
52
|
var customStyles = {
|
49
53
|
control: function control(provided, _ref) {
|
50
54
|
var isFocused = _ref.isFocused,
|
@@ -62,6 +66,17 @@ var customStyles = {
|
|
62
66
|
return _objectSpread(_objectSpread({}, provided), {}, {
|
63
67
|
zIndex: 3
|
64
68
|
});
|
69
|
+
},
|
70
|
+
singleValue: function singleValue(provided, state) {
|
71
|
+
var color = state.isDisabled ? disabledSingleValueColor : '';
|
72
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
73
|
+
color: color
|
74
|
+
});
|
75
|
+
},
|
76
|
+
placeholder: function placeholder(defaultStyles) {
|
77
|
+
return _objectSpread(_objectSpread({}, defaultStyles), {}, {
|
78
|
+
color: placeholderColor
|
79
|
+
});
|
65
80
|
}
|
66
81
|
}; // internal to forms use only
|
67
82
|
|
@@ -73,7 +88,7 @@ function ReactSelectInput(_ref2) {
|
|
73
88
|
disabled = _ref2.disabled,
|
74
89
|
onSelected = _ref2.onSelected,
|
75
90
|
onChange = _ref2.onChange,
|
76
|
-
|
91
|
+
_onBlur = _ref2.onBlur,
|
77
92
|
value = _ref2.value,
|
78
93
|
options = _ref2.options,
|
79
94
|
defaultValue = _ref2.defaultValue,
|
@@ -85,6 +100,23 @@ function ReactSelectInput(_ref2) {
|
|
85
100
|
(0, _react.useEffect)(function () {
|
86
101
|
onSelectedRef.current && onSelectedRef.current(selectedItems);
|
87
102
|
}, [selectedItems]);
|
103
|
+
var onBlurRef = (0, _react.useRef)(_onBlur);
|
104
|
+
onBlurRef.current = _onBlur;
|
105
|
+
var touched = meta.touched;
|
106
|
+
(0, _react.useEffect)(function () {
|
107
|
+
if (!touched) return; // without the timer set to 0, if the empty option is selected the required message doesn't appear until clicked away from the select input
|
108
|
+
|
109
|
+
var timerRef = setTimeout(function () {
|
110
|
+
onBlurRef.current && onBlurRef.current();
|
111
|
+
}, 0);
|
112
|
+
return function () {
|
113
|
+
clearTimeout(timerRef);
|
114
|
+
};
|
115
|
+
}, [value, touched]);
|
116
|
+
var classes = (0, _classnames["default"])(className, 'react-select-input', {
|
117
|
+
'is-invalid': !!meta.error,
|
118
|
+
disabled: disabled
|
119
|
+
});
|
88
120
|
return /*#__PURE__*/_react["default"].createElement(_reactSelect["default"], (0, _extends2["default"])({}, props, {
|
89
121
|
options: options,
|
90
122
|
isDisabled: disabled,
|
@@ -95,7 +127,10 @@ function ReactSelectInput(_ref2) {
|
|
95
127
|
getOptionValue: getOptionValue,
|
96
128
|
value: selectedItems,
|
97
129
|
onChange: handleChange,
|
98
|
-
|
130
|
+
onBlur: function onBlur() {
|
131
|
+
return _onBlur();
|
132
|
+
},
|
133
|
+
className: classes,
|
99
134
|
theme: overrideTheme,
|
100
135
|
styles: customStyles,
|
101
136
|
menuPortalTarget: document.body,
|