envoc-form 2.0.1-8 → 3.0.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.
Files changed (144) hide show
  1. package/README.md +7 -7
  2. package/dist/css/envoc-form-styles.css +7 -6
  3. package/dist/css/envoc-form-styles.css.map +1 -1
  4. package/es/AddressInput/AddressInput.js +7 -6
  5. package/es/ConfirmBaseForm/ConfirmBaseForm.js +3 -2
  6. package/es/ConfirmDeleteForm/ConfirmDeleteForm.js +6 -5
  7. package/es/DatePickerInput/DatePickerInput.js +8 -3
  8. package/es/FileInput/DefaultFileList.js +3 -2
  9. package/es/FileInput/DropzoneFileInput.js +15 -12
  10. package/es/FileInput/FileInput.js +31 -9
  11. package/es/Form/Form.js +4 -2
  12. package/es/Form/FormBasedPreventNavigation.js +4 -7
  13. package/es/FormGroupWrapper.js +2 -1
  14. package/es/FormInput/FormInput.js +14 -8
  15. package/es/FormInputArray/FormInputArray.js +39 -24
  16. package/es/IconInput.js +2 -1
  17. package/es/ReactSelectField/ReactSelectField.js +6 -3
  18. package/es/SubmitFormButton.js +2 -1
  19. package/es/__Tests__/FormTestBase.js +5 -2
  20. package/es/normalizers.js +10 -5
  21. package/es/useStandardFormInput.js +4 -2
  22. package/es/utils/objectToFormData.js +10 -2
  23. package/lib/AddressInput/AddressInput.js +14 -8
  24. package/lib/ConfirmBaseForm/ConfirmBaseForm.js +4 -2
  25. package/lib/ConfirmDeleteForm/ConfirmDeleteForm.js +6 -4
  26. package/lib/DatePickerInput/DatePickerInput.js +9 -3
  27. package/lib/FileInput/DefaultFileList.js +3 -2
  28. package/lib/FileInput/DropzoneFileInput.js +17 -12
  29. package/lib/FileInput/FileInput.js +39 -10
  30. package/lib/Form/Form.js +11 -4
  31. package/lib/Form/FormBasedPreventNavigation.js +4 -10
  32. package/lib/FormGroupWrapper.js +3 -1
  33. package/lib/FormInput/FormInput.js +15 -8
  34. package/lib/FormInputArray/FormInputArray.js +47 -26
  35. package/lib/FormSection.js +5 -1
  36. package/lib/IconInput.js +3 -1
  37. package/lib/ReactSelectField/ReactSelectField.js +13 -5
  38. package/lib/ReactSelectField/index.js +6 -2
  39. package/lib/SubmitFormButton.js +3 -1
  40. package/lib/__Tests__/FormTestBase.js +6 -2
  41. package/lib/index.js +7 -3
  42. package/lib/normalizers.js +10 -5
  43. package/lib/useStandardFormInput.js +5 -2
  44. package/lib/utils/objectToFormData.js +10 -2
  45. package/lib/validators/index.js +5 -1
  46. package/package.json +99 -92
  47. package/src/AddressInput/AddesssInput.test.js +23 -23
  48. package/src/AddressInput/AddressInput.js +73 -73
  49. package/src/AddressInput/UsStates.js +53 -53
  50. package/src/AddressInput/__snapshots__/AddesssInput.test.js.snap +207 -207
  51. package/src/AddressInput/index.js +2 -2
  52. package/src/BoolInput/BoolInput.js +7 -7
  53. package/src/BoolInput/BoolInput.test.js +23 -23
  54. package/src/BoolInput/InlineBoolInput.js +7 -7
  55. package/src/BoolInput/__snapshots__/BoolInput.test.js.snap +89 -89
  56. package/src/BoolInput/boolOptions.js +6 -6
  57. package/src/BoolInput/index.js +4 -4
  58. package/src/ConfirmBaseForm/ConfirmBaseForm.js +37 -37
  59. package/src/ConfirmBaseForm/ConfirmBaseForm.test.js +14 -14
  60. package/src/ConfirmBaseForm/__snapshots__/ConfirmBaseForm.test.js.snap +23 -23
  61. package/src/ConfirmBaseForm/index.js +1 -1
  62. package/src/ConfirmDeleteForm/ConfirmDeleteForm.js +39 -39
  63. package/src/ConfirmDeleteForm/ConfirmDeleteForm.test.js +24 -24
  64. package/src/ConfirmDeleteForm/__snapshots__/ConfirmDeleteForm.test.js.snap +25 -25
  65. package/src/ConfirmDeleteForm/index.js +1 -1
  66. package/src/DatePickerInput/DatePickerInput.js +49 -46
  67. package/src/DatePickerInput/DatePickerInput.test.js +74 -74
  68. package/src/DatePickerInput/__snapshots__/DatePickerInput.test.js.snap +134 -134
  69. package/src/DatePickerInput/date-picker-input.scss +42 -42
  70. package/src/DatePickerInput/index.js +3 -3
  71. package/src/ErrorScrollTarget.js +6 -6
  72. package/src/FileInput/DefaultFileList.js +39 -39
  73. package/src/FileInput/DropzoneFileInput.js +56 -55
  74. package/src/FileInput/DropzoneFileInput.test.js +24 -15
  75. package/src/FileInput/FileInput.js +77 -49
  76. package/src/FileInput/FileInput.test.js +24 -15
  77. package/src/FileInput/__snapshots__/DropzoneFileInput.test.js.snap +57 -28
  78. package/src/FileInput/__snapshots__/FileInput.test.js.snap +58 -22
  79. package/src/FileInput/file-input.scss +57 -57
  80. package/src/FileInput/index.js +4 -4
  81. package/src/Form/FocusError.js +48 -48
  82. package/src/Form/Form.js +139 -138
  83. package/src/Form/Form.test.js +23 -23
  84. package/src/Form/FormBasedPreventNavigation.js +25 -25
  85. package/src/Form/ServerErrorContext.js +7 -7
  86. package/src/Form/__snapshots__/Form.test.js.snap +9 -9
  87. package/src/Form/index.js +3 -3
  88. package/src/FormGroup.js +30 -30
  89. package/src/FormGroupWrapper.js +28 -28
  90. package/src/FormInput/FormInput.js +145 -144
  91. package/src/FormInput/FormInput.test.js +66 -66
  92. package/src/FormInput/__snapshots__/FormInput.test.js.snap +323 -316
  93. package/src/FormInput/form-input.scss +9 -9
  94. package/src/FormInput/index.js +2 -2
  95. package/src/FormInputArray/FormInputArray.js +224 -210
  96. package/src/FormInputArray/FormInputArray.test.js +108 -59
  97. package/src/FormInputArray/__snapshots__/FormInputArray.test.js.snap +52 -40
  98. package/src/FormInputArray/form-input-array.scss +13 -8
  99. package/src/FormInputArray/index.js +2 -2
  100. package/src/FormSection.js +13 -13
  101. package/src/IconInput.js +31 -31
  102. package/src/InlineFormInput/InlineFormInput.js +6 -6
  103. package/src/InlineFormInput/InlineFormInput.test.js +23 -23
  104. package/src/InlineFormInput/__snapshots__/InlineFormInput.test.js.snap +26 -26
  105. package/src/InlineFormInput/index.js +3 -3
  106. package/src/InlineFormInput/inline-form-input.scss +3 -3
  107. package/src/MoneyInput/InlineMoneyInput.js +7 -7
  108. package/src/MoneyInput/MoneyInput.js +7 -7
  109. package/src/MoneyInput/MoneyInputs.test.js +43 -43
  110. package/src/MoneyInput/__snapshots__/MoneyInputs.test.js.snap +81 -81
  111. package/src/MoneyInput/index.js +4 -4
  112. package/src/MoneyInput/money-input.scss +3 -3
  113. package/src/MoneyInput/moneyInputProps.js +12 -12
  114. package/src/NestedFormFieldContext.js +6 -6
  115. package/src/ReactSelectField/ReactSelectField.js +122 -120
  116. package/src/ReactSelectField/index.js +6 -6
  117. package/src/ReactSelectField/react-select-field.scss +5 -5
  118. package/src/StandardFormActions.js +27 -27
  119. package/src/SubmitFormButton.js +28 -28
  120. package/src/__Tests__/FormTestBase.js +14 -11
  121. package/src/__Tests__/IconInput.test.js +23 -23
  122. package/src/__Tests__/StandardFormActions.test.js +23 -23
  123. package/src/__Tests__/SubmitFormButton.test.js +23 -23
  124. package/src/__Tests__/__snapshots__/IconInput.test.js.snap +38 -38
  125. package/src/__Tests__/__snapshots__/StandardFormActions.test.js.snap +25 -25
  126. package/src/__Tests__/__snapshots__/SubmitFormButton.test.js.snap +18 -18
  127. package/src/__Tests__/index.js +2 -2
  128. package/src/_variables.scss +11 -11
  129. package/src/index.js +33 -33
  130. package/src/normalizers.js +42 -32
  131. package/src/selectors.js +3 -3
  132. package/src/styles.scss +7 -7
  133. package/src/useStandardFormInput.js +118 -118
  134. package/src/utils/index.js +3 -3
  135. package/src/utils/objectContainsNonSerializableProperty.js +15 -15
  136. package/src/utils/objectContainsNonSerializableProperty.test.js +49 -49
  137. package/src/utils/objectToFormData.js +89 -83
  138. package/src/utils/objectToFormData.test.js +76 -47
  139. package/src/utils/typeChecks.js +18 -18
  140. package/src/validators/index.js +2 -2
  141. package/src/validators/validators.js +93 -93
  142. package/src/validators/validators.test.js +79 -79
  143. package/CHANGELOG.json +0 -95
  144. package/CHANGELOG.md +0 -58
