envoc-form 2.0.1-1 → 2.0.1-13

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.
Files changed (155) hide show
  1. package/README.md +7 -7
  2. package/dist/css/envoc-form-styles.css +43 -5
  3. package/dist/css/envoc-form-styles.css.map +1 -1
  4. package/es/AddressInput/AddressInput.js +8 -7
  5. package/es/ConfirmBaseForm/ConfirmBaseForm.js +3 -2
  6. package/es/ConfirmDeleteForm/ConfirmDeleteForm.js +3 -2
  7. package/es/DatePickerInput/DatePickerInput.js +3 -2
  8. package/es/FileInput/DefaultFileList.js +36 -0
  9. package/es/FileInput/DropzoneFileInput.js +58 -0
  10. package/es/FileInput/FileInput.js +31 -9
  11. package/es/FileInput/index.js +2 -1
  12. package/es/Form/Form.js +11 -33
  13. package/es/Form/FormBasedPreventNavigation.js +1 -1
  14. package/es/FormGroupWrapper.js +2 -1
  15. package/es/FormInput/FormInput.js +29 -10
  16. package/es/FormInputArray/FormInputArray.js +39 -24
  17. package/es/IconInput.js +2 -1
  18. package/es/ReactSelectField/ReactSelectField.js +6 -3
  19. package/es/SubmitFormButton.js +2 -1
  20. package/es/__Tests__/FormTestBase.js +5 -2
  21. package/es/normalizers.js +10 -5
  22. package/es/useStandardFormInput.js +4 -2
  23. package/es/utils/index.js +3 -0
  24. package/es/utils/objectContainsNonSerializableProperty.js +16 -0
  25. package/es/utils/objectToFormData.js +65 -0
  26. package/es/utils/typeChecks.js +25 -0
  27. package/lib/AddressInput/AddressInput.js +15 -9
  28. package/lib/ConfirmBaseForm/ConfirmBaseForm.js +4 -2
  29. package/lib/ConfirmDeleteForm/ConfirmDeleteForm.js +6 -4
  30. package/lib/DatePickerInput/DatePickerInput.js +4 -2
  31. package/lib/FileInput/DefaultFileList.js +47 -0
  32. package/lib/FileInput/DropzoneFileInput.js +75 -0
  33. package/lib/FileInput/FileInput.js +39 -10
  34. package/lib/FileInput/index.js +13 -3
  35. package/lib/Form/Form.js +19 -39
  36. package/lib/Form/FormBasedPreventNavigation.js +7 -3
  37. package/lib/FormGroupWrapper.js +3 -1
  38. package/lib/FormInput/FormInput.js +31 -11
  39. package/lib/FormInputArray/FormInputArray.js +47 -26
  40. package/lib/FormSection.js +5 -1
  41. package/lib/IconInput.js +3 -1
  42. package/lib/ReactSelectField/ReactSelectField.js +13 -5
  43. package/lib/ReactSelectField/index.js +6 -2
  44. package/lib/SubmitFormButton.js +3 -1
  45. package/lib/__Tests__/FormTestBase.js +6 -2
  46. package/lib/index.js +7 -3
  47. package/lib/normalizers.js +10 -5
  48. package/lib/useStandardFormInput.js +5 -2
  49. package/lib/utils/index.js +23 -0
  50. package/lib/utils/objectContainsNonSerializableProperty.js +24 -0
  51. package/lib/utils/objectToFormData.js +73 -0
  52. package/lib/utils/typeChecks.js +58 -0
  53. package/lib/validators/index.js +5 -1
  54. package/package.json +99 -90
  55. package/src/AddressInput/AddesssInput.test.js +23 -23
  56. package/src/AddressInput/AddressInput.js +73 -73
  57. package/src/AddressInput/UsStates.js +53 -53
  58. package/src/AddressInput/__snapshots__/AddesssInput.test.js.snap +207 -207
  59. package/src/AddressInput/index.js +2 -2
  60. package/src/BoolInput/BoolInput.js +7 -7
  61. package/src/BoolInput/BoolInput.test.js +23 -23
  62. package/src/BoolInput/InlineBoolInput.js +7 -7
  63. package/src/BoolInput/__snapshots__/BoolInput.test.js.snap +89 -89
  64. package/src/BoolInput/boolOptions.js +6 -6
  65. package/src/BoolInput/index.js +4 -4
  66. package/src/ConfirmBaseForm/ConfirmBaseForm.js +37 -37
  67. package/src/ConfirmBaseForm/ConfirmBaseForm.test.js +14 -14
  68. package/src/ConfirmBaseForm/__snapshots__/ConfirmBaseForm.test.js.snap +23 -23
  69. package/src/ConfirmBaseForm/index.js +1 -1
  70. package/src/ConfirmDeleteForm/ConfirmDeleteForm.js +39 -39
  71. package/src/ConfirmDeleteForm/ConfirmDeleteForm.test.js +24 -24
  72. package/src/ConfirmDeleteForm/__snapshots__/ConfirmDeleteForm.test.js.snap +25 -25
  73. package/src/ConfirmDeleteForm/index.js +1 -1
  74. package/src/DatePickerInput/DatePickerInput.js +46 -46
  75. package/src/DatePickerInput/DatePickerInput.test.js +74 -74
  76. package/src/DatePickerInput/__snapshots__/DatePickerInput.test.js.snap +134 -131
  77. package/src/DatePickerInput/date-picker-input.scss +42 -42
  78. package/src/DatePickerInput/index.js +3 -3
  79. package/src/ErrorScrollTarget.js +6 -6
  80. package/src/FileInput/DefaultFileList.js +39 -0
  81. package/src/FileInput/DropzoneFileInput.js +56 -0
  82. package/src/FileInput/DropzoneFileInput.test.js +24 -0
  83. package/src/FileInput/FileInput.js +77 -49
  84. package/src/FileInput/FileInput.test.js +24 -15
  85. package/src/FileInput/__snapshots__/DropzoneFileInput.test.js.snap +57 -0
  86. package/src/FileInput/__snapshots__/FileInput.test.js.snap +58 -22
  87. package/src/FileInput/file-input.scss +58 -17
  88. package/src/FileInput/index.js +4 -3
  89. package/src/Form/FocusError.js +48 -48
  90. package/src/Form/Form.js +139 -161
  91. package/src/Form/Form.test.js +23 -23
  92. package/src/Form/FormBasedPreventNavigation.js +25 -25
  93. package/src/Form/ServerErrorContext.js +7 -7
  94. package/src/Form/__snapshots__/Form.test.js.snap +9 -9
  95. package/src/Form/index.js +3 -3
  96. package/src/FormGroup.js +30 -30
  97. package/src/FormGroupWrapper.js +28 -28
  98. package/src/FormInput/FormInput.js +144 -136
  99. package/src/FormInput/FormInput.test.js +66 -66
  100. package/src/FormInput/__snapshots__/FormInput.test.js.snap +323 -313
  101. package/src/FormInput/form-input.scss +9 -9
  102. package/src/FormInput/index.js +2 -2
  103. package/src/FormInputArray/FormInputArray.js +224 -210
  104. package/src/FormInputArray/FormInputArray.test.js +108 -59
  105. package/src/FormInputArray/__snapshots__/FormInputArray.test.js.snap +52 -40
  106. package/src/FormInputArray/form-input-array.scss +13 -8
  107. package/src/FormInputArray/index.js +2 -2
  108. package/src/FormSection.js +13 -13
  109. package/src/IconInput.js +31 -31
  110. package/src/InlineFormInput/InlineFormInput.js +6 -6
  111. package/src/InlineFormInput/InlineFormInput.test.js +23 -23
  112. package/src/InlineFormInput/__snapshots__/InlineFormInput.test.js.snap +26 -26
  113. package/src/InlineFormInput/index.js +3 -3
  114. package/src/InlineFormInput/inline-form-input.scss +3 -3
  115. package/src/MoneyInput/InlineMoneyInput.js +7 -7
  116. package/src/MoneyInput/MoneyInput.js +7 -7
  117. package/src/MoneyInput/MoneyInputs.test.js +43 -43
  118. package/src/MoneyInput/__snapshots__/MoneyInputs.test.js.snap +81 -81
  119. package/src/MoneyInput/index.js +4 -4
  120. package/src/MoneyInput/money-input.scss +3 -3
  121. package/src/MoneyInput/moneyInputProps.js +12 -12
  122. package/src/NestedFormFieldContext.js +6 -6
  123. package/src/ReactSelectField/ReactSelectField.js +122 -120
  124. package/src/ReactSelectField/index.js +6 -6
  125. package/src/ReactSelectField/react-select-field.scss +5 -5
  126. package/src/StandardFormActions.js +27 -27
  127. package/src/SubmitFormButton.js +28 -28
  128. package/src/__Tests__/FormTestBase.js +14 -11
  129. package/src/__Tests__/IconInput.test.js +23 -23
  130. package/src/__Tests__/StandardFormActions.test.js +23 -23
  131. package/src/__Tests__/SubmitFormButton.test.js +23 -23
  132. package/src/__Tests__/__snapshots__/IconInput.test.js.snap +38 -38
  133. package/src/__Tests__/__snapshots__/StandardFormActions.test.js.snap +25 -25
  134. package/src/__Tests__/__snapshots__/SubmitFormButton.test.js.snap +18 -18
  135. package/src/__Tests__/index.js +2 -2
  136. package/src/_variables.scss +11 -11
  137. package/src/index.js +33 -33
  138. package/src/normalizers.js +42 -32
  139. package/src/selectors.js +3 -3
  140. package/src/styles.scss +7 -7
  141. package/src/useStandardFormInput.js +118 -118
  142. package/src/utils/index.js +3 -0
  143. package/src/utils/objectContainsNonSerializableProperty.js +15 -0
  144. package/src/utils/objectContainsNonSerializableProperty.test.js +49 -0
  145. package/src/utils/objectToFormData.js +89 -0
  146. package/src/utils/objectToFormData.test.js +76 -0
  147. package/src/utils/typeChecks.js +18 -0
  148. package/src/validators/index.js +2 -2
  149. package/src/validators/validators.js +93 -93
  150. package/src/validators/validators.test.js +79 -79
  151. package/CHANGELOG.json +0 -95
  152. package/CHANGELOG.md +0 -58
  153. package/es/FormInput/utilities.js +0 -71
  154. package/lib/FormInput/utilities.js +0 -86
  155. package/src/FormInput/utilities.js +0 -26
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # envoc-form
2
-
3
- [![npm package][npm-badge]][npm]
4
-
5
- Base form package for envoc projects.
6
-
7
- [npm-badge]: https://img.shields.io/npm/v/envoc-form.png?style=flat
1
+ # envoc-form
2
+
3
+ [![npm package][npm-badge]][npm]
4
+
5
+ Base form package for envoc projects.
6
+
7
+ [npm-badge]: https://img.shields.io/npm/v/envoc-form.png?style=flat
8
8
  [npm]: https://www.npmjs.com/package/envoc-form