@@ -1,144 +1,145 @@
1
- import React from 'react';
2
- import classnames from 'classnames';
3
- import {
4
- Input as BootstrapInput,
5
- FormFeedback,
6
- CustomInput,
7
- FormText,
8
- Alert,
9
- } from 'reactstrap';
10
- import lru from 'lru-cache';
11
- import PropTypes from 'prop-types';
12
- import TextareaAutosize from 'react-textarea-autosize';
13
- import { useAxiosRequest } from 'envoc-request';
14
- import FormGroupWrapper from '../FormGroupWrapper';
15
- import DatePickerInput from '../DatePickerInput';
16
- import ReactSelectField from '../ReactSelectField';
17
- import useStandardFormInput from '../useStandardFormInput';
18
- import { FileInput, DropzoneFileInput } from '../FileInput';
19
-
20
- export default function FormInput(props) {
21
- const [input, meta] = useStandardFormInput(props);
22
- const { className, hide } = props;
23
- return (
24
- <StandardFieldGroup
25
- {...input}
26
- className={classnames({ 'd-none': hide }, className)}
27
- meta={meta}
28
- />
29
- );
30
- }
31
-
32
- FormInput.propTypes = {
33
- id: PropTypes.string,
34
- label: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
35
- name: PropTypes.string.isRequired,
36
- placeholder: PropTypes.string,
37
- helpText: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
38
- };
39
-
40
- function StandardFieldGroup(props) {
41
- switch (props.type) {
42
- case 'date':
43
- return <FormGroupWrapper {...props} Component={DatePicker} />;
44
- case 'select':
45
- if (props.optionsUrl) {
46
- return <FormGroupWrapper {...props} Component={RemoteSelect} />;
47
- } else {
48
- return <FormGroupWrapper {...props} Component={Select} />;
49
- }
50
- case 'checkbox':
51
- case 'radio':
52
- return Checkbox(props);
53
- case 'file':
54
- if (props.dropzone) {
55
- return <FormGroupWrapper {...props} Component={DropzoneFileInput} />;
56
- }
57
- return <FormGroupWrapper {...props} Component={FileInput} />;
58
- case 'textarea':
59
- return <FormGroupWrapper {...props} Component={TextAreaInput} />;
60
- default:
61
- return <FormGroupWrapper {...props} Component={DefaultInput} />;
62
- }
63
- }
64
-
65
- const TextAreaInput = ({ className, meta, helpText, ...props }) => {
66
- return (
67
- <TextareaAutosize
68
- cacheMeasurements
69
- className={classnames(
70
- className,
71
- 'form-control',
72
- meta.error ? 'is-invalid' : ''
73
- )}
74
- {...props}
75
- />
76
- );
77
- };
78
-
79
- const DefaultInput = ({ meta, ...props }) => {
80
- return <BootstrapInput invalid={!!meta.error} {...props} />;
81
- };
82
-
83
- const Select = ({ includeEmptyOption = true, options, ...props }) => {
84
- const allOptions = includeEmptyOption
85
- ? [{ label: ' ', value: null }, ...options]
86
- : options;
87
- return <ReactSelectField {...props} options={allOptions} />;
88
- };
89
-
90
- // low cache value just to prevent the same dropdown from hitting the API at the same time
91
- // TODO: global cache provider / "envoc-cache" instead of this static instance
92
- export const optionCache = new lru({ max: 500, maxAge: 1000 * 10 });
93
- const RemoteSelect = ({
94
- optionsUrl,
95
- includeEmptyOption = true,
96
- includeOtherOption = false,
97
- cache = optionCache,
98
- maxAge = 1000 * 10,
99
- ...props
100
- }) => {
101
- const request = {
102
- method: 'get',
103
- url: optionsUrl,
104
- cache: cache,
105
- maxAge: maxAge,
106
- autoExecute: true,
107
- };
108
- const webRequest = useAxiosRequest(request);
109
- if (webRequest.error) {
110
- return <Alert color="danger">An error occurred while loading.</Alert>;
111
- }
112
-
113
- const options = [];
114
-
115
- if (webRequest.loading) {
116
- options.push({ label: 'Loading...', value: '' });
117
- } else {
118
- if (includeEmptyOption) {
119
- options.push({ label: ' ', value: null });
120
- }
121
- options.push(...webRequest.resp.data.result);
122
- if (includeOtherOption) {
123
- options.push({ label: 'Other', value: 'other' });
124
- }
125
- }
126
-
127
- return <ReactSelectField {...props} options={options} />;
128
- };
129
-
130
- const DatePicker = ({ meta, ...props }) => {
131
- return (
132
- <DatePickerInput {...props} className={meta.error ? 'is-invalid' : ''} />
133
- );
134
- };
135
-
136
- const Checkbox = ({ helpText, meta, ...props }) => {
137
- return (
138
- <React.Fragment>
139
- <CustomInput {...props} />
140
- {meta.error && <FormFeedback>{meta.error}</FormFeedback>}
141
- {helpText && <FormText>{helpText}</FormText>}
142
- </React.Fragment>
143
- );
144
- };
1
+ import React from 'react';
2
+ import classnames from 'classnames';
3
+ import {
4
+ Input as BootstrapInput,
5
+ FormFeedback,
6
+ CustomInput,
7
+ FormText,
8
+ Alert,
9
+ } from 'reactstrap';
10
+ import lru from 'lru-cache';
11
+ import PropTypes from 'prop-types';
12
+ import TextareaAutosize from 'react-textarea-autosize';
13
+ import { useAxiosRequest } from 'envoc-request';
14
+ import FormGroupWrapper from '../FormGroupWrapper';
15
+ import DatePickerInput from '../DatePickerInput';
16
+ import ReactSelectField from '../ReactSelectField';
17
+ import useStandardFormInput from '../useStandardFormInput';
18
+ import { FileInput, DropzoneFileInput } from '../FileInput';
19
+
20
+ export default function FormInput(props) {
21
+ const [input, meta] = useStandardFormInput(props);
22
+ const { className, hide } = props;
23
+ return (
24
+ <StandardFieldGroup
25
+ {...input}
26
+ className={classnames({ 'd-none': hide }, className)}
27
+ meta={meta}
28
+ />
29
+ );
30
+ }
31
+
32
+ FormInput.propTypes = {
33
+ id: PropTypes.string,
34
+ label: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
35
+ name: PropTypes.string.isRequired,
36
+ placeholder: PropTypes.string,
37
+ helpText: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
38
+ };
39
+
40
+ function StandardFieldGroup(props) {
41
+ switch (props.type) {
42
+ case 'date':
43
+ return <FormGroupWrapper {...props} Component={DatePicker} />;
44
+ case 'select':
45
+ if (props.optionsUrl) {
46
+ return <FormGroupWrapper {...props} Component={RemoteSelect} />;
47
+ } else {
48
+ return <FormGroupWrapper {...props} Component={Select} />;
49
+ }
50
+ case 'checkbox':
51
+ case 'radio':
52
+ return Checkbox(props);
53
+ case 'file':
54
+ if (props.dropzone) {
55
+ return <FormGroupWrapper {...props} Component={DropzoneFileInput} />;
56
+ }
57
+ return <FormGroupWrapper {...props} Component={FileInput} />;
58
+ case 'textarea':
59
+ return <FormGroupWrapper {...props} Component={TextAreaInput} />;
60
+ default:
61
+ return <FormGroupWrapper {...props} Component={DefaultInput} />;
62
+ }
63
+ }
64
+
65
+ const TextAreaInput = ({ className, meta, helpText, ...props }) => {
66
+ return (
67
+ <TextareaAutosize
68
+ cacheMeasurements
69
+ className={classnames(
70
+ className,
71
+ 'form-control',
72
+ meta.error ? 'is-invalid' : ''
73
+ )}
74
+ {...props}
75
+ />
76
+ );
77
+ };
78
+
79
+ const DefaultInput = ({ meta, ...props }) => {
80
+ return <BootstrapInput invalid={!!meta.error} {...props} />;
81
+ };
82
+
83
+ const Select = ({ includeEmptyOption = true, options, ...props }) => {
84
+ const allOptions =
85
+ includeEmptyOption && !props.isMulti
86
+ ? [{ label: ' ', value: null }, ...options]
87
+ : options;
88
+ return <ReactSelectField {...props} options={allOptions} />;
89
+ };
90
+
91
+ // low cache value just to prevent the same dropdown from hitting the API at the same time
92
+ // TODO: global cache provider / "envoc-cache" instead of this static instance
93
+ export const optionCache = new lru({ max: 500, maxAge: 1000 * 10 });
94
+ const RemoteSelect = ({
95
+ optionsUrl,
96
+ includeEmptyOption = true,
97
+ includeOtherOption = false,
98
+ cache = optionCache,
99
+ maxAge = 1000 * 10,
100
+ ...props
101
+ }) => {
102
+ const request = {
103
+ method: 'get',
104
+ url: optionsUrl,
105
+ cache: cache,
106
+ maxAge: maxAge,
107
+ autoExecute: true,
108
+ };
109
+ const webRequest = useAxiosRequest(request);
110
+ if (webRequest.error) {
111
+ return <Alert color="danger">An error occurred while loading.</Alert>;
112
+ }
113
+
114
+ const options = [];
115
+
116
+ if (webRequest.loading) {
117
+ options.push({ label: 'Loading...', value: '' });
118
+ } else {
119
+ if (includeEmptyOption && !props.isMulti) {
120
+ options.push({ label: ' ', value: null });
121
+ }
122
+ options.push(...webRequest.resp.data.result);
123
+ if (includeOtherOption) {
124
+ options.push({ label: 'Other', value: 'other' });
125
+ }
126
+ }
127
+
128
+ return <ReactSelectField {...props} options={options} />;
129
+ };
130
+
131
+ const DatePicker = ({ meta, ...props }) => {
132
+ return (
133
+ <DatePickerInput {...props} className={meta.error ? 'is-invalid' : ''} />
134
+ );
135
+ };
136
+
137
+ const Checkbox = ({ helpText, meta, ...props }) => {
138
+ return (
139
+ <React.Fragment>
140
+ <CustomInput {...props} />
141
+ {meta.error && <FormFeedback>{meta.error}</FormFeedback>}
142
+ {helpText && <FormText>{helpText}</FormText>}
143
+ </React.Fragment>
144
+ );
145
+ };
@@ -1,66 +1,66 @@
1
- import React from 'react';
2
- import { render, screen } from '@testing-library/react';
3
- import '@testing-library/jest-dom/extend-expect';
4
- import { FormTestBase } from '../__Tests__';
5
- import FormInput from './FormInput';
6
- HTMLCanvasElement.prototype.getContext = () => {};
7
-
8
- describe('FormInput', () => {
9
- it('renders without crashing', () => {
10
- render(
11
- <FormTestBase>
12
- <FormInput name="test" />
13
- </FormTestBase>
14
- );
15
- });
16
-
17
- it('has matching datepicker snapshot', () => {
18
- const renderResult = render(
19
- <FormTestBase>
20
- <FormInput
21
- name="test"
22
- minDate={new Date('9/23/2020')}
23
- maxDate={new Date('09/23/2021')}
24
- type="date"
25
- />
26
- </FormTestBase>
27
- );
28
- expect(renderResult.asFragment()).toMatchSnapshot();
29
- });
30
-
31
- it('has matching textarea snapshot', () => {
32
- const renderResult = render(
33
- <FormTestBase>
34
- <FormInput name="test" type="textarea" />
35
- </FormTestBase>
36
- );
37
- expect(renderResult.asFragment()).toMatchSnapshot();
38
- });
39
-
40
- it('has matching checkbox snapshot', () => {
41
- const renderResult = render(
42
- <FormTestBase>
43
- <FormInput name="test" type="checkbox" />
44
- </FormTestBase>
45
- );
46
- expect(renderResult.asFragment()).toMatchSnapshot();
47
- });
48
-
49
- it('has matching file input snapshot', () => {
50
- const renderResult = render(
51
- <FormTestBase>
52
- <FormInput name="test" type="file" />
53
- </FormTestBase>
54
- );
55
- expect(renderResult.asFragment()).toMatchSnapshot();
56
- });
57
-
58
- it('has matching select snapshot', () => {
59
- const renderResult = render(
60
- <FormTestBase>
61
- <FormInput name="test" type="select" options={[]} />
62
- </FormTestBase>
63
- );
64
- expect(renderResult.asFragment()).toMatchSnapshot();
65
- });
66
- });
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import '@testing-library/jest-dom/extend-expect';
4
+ import { FormTestBase } from '../__Tests__';
5
+ import FormInput from './FormInput';
6
+ HTMLCanvasElement.prototype.getContext = () => {};
7
+
8
+ describe('FormInput', () => {
9
+ it('renders without crashing', () => {
10
+ render(
11
+ <FormTestBase>
12
+ <FormInput name="test" />
13
+ </FormTestBase>
14
+ );
15
+ });
16
+
17
+ it('has matching datepicker snapshot', () => {
18
+ const renderResult = render(
19
+ <FormTestBase>
20
+ <FormInput
21
+ name="test"
22
+ minDate={new Date('9/23/2020')}
23
+ maxDate={new Date('09/23/2021')}
24
+ type="date"
25
+ />
26
+ </FormTestBase>
27
+ );
28
+ expect(renderResult.asFragment()).toMatchSnapshot();
29
+ });
30
+
31
+ it('has matching textarea snapshot', () => {
32
+ const renderResult = render(
33
+ <FormTestBase>
34
+ <FormInput name="test" type="textarea" />
35
+ </FormTestBase>
36
+ );
37
+ expect(renderResult.asFragment()).toMatchSnapshot();
38
+ });
39
+
40
+ it('has matching checkbox snapshot', () => {
41
+ const renderResult = render(
42
+ <FormTestBase>
43
+ <FormInput name="test" type="checkbox" />
44
+ </FormTestBase>
45
+ );
46
+ expect(renderResult.asFragment()).toMatchSnapshot();
47
+ });
48
+
49
+ it('has matching file input snapshot', () => {
50
+ const renderResult = render(
51
+ <FormTestBase>
52
+ <FormInput name="test" type="file" />
53
+ </FormTestBase>
54
+ );
55
+ expect(renderResult.asFragment()).toMatchSnapshot();
56
+ });
57
+
58
+ it('has matching select snapshot', () => {
59
+ const renderResult = render(
60
+ <FormTestBase>
61
+ <FormInput name="test" type="select" options={[]} />
62
+ </FormTestBase>
63
+ );
64
+ expect(renderResult.asFragment()).toMatchSnapshot();
65
+ });
66
+ });