@@ -62,13 +62,51 @@ input.money-input {
62
62
  display: none !important;
63
63
  }
64
64
 
65
- .remove-array-item {
66
- width: 35px;
65
+ section.react-dropzone > div {
67
66
  display: flex;
68
- justify-content: center;
67
+ flex: 1;
68
+ flex-direction: column;
69
69
  align-items: center;
70
- margin-bottom: auto;
71
- margin-top: 0;
70
+ border: 1px dashed #d8dbe0;
71
+ border-radius: 0.25rem;
72
+ background-color: white;
73
+ color: #8a93a2;
74
+ outline: none;
75
+ margin: 0;
76
+ padding: 20px;
77
+ transition: "border .24s ease-in-out";
78
+ cursor: pointer;
79
+ }
80
+ section.react-dropzone > div:focus, section.react-dropzone > div:focus-within {
81
+ border-color: #958bef;
82
+ box-shadow: 0 0 0 0.2rem rgba(50, 31, 219, 0.25);
83
+ }
84
+ section.react-dropzone.active > div, section.react-dropzone.accept > div {
85
+ border-color: #958bef;
86
+ box-shadow: 0 0 0 0.2rem rgba(50, 31, 219, 0.25);
87
+ }
88
+ section.react-dropzone.reject > div {
89
+ color: #e55353;
90
+ border-color: #e55353;
91
+ box-shadow: rgba(229, 83, 83, 0.25) 0px 0px 0px 3.2px;
92
+ }
93
+ section.react-dropzone.disabled > div {
94
+ background-color: #f2f2f2;
95
+ border-color: #e6e6e6;
96
+ cursor: no-drop;
97
+ }
98
+ section.react-dropzone > aside > .list-group:not(:empty) {
99
+ margin-top: 1rem;
100
+ }
101
+
102
+ .field-array-card {
103
+ margin-bottom: 1rem;
104
+ }
105
+ .field-array-card .field-array-item.removed {
106
+ display: none;
107
+ }
108
+ .field-array-card .field-array-item > .remove-array-item {
109
+ display: flex;
72
110
  }
73
111
 
74
112
  div.react-select-input.has-error {
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../../src/DatePickerInput/date-picker-input.scss","../../src/InlineFormInput/inline-form-input.scss","../../src/MoneyInput/money-input.scss","../../src/FormInput/form-input.scss","../../src/FileInput/file-input.scss","../../src/_variables.scss","../../src/FormInputArray/form-input-array.scss","../../src/ReactSelectField/react-select-field.scss"],"names":[],"mappings":"AAEA;EACE;;AACA;EACE;EACA;;AAEF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAEF;EACE;EACA;;AACA;EACE;;AAIJ;EACE;;;ACvCJ;EACE;;;ACDF;EACE;;;ACDF;EACE;;;AAIA;EACE;;;ACFA;EACE;;;AAKN;EACE,kBCFgC;EDGhC,cCF4B;;ADG5B;EACE;;;AEdJ;EACE;EACA;EACA;EACA;EACA;EACA;;;ACJF;EACE,cFDI","file":"envoc-form-styles.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../../src/DatePickerInput/date-picker-input.scss","../../src/InlineFormInput/inline-form-input.scss","../../src/MoneyInput/money-input.scss","../../src/FormInput/form-input.scss","../../src/FileInput/file-input.scss","../../src/_variables.scss","../../src/FormInputArray/form-input-array.scss","../../src/ReactSelectField/react-select-field.scss"],"names":[],"mappings":"AAEA;EACE;;AACA;EACE;EACA;;AAEF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAEF;EACE;EACA;;AACA;EACE;;AAIJ;EACE;;;ACvCJ;EACE;;;ACDF;EACE;;;ACDF;EACE;;;AAIA;EACE;;;ACFA;EACE;;;AAKN;EACE,kBCFgC;EDGhC,cCF4B;;ADG5B;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;;AAGJ;EAEE;EACA;;AAEF;EACE;EACA;EACA;;AAEF;EACE,kBCzC8B;ED0C9B,cCzC0B;ED0C1B;;AAEF;EACE;;;AEvDJ;EACE;;AAGE;EACE;;AAGF;EACE;;;ACPN;EACE,cFDI","file":"envoc-form-styles.css"}
@@ -5,10 +5,11 @@ import _createClass from "@babel/runtime/helpers/esm/createClass";
5
5
  import _inherits from "@babel/runtime/helpers/esm/inherits";
6
6
  import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
7
7
  import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
8
+ var _excluded = ["name"];
8
9
 
9
10
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
10
11
 
11
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
12
+ 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; } }
12
13
 
13
14
  import React from 'react';
14
15
  import { Col, Row } from 'reactstrap';
@@ -35,7 +36,7 @@ var AddressInput = /*#__PURE__*/function (_React$Component) {
35
36
  value: function render() {
36
37
  var _this$props = this.props,
37
38
  name = _this$props.name,
38
- props = _objectWithoutProperties(_this$props, ["name"]);
39
+ props = _objectWithoutProperties(_this$props, _excluded);
39
40
 
40
41
  return /*#__PURE__*/React.createElement(FormSection, _extends({
41
42
  name: name
@@ -69,7 +70,7 @@ var AddressInput = /*#__PURE__*/function (_React$Component) {
69
70
  })), /*#__PURE__*/React.createElement(Col, {
70
71
  xs: 4
71
72
  }, /*#__PURE__*/React.createElement(FormInput, {
72
- name: "zipcode",
73
+ name: "zipCode",
73
74
  placeholder: "Zip",
74
75
  label: "Zip",
75
76
  autoComplete: "postal-code",
@@ -84,10 +85,10 @@ var AddressInput = /*#__PURE__*/function (_React$Component) {
84
85
 
85
86
  export { AddressInput as default };
86
87
  AddressInput.propTypes = {
87
- /**
88
- * The key that the resulting values should be nested under within the form values.
89
- * If name prop were chicken the submitted form values would look like: {chicken: {address1:...}}
90
- * this allows us to have two address inputs inside the same form (shipping and billing address)
88
+ /**
89
+ * The key that the resulting values should be nested under within the form values.
90
+ * If name prop were chicken the submitted form values would look like: {chicken: {address1:...}}
91
+ * this allows us to have two address inputs inside the same form (shipping and billing address)
91
92
  */
92
93
  name: PropTypes.string
93
94
  };
@@ -1,8 +1,9 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
3
3
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
4
+ var _excluded = ["handleCancel", "request", "yesColor", "style", "title"];
4
5
 
5
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
6
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
6
7
 
7
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; }
8
9
 
@@ -16,7 +17,7 @@ export default function ConfirmBaseForm(_ref) {
16
17
  yesColor = _ref$yesColor === void 0 ? 'danger' : _ref$yesColor,
17
18
  style = _ref.style,
18
19
  title = _ref.title,
19
- props = _objectWithoutProperties(_ref, ["handleCancel", "request", "yesColor", "style", "title"]);
20
+ props = _objectWithoutProperties(_ref, _excluded);
20
21
 
21
22
  var webRequest = useAxiosRequest(Object.assign({}, request, {
22
23
  autoExecute: false
@@ -1,14 +1,15 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
3
+ var _excluded = ["successUrl", "form", "children"];
3
4
  import React from 'react';
4
- import { useHistory, useParams } from 'react-router';
5
+ import { useHistory, useParams } from 'react-router-dom';
5
6
  import ConfirmBaseForm from '../ConfirmBaseForm';
6
7
  import { toast } from 'react-toastify';
7
8
  export default function ConfirmDeleteForm(_ref) {
8
9
  var successUrl = _ref.successUrl,
9
10
  form = _ref.form,
10
11
  children = _ref.children,
11
- props = _objectWithoutProperties(_ref, ["successUrl", "form", "children"]);
12
+ props = _objectWithoutProperties(_ref, _excluded);
12
13
 
13
14
  var history = useHistory();
14
15
 
@@ -7,10 +7,11 @@ import _inherits from "@babel/runtime/helpers/esm/inherits";
7
7
  import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
8
8
  import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
9
9
  import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
10
+ var _excluded = ["value", "className"];
10
11
 
11
12
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
12
13
 
13
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
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; } }
14
15
 
15
16
  import React from 'react';
16
17
  import DatePicker from 'react-date-picker';
@@ -59,7 +60,7 @@ var DatePickerInput = /*#__PURE__*/function (_React$Component) {
59
60
  var _this$props = this.props,
60
61
  value = _this$props.value,
61
62
  className = _this$props.className,
62
- rest = _objectWithoutProperties(_this$props, ["value", "className"]);
63
+ rest = _objectWithoutProperties(_this$props, _excluded);
63
64
 
64
65
  if (value && !dateOnlyRegex.test(value)) {
65
66
  var errorMessage = "Invalid date only value of ".concat(value, " passed to DatePicker input. This input is only configured to handle dates in the format yyyy-mm-dd. Ensure that the server is configured to return date only values.");
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import { ListGroupItem, ListGroup } from 'reactstrap';
3
+ export default function DefaultFileList(_ref) {
4
+ var files = _ref.files,
5
+ _ref$rejectedFiles = _ref.rejectedFiles,
6
+ rejectedFiles = _ref$rejectedFiles === void 0 ? [] : _ref$rejectedFiles;
7
+ return /*#__PURE__*/React.createElement(ListGroup, null, files.map(function (file) {
8
+ return /*#__PURE__*/React.createElement(Group, {
9
+ key: file.path,
10
+ item: file,
11
+ warning: false
12
+ });
13
+ }), rejectedFiles.map(function (_ref2) {
14
+ var file = _ref2.file;
15
+ return /*#__PURE__*/React.createElement(Group, {
16
+ key: file.path,
17
+ item: file,
18
+ warning: true
19
+ });
20
+ }));
21
+ }
22
+
23
+ function Group(_ref3) {
24
+ var item = _ref3.item,
25
+ warning = _ref3.warning;
26
+ return /*#__PURE__*/React.createElement(ListGroupItem, {
27
+ color: "d-flex ".concat(warning ? 'warning' : 'success', " justify-content-between list-group-item ").concat(warning ? 'list-group-item-warning' : 'list-group-item-success', " px-3 py-1 rounded-1")
28
+ }, /*#__PURE__*/React.createElement("span", {
29
+ className: "d-flex justify-content-between w-100"
30
+ }, /*#__PURE__*/React.createElement("span", null, item.name), " ", /*#__PURE__*/React.createElement("span", null, humanFileSize(item.size))));
31
+ }
32
+
33
+ function humanFileSize(size) {
34
+ var i = Math.floor(Math.log(size) / Math.log(1024));
35
+ return (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'KB', 'MB', 'GB', 'TB'][i];
36
+ }
@@ -0,0 +1,58 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
3
+ import _readOnlyError from "@babel/runtime/helpers/esm/readOnlyError";
4
+ var _excluded = ["className", "onChange", "value", "accept", "disabled", "multiple", "FileList", "placeholder", "dropzone"];
5
+ import React from 'react';
6
+ import { useDropzone } from 'react-dropzone';
7
+ import classNames from 'classnames';
8
+ import DefaultFileList from './DefaultFileList';
9
+ export default function DropzoneFileInput(_ref) {
10
+ var classNameProp = _ref.className,
11
+ onChange = _ref.onChange,
12
+ value = _ref.value,
13
+ accept = _ref.accept,
14
+ disabled = _ref.disabled,
15
+ _ref$multiple = _ref.multiple,
16
+ multiple = _ref$multiple === void 0 ? false : _ref$multiple,
17
+ _ref$FileList = _ref.FileList,
18
+ FileList = _ref$FileList === void 0 ? DefaultFileList : _ref$FileList,
19
+ _ref$placeholder = _ref.placeholder,
20
+ placeholder = _ref$placeholder === void 0 ? 'Drag and drop some file(s) here, or click to select file(s)' : _ref$placeholder,
21
+ dropzone = _ref.dropzone,
22
+ props = _objectWithoutProperties(_ref, _excluded);
23
+
24
+ var _useDropzone = useDropzone({
25
+ accept: accept,
26
+ onDrop: onDrop,
27
+ disabled: disabled,
28
+ multiple: multiple
29
+ }),
30
+ _useDropzone$accepted = _useDropzone.acceptedFiles,
31
+ acceptedFiles = _useDropzone$accepted === void 0 ? (acceptedFiles[0], _readOnlyError("acceptedFiles")) : _useDropzone$accepted,
32
+ _useDropzone$fileReje = _useDropzone.fileRejections,
33
+ fileRejections = _useDropzone$fileReje === void 0 ? fileRejections.push(acceptedFiles.slice(1, acceptedFiles.length)) : _useDropzone$fileReje,
34
+ getRootProps = _useDropzone.getRootProps,
35
+ getInputProps = _useDropzone.getInputProps,
36
+ isDragAccept = _useDropzone.isDragAccept,
37
+ isDragReject = _useDropzone.isDragReject;
38
+
39
+ function onDrop(acceptedFiles) {
40
+ if (!(acceptedFiles !== null && acceptedFiles !== void 0 && acceptedFiles.length) > 1 && !multiple) {
41
+ onChange(null);
42
+ } else {
43
+ onChange(acceptedFiles);
44
+ }
45
+ }
46
+
47
+ var className = classNames('react-dropzone', classNameProp, {
48
+ accept: isDragAccept,
49
+ reject: isDragReject,
50
+ disabled: disabled
51
+ });
52
+ return /*#__PURE__*/React.createElement("section", {
53
+ className: className
54
+ }, /*#__PURE__*/React.createElement("div", getRootProps(), /*#__PURE__*/React.createElement("input", _extends({}, props, getInputProps())), /*#__PURE__*/React.createElement(React.Fragment, null, placeholder), !multiple && /*#__PURE__*/React.createElement("b", null, "Only one file accepted."), accept && /*#__PURE__*/React.createElement("b", null, "Files of type \"".concat(accept, "\" accepted"))), /*#__PURE__*/React.createElement("aside", null, /*#__PURE__*/React.createElement(FileList, {
55
+ files: acceptedFiles,
56
+ rejectedFiles: fileRejections
57
+ })));
58
+ }
@@ -1,35 +1,57 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
1
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
4
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
3
- import React, { useEffect, useRef } from 'react';
5
+ var _excluded = ["className", "onChange", "value", "multiple"];
6
+ import React, { useEffect, useRef, useState } from 'react';
7
+ import DefaultFileList from './DefaultFileList';
4
8
  export default function FileInput(_ref) {
5
9
  var className = _ref.className,
6
10
  onChange = _ref.onChange,
7
11
  value = _ref.value,
8
- props = _objectWithoutProperties(_ref, ["className", "onChange", "value"]);
12
+ _ref$multiple = _ref.multiple,
13
+ multiple = _ref$multiple === void 0 ? false : _ref$multiple,
14
+ props = _objectWithoutProperties(_ref, _excluded);
9
15
 
10
16
  var inputRef = useRef();
17
+
18
+ var _useState = useState([]),
19
+ _useState2 = _slicedToArray(_useState, 2),
20
+ acceptedFiles = _useState2[0],
21
+ setAcceptedFiles = _useState2[1];
22
+
11
23
  useEffect(function () {
12
24
  if (!value && inputRef.current) {
13
25
  inputRef.current.value = null;
14
26
  }
15
27
  }, [value]);
16
- return /*#__PURE__*/React.createElement("div", {
28
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
17
29
  className: "custom-file file-input ".concat(className || '', " ").concat(props.disabled ? 'disabled' : '')
18
- }, /*#__PURE__*/React.createElement("input", _extends({
30
+ }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("input", _extends({
19
31
  ref: inputRef,
20
32
  type: "file",
21
33
  className: "custom-file-input",
22
- onChange: handleChange
23
- }, props)), /*#__PURE__*/React.createElement("label", {
34
+ onChange: handleChange,
35
+ multiple: multiple
36
+ }, props))), /*#__PURE__*/React.createElement("label", {
24
37
  className: "custom-file-label"
25
- }, !value && /*#__PURE__*/React.createElement("span", null, "Choose A File..."), value && /*#__PURE__*/React.createElement("span", null, value.name, " - size: ", humanFileSize(value.size))));
38
+ }, /*#__PURE__*/React.createElement("div", null, !value && /*#__PURE__*/React.createElement("span", null, "Choose A File..."), value && (!multiple ? /*#__PURE__*/React.createElement("span", null, value.name, " - size: ", humanFileSize(value.size)) : value.length === 1 ? /*#__PURE__*/React.createElement("span", null, value[0].name, " - size: ", humanFileSize(value[0].size)) : /*#__PURE__*/React.createElement("span", null, "Multiple files selected."))))), /*#__PURE__*/React.createElement(DefaultFileList, {
39
+ files: acceptedFiles
40
+ }));
26
41
 
27
42
  function handleChange(e) {
28
43
  if (e == null || !e.target || !e.target.files.length) {
29
44
  onChange(null);
30
45
  } else {
31
- var target = e.target.files[0];
32
- onChange(target);
46
+ var files = _toConsumableArray(e.target.files);
47
+
48
+ setAcceptedFiles(files);
49
+
50
+ if (!multiple) {
51
+ onChange(files[0]);
52
+ } else {
53
+ onChange(files);
54
+ }
33
55
  }
34
56
  }
35
57
  }
@@ -1,2 +1,3 @@
1
1
  import FileInput from './FileInput';
2
- export default FileInput;
2
+ import DropzoneFileInput from './DropzoneFileInput';
3
+ export { FileInput, DropzoneFileInput };
package/es/Form/Form.js CHANGED
@@ -1,14 +1,15 @@
1
- import _typeof from "@babel/runtime/helpers/esm/typeof";
2
1
  import _extends from "@babel/runtime/helpers/esm/extends";
3
2
  import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
4
3
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
5
4
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
5
+ var _excluded = ["children", "className", "style", "ignoreLostChanges", "onSubmit", "initialValues"];
6
6
  import React, { useState, useMemo, useContext } from 'react';
7
7
  import PropTypes from 'prop-types';
8
8
  import FocusError from './FocusError';
9
9
  import { Formik, Form as FormikFormWrapper, useFormikContext } from 'formik';
10
10
  import FormBasedPreventNavigation from './FormBasedPreventNavigation';
11
11
  import ServerErrorContext from './ServerErrorContext';
12
+ import { objectToFormData, objectContainsNonSerializableProperty } from '../utils';
12
13
  export default function Form(_ref) {
13
14
  var children = _ref.children,
14
15
  className = _ref.className,
@@ -16,7 +17,7 @@ export default function Form(_ref) {
16
17
  ignoreLostChanges = _ref.ignoreLostChanges,
17
18
  onSubmit = _ref.onSubmit,
18
19
  initialValues = _ref.initialValues,
19
- props = _objectWithoutProperties(_ref, ["children", "className", "style", "ignoreLostChanges", "onSubmit", "initialValues"]);
20
+ props = _objectWithoutProperties(_ref, _excluded);
20
21
 
21
22
  // formik resets all error on each blur (with our settings)
22
23
  // this means that ALL errors from the server disappear when any one field is blurred
@@ -60,10 +61,13 @@ export default function Form(_ref) {
60
61
  function handleSubmit(values, formikBag) {
61
62
  var formData = null;
62
63
 
63
- if (Object.entries(values).some(function (value) {
64
- return value && value[1] instanceof File;
65
- })) {
66
- formData = objectToFormData(values);
64
+ if (objectContainsNonSerializableProperty(values)) {
65
+ formData = objectToFormData(values, {
66
+ indices: true,
67
+ dotNotation: true,
68
+ allowEmptyArrays: true,
69
+ noFileListBrackets: true
70
+ });
67
71
  }
68
72
 
69
73
  return Promise.resolve(onSubmit(formData || values)).then(function (response) {
@@ -112,34 +116,8 @@ function DisplayFormState() {
112
116
  padding: '.5rem'
113
117
  }
114
118
  }, serverErrorContext && serverErrorContext.errors && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("strong", null, "serverErrors = "), JSON.stringify(serverErrorContext.errors, null, 2)), /*#__PURE__*/React.createElement("strong", null, "formState = "), JSON.stringify(formState, null, 2)));
115
- } // https://github.com/silkyland/object-to-formdata
116
-
117
-
118
- export var objectToFormData = function objectToFormData(obj, form, namespace) {
119
- var fd = form || new FormData();
120
- var formKey;
121
-
122
- for (var property in obj) {
123
- if (obj.hasOwnProperty(property)) {
124
- if (namespace) {
125
- formKey = namespace + '.' + property;
126
- } else {
127
- formKey = property;
128
- }
129
-
130
- if (obj[property] instanceof Date) {
131
- fd.append(formKey, obj[property].toISOString());
132
- } else if (_typeof(obj[property]) === 'object' && !(obj[property] instanceof File) && !(obj[property] instanceof Blob)) {
133
- objectToFormData(obj[property], fd, formKey);
134
- } else {
135
- // if it's a string or a File object
136
- fd.append(formKey, obj[property]);
137
- }
138
- }
139
- }
119
+ }
140
120
 
141
- return fd;
142
- };
143
121
  Form.propTypes = {
144
122
  ignoreLostChanges: PropTypes.bool,
145
123
  onSubmit: PropTypes.func.isRequired,
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect } from 'react';
2
- import { Prompt } from 'react-router';
2
+ import { Prompt } from 'react-router-dom';
3
3
  import { useFormikContext } from 'formik';
4
4
  export default function FormBasedPreventNavigation(_ref) {
5
5
  var ignoreLostChanges = _ref.ignoreLostChanges,
@@ -1,5 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
3
+ var _excluded = ["prepend", "append", "Component", "helpText"];
3
4
  import React from 'react';
4
5
  import { InputGroup } from 'reactstrap';
5
6
  import FormGroup from './FormGroup';
@@ -9,7 +10,7 @@ export default function FormGroupWrapper(_ref) {
9
10
  append = _ref.append,
10
11
  Component = _ref.Component,
11
12
  helpText = _ref.helpText,
12
- props = _objectWithoutProperties(_ref, ["prepend", "append", "Component", "helpText"]);
13
+ props = _objectWithoutProperties(_ref, _excluded);
13
14
 
14
15
  var meta = props.meta;
15
16
  return /*#__PURE__*/React.createElement(FormGroup, _extends({
@@ -2,6 +2,12 @@ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
5
+ var _excluded = ["className", "meta", "helpText"],
6
+ _excluded2 = ["meta"],
7
+ _excluded3 = ["includeEmptyOption", "options"],
8
+ _excluded4 = ["optionsUrl", "includeEmptyOption", "includeOtherOption", "cache", "maxAge"],
9
+ _excluded5 = ["meta"],
10
+ _excluded6 = ["helpText", "meta"];
5
11
  import React from 'react';
6
12
  import classnames from 'classnames';
7
13
  import { Input as BootstrapInput, FormFeedback, CustomInput, FormText, Alert } from 'reactstrap';
@@ -13,7 +19,7 @@ import FormGroupWrapper from '../FormGroupWrapper';
13
19
  import DatePickerInput from '../DatePickerInput';
14
20
  import ReactSelectField from '../ReactSelectField';
15
21
  import useStandardFormInput from '../useStandardFormInput';
16
- import FileInput from '../FileInput';
22
+ import { FileInput, DropzoneFileInput } from '../FileInput';
17
23
  export default function FormInput(props) {
18
24
  var _useStandardFormInput = useStandardFormInput(props),
19
25
  _useStandardFormInput2 = _slicedToArray(_useStandardFormInput, 2),
@@ -60,6 +66,12 @@ function StandardFieldGroup(props) {
60
66
  return Checkbox(props);
61
67
 
62
68
  case 'file':
69
+ if (props.dropzone) {
70
+ return /*#__PURE__*/React.createElement(FormGroupWrapper, _extends({}, props, {
71
+ Component: DropzoneFileInput
72
+ }));
73
+ }
74
+
63
75
  return /*#__PURE__*/React.createElement(FormGroupWrapper, _extends({}, props, {
64
76
  Component: FileInput
65
77
  }));
@@ -80,7 +92,7 @@ var TextAreaInput = function TextAreaInput(_ref) {
80
92
  var className = _ref.className,
81
93
  meta = _ref.meta,
82
94
  helpText = _ref.helpText,
83
- props = _objectWithoutProperties(_ref, ["className", "meta", "helpText"]);
95
+ props = _objectWithoutProperties(_ref, _excluded);
84
96
 
85
97
  return /*#__PURE__*/React.createElement(TextareaAutosize, _extends({
86
98
  cacheMeasurements: true,
@@ -90,7 +102,7 @@ var TextAreaInput = function TextAreaInput(_ref) {
90
102
 
91
103
  var DefaultInput = function DefaultInput(_ref2) {
92
104
  var meta = _ref2.meta,
93
- props = _objectWithoutProperties(_ref2, ["meta"]);
105
+ props = _objectWithoutProperties(_ref2, _excluded2);
94
106
 
95
107
  return /*#__PURE__*/React.createElement(BootstrapInput, _extends({
96
108
  invalid: !!meta.error
@@ -101,7 +113,7 @@ var Select = function Select(_ref3) {
101
113
  var _ref3$includeEmptyOpt = _ref3.includeEmptyOption,
102
114
  includeEmptyOption = _ref3$includeEmptyOpt === void 0 ? true : _ref3$includeEmptyOpt,
103
115
  options = _ref3.options,
104
- props = _objectWithoutProperties(_ref3, ["includeEmptyOption", "options"]);
116
+ props = _objectWithoutProperties(_ref3, _excluded3);
105
117
 
106
118
  var allOptions = includeEmptyOption ? [{
107
119
  label: ' ',
@@ -110,11 +122,13 @@ var Select = function Select(_ref3) {
110
122
  return /*#__PURE__*/React.createElement(ReactSelectField, _extends({}, props, {
111
123
  options: allOptions
112
124
  }));
113
- };
125
+ }; // low cache value just to prevent the same dropdown from hitting the API at the same time
126
+ // TODO: global cache provider / "envoc-cache" instead of this static instance
127
+
114
128
 
115
129
  export var optionCache = new lru({
116
130
  max: 500,
117
- maxAge: 1000 * 60 * 5
131
+ maxAge: 1000 * 10
118
132
  });
119
133
 
120
134
  var RemoteSelect = function RemoteSelect(_ref4) {
@@ -123,12 +137,17 @@ var RemoteSelect = function RemoteSelect(_ref4) {
123
137
  includeEmptyOption = _ref4$includeEmptyOpt === void 0 ? true : _ref4$includeEmptyOpt,
124
138
  _ref4$includeOtherOpt = _ref4.includeOtherOption,
125
139
  includeOtherOption = _ref4$includeOtherOpt === void 0 ? false : _ref4$includeOtherOpt,
126
- props = _objectWithoutProperties(_ref4, ["optionsUrl", "includeEmptyOption", "includeOtherOption"]);
140
+ _ref4$cache = _ref4.cache,
141
+ cache = _ref4$cache === void 0 ? optionCache : _ref4$cache,
142
+ _ref4$maxAge = _ref4.maxAge,
143
+ maxAge = _ref4$maxAge === void 0 ? 1000 * 10 : _ref4$maxAge,
144
+ props = _objectWithoutProperties(_ref4, _excluded4);
127
145
 
128
146
  var request = {
129
147
  method: 'get',
130
148
  url: optionsUrl,
131
- cache: optionCache,
149
+ cache: cache,
150
+ maxAge: maxAge,
132
151
  autoExecute: true
133
152
  };
134
153
  var webRequest = useAxiosRequest(request);
@@ -171,7 +190,7 @@ var RemoteSelect = function RemoteSelect(_ref4) {
171
190
 
172
191
  var DatePicker = function DatePicker(_ref5) {
173
192
  var meta = _ref5.meta,
174
- props = _objectWithoutProperties(_ref5, ["meta"]);
193
+ props = _objectWithoutProperties(_ref5, _excluded5);
175
194
 
176
195
  return /*#__PURE__*/React.createElement(DatePickerInput, _extends({}, props, {
177
196
  className: meta.error ? 'is-invalid' : ''
@@ -181,7 +200,7 @@ var DatePicker = function DatePicker(_ref5) {
181
200
  var Checkbox = function Checkbox(_ref6) {
182
201
  var helpText = _ref6.helpText,
183
202
  meta = _ref6.meta,
184
- props = _objectWithoutProperties(_ref6, ["helpText", "meta"]);
203
+ props = _objectWithoutProperties(_ref6, _excluded6);
185
204
 
186
205
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(CustomInput, props), meta.error && /*#__PURE__*/React.createElement(FormFeedback, null, meta.error), helpText && /*#__PURE__*/React.createElement(FormText, null, helpText));
187
206
  };