envoc-form 2.0.1-7 → 2.0.1

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 (143) 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 +7 -6
  5. package/es/ConfirmBaseForm/ConfirmBaseForm.js +3 -2
  6. package/es/ConfirmDeleteForm/ConfirmDeleteForm.js +2 -1
  7. package/es/DatePickerInput/DatePickerInput.js +22 -5
  8. package/es/FileInput/DefaultFileList.js +12 -8
  9. package/es/FileInput/DropzoneFileInput.js +24 -23
  10. package/es/FileInput/FileInput.js +31 -9
  11. package/es/Form/Form.js +4 -2
  12. package/es/FormGroupWrapper.js +2 -1
  13. package/es/FormInput/FormInput.js +12 -6
  14. package/es/FormInputArray/FormInputArray.js +39 -24
  15. package/es/IconInput.js +2 -1
  16. package/es/ReactSelectField/ReactSelectField.js +6 -3
  17. package/es/SubmitFormButton.js +2 -1
  18. package/es/__Tests__/FormTestBase.js +5 -2
  19. package/es/normalizers.js +10 -5
  20. package/es/useStandardFormInput.js +4 -2
  21. package/es/utils/objectToFormData.js +10 -2
  22. package/lib/AddressInput/AddressInput.js +14 -8
  23. package/lib/ConfirmBaseForm/ConfirmBaseForm.js +4 -2
  24. package/lib/ConfirmDeleteForm/ConfirmDeleteForm.js +3 -1
  25. package/lib/DatePickerInput/DatePickerInput.js +25 -5
  26. package/lib/FileInput/DefaultFileList.js +20 -13
  27. package/lib/FileInput/DropzoneFileInput.js +25 -25
  28. package/lib/FileInput/FileInput.js +39 -10
  29. package/lib/Form/Form.js +11 -4
  30. package/lib/Form/FormBasedPreventNavigation.js +5 -1
  31. package/lib/FormGroupWrapper.js +3 -1
  32. package/lib/FormInput/FormInput.js +13 -6
  33. package/lib/FormInputArray/FormInputArray.js +47 -26
  34. package/lib/FormSection.js +5 -1
  35. package/lib/IconInput.js +3 -1
  36. package/lib/ReactSelectField/ReactSelectField.js +13 -5
  37. package/lib/ReactSelectField/index.js +6 -2
  38. package/lib/SubmitFormButton.js +3 -1
  39. package/lib/__Tests__/FormTestBase.js +6 -2
  40. package/lib/index.js +7 -3
  41. package/lib/normalizers.js +10 -5
  42. package/lib/useStandardFormInput.js +5 -2
  43. package/lib/utils/objectToFormData.js +10 -2
  44. package/lib/validators/index.js +5 -1
  45. package/package.json +99 -93
  46. package/src/AddressInput/AddesssInput.test.js +23 -23
  47. package/src/AddressInput/AddressInput.js +73 -73
  48. package/src/AddressInput/UsStates.js +53 -53
  49. package/src/AddressInput/__snapshots__/AddesssInput.test.js.snap +207 -207
  50. package/src/AddressInput/index.js +2 -2
  51. package/src/BoolInput/BoolInput.js +7 -7
  52. package/src/BoolInput/BoolInput.test.js +23 -23
  53. package/src/BoolInput/InlineBoolInput.js +7 -7
  54. package/src/BoolInput/__snapshots__/BoolInput.test.js.snap +89 -89
  55. package/src/BoolInput/boolOptions.js +6 -6
  56. package/src/BoolInput/index.js +4 -4
  57. package/src/ConfirmBaseForm/ConfirmBaseForm.js +37 -37
  58. package/src/ConfirmBaseForm/ConfirmBaseForm.test.js +14 -14
  59. package/src/ConfirmBaseForm/__snapshots__/ConfirmBaseForm.test.js.snap +23 -23
  60. package/src/ConfirmBaseForm/index.js +1 -1
  61. package/src/ConfirmDeleteForm/ConfirmDeleteForm.js +39 -39
  62. package/src/ConfirmDeleteForm/ConfirmDeleteForm.test.js +24 -24
  63. package/src/ConfirmDeleteForm/__snapshots__/ConfirmDeleteForm.test.js.snap +25 -25
  64. package/src/ConfirmDeleteForm/index.js +1 -1
  65. package/src/DatePickerInput/DatePickerInput.js +58 -46
  66. package/src/DatePickerInput/DatePickerInput.test.js +74 -74
  67. package/src/DatePickerInput/__snapshots__/DatePickerInput.test.js.snap +134 -134
  68. package/src/DatePickerInput/date-picker-input.scss +42 -42
  69. package/src/DatePickerInput/index.js +3 -3
  70. package/src/ErrorScrollTarget.js +6 -6
  71. package/src/FileInput/DefaultFileList.js +39 -39
  72. package/src/FileInput/DropzoneFileInput.js +56 -59
  73. package/src/FileInput/DropzoneFileInput.test.js +24 -0
  74. package/src/FileInput/FileInput.js +77 -49
  75. package/src/FileInput/FileInput.test.js +24 -15
  76. package/src/FileInput/__snapshots__/DropzoneFileInput.test.js.snap +57 -0
  77. package/src/FileInput/__snapshots__/FileInput.test.js.snap +58 -22
  78. package/src/FileInput/file-input.scss +58 -17
  79. package/src/FileInput/index.js +4 -4
  80. package/src/Form/FocusError.js +48 -48
  81. package/src/Form/Form.js +139 -138
  82. package/src/Form/Form.test.js +23 -23
  83. package/src/Form/FormBasedPreventNavigation.js +25 -25
  84. package/src/Form/ServerErrorContext.js +7 -7
  85. package/src/Form/__snapshots__/Form.test.js.snap +9 -9
  86. package/src/Form/index.js +3 -3
  87. package/src/FormGroup.js +30 -30
  88. package/src/FormGroupWrapper.js +28 -28
  89. package/src/FormInput/FormInput.js +144 -144
  90. package/src/FormInput/FormInput.test.js +66 -66
  91. package/src/FormInput/__snapshots__/FormInput.test.js.snap +323 -316
  92. package/src/FormInput/form-input.scss +9 -9
  93. package/src/FormInput/index.js +2 -2
  94. package/src/FormInputArray/FormInputArray.js +224 -210
  95. package/src/FormInputArray/FormInputArray.test.js +108 -59
  96. package/src/FormInputArray/__snapshots__/FormInputArray.test.js.snap +52 -40
  97. package/src/FormInputArray/form-input-array.scss +13 -8
  98. package/src/FormInputArray/index.js +2 -2
  99. package/src/FormSection.js +13 -13
  100. package/src/IconInput.js +31 -31
  101. package/src/InlineFormInput/InlineFormInput.js +6 -6
  102. package/src/InlineFormInput/InlineFormInput.test.js +23 -23
  103. package/src/InlineFormInput/__snapshots__/InlineFormInput.test.js.snap +26 -26
  104. package/src/InlineFormInput/index.js +3 -3
  105. package/src/InlineFormInput/inline-form-input.scss +3 -3
  106. package/src/MoneyInput/InlineMoneyInput.js +7 -7
  107. package/src/MoneyInput/MoneyInput.js +7 -7
  108. package/src/MoneyInput/MoneyInputs.test.js +43 -43
  109. package/src/MoneyInput/__snapshots__/MoneyInputs.test.js.snap +81 -81
  110. package/src/MoneyInput/index.js +4 -4
  111. package/src/MoneyInput/money-input.scss +3 -3
  112. package/src/MoneyInput/moneyInputProps.js +12 -12
  113. package/src/NestedFormFieldContext.js +6 -6
  114. package/src/ReactSelectField/ReactSelectField.js +122 -120
  115. package/src/ReactSelectField/index.js +6 -6
  116. package/src/ReactSelectField/react-select-field.scss +5 -5
  117. package/src/StandardFormActions.js +27 -27
  118. package/src/SubmitFormButton.js +28 -28
  119. package/src/__Tests__/FormTestBase.js +14 -11
  120. package/src/__Tests__/IconInput.test.js +23 -23
  121. package/src/__Tests__/StandardFormActions.test.js +23 -23
  122. package/src/__Tests__/SubmitFormButton.test.js +23 -23
  123. package/src/__Tests__/__snapshots__/IconInput.test.js.snap +38 -38
  124. package/src/__Tests__/__snapshots__/StandardFormActions.test.js.snap +25 -25
  125. package/src/__Tests__/__snapshots__/SubmitFormButton.test.js.snap +18 -18
  126. package/src/__Tests__/index.js +2 -2
  127. package/src/_variables.scss +11 -11
  128. package/src/index.js +33 -33
  129. package/src/normalizers.js +42 -32
  130. package/src/selectors.js +3 -3
  131. package/src/styles.scss +7 -7
  132. package/src/useStandardFormInput.js +118 -118
  133. package/src/utils/index.js +3 -3
  134. package/src/utils/objectContainsNonSerializableProperty.js +15 -15
  135. package/src/utils/objectContainsNonSerializableProperty.test.js +49 -49
  136. package/src/utils/objectToFormData.js +89 -83
  137. package/src/utils/objectToFormData.test.js +76 -47
  138. package/src/utils/typeChecks.js +18 -18
  139. package/src/validators/index.js +2 -2
  140. package/src/validators/validators.js +93 -93
  141. package/src/validators/validators.test.js +79 -79
  142. package/CHANGELOG.json +0 -95
  143. package/CHANGELOG.md +0 -58
@@ -1,59 +1,56 @@
1
- import './file-input.scss';
2
- import React, { useMemo } from 'react';
3
- import { useDropzone } from 'react-dropzone';
4
- import classNames from 'classnames';
5
- import DefaultFileList from './DefaultFileList';
6
-
7
- export default function DropzoneFileInput({
8
- className,
9
- onChange,
10
- value,
11
- accept,
12
- disabled,
13
- multiple,
14
- FileList = DefaultFileList,
15
- placeholder = "Drag 'n' drop some files here, or click to select files",
16
- ...props
17
- }) {
18
- const {
19
- acceptedFiles,
20
- fileRejections,
21
- getRootProps,
22
- getInputProps,
23
- isDragAccept,
24
- isDragReject,
25
- } = useDropzone({ accept, onDrop, disabled: disabled });
26
-
27
- function onDrop(acceptedFiles) {
28
- if (acceptedFiles?.length) {
29
- onChange(null);
30
- } else if (multiple) {
31
- onChange(acceptedFiles);
32
- } else {
33
- const target = acceptedFiles[0];
34
- onChange(target);
35
- }
36
- }
37
-
38
- const classNameProp = useMemo(
39
- () =>
40
- classNames('react-dropzone', {
41
- accept: isDragAccept,
42
- reject: isDragReject,
43
- disabled: disabled,
44
- }),
45
- [isDragAccept, isDragReject, disabled]
46
- );
47
-
48
- return (
49
- <section className={classNameProp}>
50
- <div {...getRootProps()}>
51
- <input {...props} {...getInputProps()} />
52
- <>{placeholder}</>
53
- </div>
54
- <aside>
55
- <FileList files={acceptedFiles} rejectedFiles={fileRejections} />
56
- </aside>
57
- </section>
58
- );
59
- }
1
+ import React from 'react';
2
+ import { useDropzone } from 'react-dropzone';
3
+ import classNames from 'classnames';
4
+ import DefaultFileList from './DefaultFileList';
5
+
6
+ export default function DropzoneFileInput({
7
+ className: classNameProp,
8
+ onChange,
9
+ value,
10
+ accept,
11
+ disabled,
12
+ multiple = false,
13
+ FileList = DefaultFileList,
14
+ placeholder = 'Drag and drop some file(s) here, or click to select file(s)',
15
+ dropzone,
16
+ ...props
17
+ }) {
18
+ const {
19
+ acceptedFiles = (acceptedFiles = acceptedFiles[0]),
20
+ fileRejections = fileRejections.push(
21
+ acceptedFiles.slice(1, acceptedFiles.length)
22
+ ),
23
+ getRootProps,
24
+ getInputProps,
25
+ isDragAccept,
26
+ isDragReject,
27
+ } = useDropzone({ accept, onDrop, disabled: disabled, multiple: multiple });
28
+
29
+ function onDrop(acceptedFiles) {
30
+ if (!acceptedFiles?.length > 1 && !multiple) {
31
+ onChange(null);
32
+ } else {
33
+ onChange(acceptedFiles);
34
+ }
35
+ }
36
+
37
+ const className = classNames('react-dropzone', classNameProp, {
38
+ accept: isDragAccept,
39
+ reject: isDragReject,
40
+ disabled: disabled,
41
+ });
42
+
43
+ return (
44
+ <section className={className}>
45
+ <div {...getRootProps()}>
46
+ <input {...props} {...getInputProps()} />
47
+ <>{placeholder}</>
48
+ {!multiple && <b>{`Only one file accepted.`}</b>}
49
+ {accept && <b>{`Files of type "${accept}" accepted`}</b>}
50
+ </div>
51
+ <aside>
52
+ <FileList files={acceptedFiles} rejectedFiles={fileRejections} />
53
+ </aside>
54
+ </section>
55
+ );
56
+ }
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+
4
+ import DropzoneFileInput from './DropzoneFileInput';
5
+
6
+ describe('DropZoneFileInput', () => {
7
+ it('Renders without error', () => {
8
+ render(<DropzoneFileInput name="myFile" />);
9
+ });
10
+
11
+ it('Renders multiple file without error', () => {
12
+ render(<DropzoneFileInput name="myFile" multiple />);
13
+ });
14
+
15
+ it('has matching snapshot', () => {
16
+ const renderResult = render(<DropzoneFileInput name="myFile" />);
17
+ expect(renderResult.asFragment()).toMatchSnapshot();
18
+ });
19
+
20
+ it('Multiple file input has matching snapshot', () => {
21
+ const renderResult = render(<DropzoneFileInput name="myFile" multiple />);
22
+ expect(renderResult.asFragment()).toMatchSnapshot();
23
+ });
24
+ });
@@ -1,49 +1,77 @@
1
- import React, { useEffect, useRef } from 'react';
2
-
3
- export default function FileInput({ className, onChange, value, ...props }) {
4
- const inputRef = useRef();
5
- useEffect(() => {
6
- if (!value && inputRef.current) {
7
- inputRef.current.value = null;
8
- }
9
- }, [value]);
10
- return (
11
- <div
12
- className={`custom-file file-input ${className || ''} ${
13
- props.disabled ? 'disabled' : ''
14
- }`}>
15
- <input
16
- ref={inputRef}
17
- type="file"
18
- className="custom-file-input"
19
- onChange={handleChange}
20
- {...props}
21
- />
22
- <label className="custom-file-label">
23
- {!value && <span>Choose A File...</span>}
24
- {value && (
25
- <span>
26
- {value.name} - size: {humanFileSize(value.size)}
27
- </span>
28
- )}
29
- </label>
30
- </div>
31
- );
32
- function handleChange(e) {
33
- if (e == null || !e.target || !e.target.files.length) {
34
- onChange(null);
35
- } else {
36
- const target = e.target.files[0];
37
- onChange(target);
38
- }
39
- }
40
- }
41
-
42
- function humanFileSize(size) {
43
- const i = Math.floor(Math.log(size) / Math.log(1024));
44
- return (
45
- (size / Math.pow(1024, i)).toFixed(2) * 1 +
46
- ' ' +
47
- ['B', 'KB', 'MB', 'GB', 'TB'][i]
48
- );
49
- }
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import DefaultFileList from './DefaultFileList';
3
+
4
+ export default function FileInput({
5
+ className,
6
+ onChange,
7
+ value,
8
+ multiple = false,
9
+ ...props
10
+ }) {
11
+ const inputRef = useRef();
12
+ const [acceptedFiles, setAcceptedFiles] = useState([]);
13
+ useEffect(() => {
14
+ if (!value && inputRef.current) {
15
+ inputRef.current.value = null;
16
+ }
17
+ }, [value]);
18
+ return (
19
+ <>
20
+ <div
21
+ className={`custom-file file-input ${className || ''} ${
22
+ props.disabled ? 'disabled' : ''
23
+ }`}>
24
+ <div>
25
+ <input
26
+ ref={inputRef}
27
+ type="file"
28
+ className="custom-file-input"
29
+ onChange={handleChange}
30
+ multiple={multiple}
31
+ {...props}
32
+ />
33
+ </div>
34
+ <label className="custom-file-label">
35
+ <div>
36
+ {!value && <span>Choose A File...</span>}
37
+ {value &&
38
+ (!multiple ? (
39
+ <span>
40
+ {value.name} - size: {humanFileSize(value.size)}
41
+ </span>
42
+ ) : value.length === 1 ? (
43
+ <span>
44
+ {value[0].name} - size: {humanFileSize(value[0].size)}
45
+ </span>
46
+ ) : (
47
+ <span>Multiple files selected.</span>
48
+ ))}
49
+ </div>
50
+ </label>
51
+ </div>
52
+ <DefaultFileList files={acceptedFiles} />
53
+ </>
54
+ );
55
+ function handleChange(e) {
56
+ if (e == null || !e.target || !e.target.files.length) {
57
+ onChange(null);
58
+ } else {
59
+ const files = [...e.target.files];
60
+ setAcceptedFiles(files);
61
+ if (!multiple) {
62
+ onChange(files[0]);
63
+ } else {
64
+ onChange(files);
65
+ }
66
+ }
67
+ }
68
+ }
69
+
70
+ function humanFileSize(size) {
71
+ const i = Math.floor(Math.log(size) / Math.log(1024));
72
+ return (
73
+ (size / Math.pow(1024, i)).toFixed(2) * 1 +
74
+ ' ' +
75
+ ['B', 'KB', 'MB', 'GB', 'TB'][i]
76
+ );
77
+ }
@@ -1,15 +1,24 @@
1
- import React from 'react';
2
- import { render, screen } from '@testing-library/react';
3
-
4
- import FileInput from './FileInput';
5
-
6
- describe('FileInput', () => {
7
- it('Renders without error', () => {
8
- render(<FileInput name="myFile" />);
9
- });
10
-
11
- it('has matching snapshot', () => {
12
- const renderResult = render(<FileInput name="myFile" />);
13
- expect(renderResult.asFragment()).toMatchSnapshot();
14
- });
15
- });
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+
4
+ import FileInput from './FileInput';
5
+
6
+ describe('FileInput', () => {
7
+ it('Renders without error', () => {
8
+ render(<FileInput name="myFile" />);
9
+ });
10
+
11
+ it('Renders multiple files without error', () => {
12
+ render(<FileInput name="myFile" multiple />);
13
+ });
14
+
15
+ it('has matching snapshot', () => {
16
+ const renderResult = render(<FileInput name="myFile" />);
17
+ expect(renderResult.asFragment()).toMatchSnapshot();
18
+ });
19
+
20
+ it('multiple files has matching snapshot', () => {
21
+ const renderResult = render(<FileInput name="myFile" multiple />);
22
+ expect(renderResult.asFragment()).toMatchSnapshot();
23
+ });
24
+ });
@@ -0,0 +1,57 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`DropZoneFileInput Multiple file input has matching snapshot 1`] = `
4
+ <DocumentFragment>
5
+ <section
6
+ class="react-dropzone"
7
+ >
8
+ <div
9
+ tabindex="0"
10
+ >
11
+ <input
12
+ autocomplete="off"
13
+ multiple=""
14
+ name="myFile"
15
+ style="display: none;"
16
+ tabindex="-1"
17
+ type="file"
18
+ />
19
+ Drag and drop some file(s) here, or click to select file(s)
20
+ </div>
21
+ <aside>
22
+ <ul
23
+ class="list-group"
24
+ />
25
+ </aside>
26
+ </section>
27
+ </DocumentFragment>
28
+ `;
29
+
30
+ exports[`DropZoneFileInput has matching snapshot 1`] = `
31
+ <DocumentFragment>
32
+ <section
33
+ class="react-dropzone"
34
+ >
35
+ <div
36
+ tabindex="0"
37
+ >
38
+ <input
39
+ autocomplete="off"
40
+ name="myFile"
41
+ style="display: none;"
42
+ tabindex="-1"
43
+ type="file"
44
+ />
45
+ Drag and drop some file(s) here, or click to select file(s)
46
+ <b>
47
+ Only one file accepted.
48
+ </b>
49
+ </div>
50
+ <aside>
51
+ <ul
52
+ class="list-group"
53
+ />
54
+ </aside>
55
+ </section>
56
+ </DocumentFragment>
57
+ `;
@@ -1,22 +1,58 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`FileInput has matching snapshot 1`] = `
4
- <DocumentFragment>
5
- <div
6
- class="custom-file file-input "
7
- >
8
- <input
9
- class="custom-file-input"
10
- name="myFile"
11
- type="file"
12
- />
13
- <label
14
- class="custom-file-label"
15
- >
16
- <span>
17
- Choose A File...
18
- </span>
19
- </label>
20
- </div>
21
- </DocumentFragment>
22
- `;
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`FileInput has matching snapshot 1`] = `
4
+ <DocumentFragment>
5
+ <div
6
+ class="custom-file file-input "
7
+ >
8
+ <div>
9
+ <input
10
+ class="custom-file-input"
11
+ name="myFile"
12
+ type="file"
13
+ />
14
+ </div>
15
+ <label
16
+ class="custom-file-label"
17
+ >
18
+ <div>
19
+ <span>
20
+ Choose A File...
21
+ </span>
22
+ </div>
23
+ </label>
24
+ </div>
25
+ <ul
26
+ class="list-group"
27
+ />
28
+ </DocumentFragment>
29
+ `;
30
+
31
+ exports[`FileInput multiple files has matching snapshot 1`] = `
32
+ <DocumentFragment>
33
+ <div
34
+ class="custom-file file-input "
35
+ >
36
+ <div>
37
+ <input
38
+ class="custom-file-input"
39
+ multiple=""
40
+ name="myFile"
41
+ type="file"
42
+ />
43
+ </div>
44
+ <label
45
+ class="custom-file-label"
46
+ >
47
+ <div>
48
+ <span>
49
+ Choose A File...
50
+ </span>
51
+ </div>
52
+ </label>
53
+ </div>
54
+ <ul
55
+ class="list-group"
56
+ />
57
+ </DocumentFragment>
58
+ `;
@@ -1,17 +1,58 @@
1
- @import '../variables';
2
-
3
- .file-input {
4
- &.is-invalid {
5
- .custom-file-label {
6
- border: 1px solid $red;
7
- }
8
- }
9
- }
10
-
11
- .custom-file-input:disabled ~ .custom-file-label {
12
- background-color: $input-disabled-background-color;
13
- border-color: $input-disabled-border-color;
14
- &:after {
15
- display: none !important;
16
- }
17
- }
1
+ @import '../variables';
2
+
3
+ .file-input {
4
+ &.is-invalid {
5
+ .custom-file-label {
6
+ border: 1px solid $red;
7
+ }
8
+ }
9
+ }
10
+
11
+ .custom-file-input:disabled ~ .custom-file-label {
12
+ background-color: $input-disabled-background-color;
13
+ border-color: $input-disabled-border-color;
14
+ &:after {
15
+ display: none !important;
16
+ }
17
+ }
18
+
19
+ section.react-dropzone {
20
+ & > div {
21
+ display: flex;
22
+ flex: 1;
23
+ flex-direction: column;
24
+ align-items: center;
25
+ border: 1px dashed #d8dbe0;
26
+ border-radius: 0.25rem;
27
+ background-color: white;
28
+ color: #8a93a2;
29
+ outline: none;
30
+ margin: 0;
31
+ padding: 20px;
32
+ transition: 'border .24s ease-in-out';
33
+ cursor: pointer;
34
+ &:focus,
35
+ &:focus-within {
36
+ border-color: #958bef;
37
+ box-shadow: 0 0 0 0.2rem rgba(50, 31, 219, 0.25);
38
+ }
39
+ }
40
+ &.active > div,
41
+ &.accept > div {
42
+ border-color: #958bef;
43
+ box-shadow: 0 0 0 0.2rem rgba(50, 31, 219, 0.25);
44
+ }
45
+ &.reject > div {
46
+ color: rgb(229, 83, 83);
47
+ border-color: rgb(229, 83, 83);
48
+ box-shadow: rgba(229, 83, 83, 0.25) 0px 0px 0px 3.2px;
49
+ }
50
+ &.disabled > div {
51
+ background-color: $input-disabled-background-color;
52
+ border-color: $input-disabled-border-color;
53
+ cursor: no-drop;
54
+ }
55
+ & > aside > .list-group:not(:empty) {
56
+ margin-top: 1rem;
57
+ }
58
+ }
@@ -1,4 +1,4 @@
1
- import FileInput from './FileInput';
2
- import DropzoneFileInput from './DropzoneFileInput';
3
-
4
- export { FileInput, DropzoneFileInput };
1
+ import FileInput from './FileInput';
2
+ import DropzoneFileInput from './DropzoneFileInput';
3
+
4
+ export { FileInput, DropzoneFileInput };
@@ -1,48 +1,48 @@
1
- import { useEffect } from 'react';
2
- import { useFormikContext } from 'formik';
3
- import smoothscroll from 'smoothscroll-polyfill';
4
-
5
- export default function FocusError(props) {
6
- const { errors, isSubmitting, isValidating } = useFormikContext();
7
- smoothscroll.polyfill();
8
- useEffect(() => {
9
- if (!isSubmitting || isValidating) {
10
- return;
11
- }
12
- //This block handles any front-end input validation errors
13
- //e.g. required fields, max characters, etc
14
- const keys = Object.keys(errors);
15
- if (keys.length > 0) {
16
- return scrollToErrorElement(keys);
17
- }
18
- //This block handles any input-specific server-side errors
19
- //e.g. improper email formatting, invalid phone number, etc.
20
- if (
21
- props.serverErrors.errors &&
22
- Object.values(props.serverErrors.errors).some((x) => !!x)
23
- ) {
24
- const names = Object.keys(props.serverErrors.errors);
25
- return scrollToErrorElement(names);
26
- }
27
- }, [errors, isSubmitting, isValidating, props]);
28
- return null;
29
- }
30
-
31
- const scrollToErrorElement = (keys) => {
32
- let firstErrorElement = document.getElementById(
33
- `${keys[0].toLowerCase()}-error-scroll-target`
34
- );
35
- if (firstErrorElement == null || firstErrorElement.parentNode == null) {
36
- return;
37
- }
38
- firstErrorElement = firstErrorElement.parentNode;
39
- const headerOffset = -110;
40
- const y =
41
- firstErrorElement.getBoundingClientRect().top +
42
- window.pageYOffset +
43
- headerOffset;
44
- window.scrollTo({ top: y, behavior: 'smooth' });
45
- setTimeout(() => {
46
- firstErrorElement.focus();
47
- }, 500);
48
- };
1
+ import { useEffect } from 'react';
2
+ import { useFormikContext } from 'formik';
3
+ import smoothscroll from 'smoothscroll-polyfill';
4
+
5
+ export default function FocusError(props) {
6
+ const { errors, isSubmitting, isValidating } = useFormikContext();
7
+ smoothscroll.polyfill();
8
+ useEffect(() => {
9
+ if (!isSubmitting || isValidating) {
10
+ return;
11
+ }
12
+ //This block handles any front-end input validation errors
13
+ //e.g. required fields, max characters, etc
14
+ const keys = Object.keys(errors);
15
+ if (keys.length > 0) {
16
+ return scrollToErrorElement(keys);
17
+ }
18
+ //This block handles any input-specific server-side errors
19
+ //e.g. improper email formatting, invalid phone number, etc.
20
+ if (
21
+ props.serverErrors.errors &&
22
+ Object.values(props.serverErrors.errors).some((x) => !!x)
23
+ ) {
24
+ const names = Object.keys(props.serverErrors.errors);
25
+ return scrollToErrorElement(names);
26
+ }
27
+ }, [errors, isSubmitting, isValidating, props]);
28
+ return null;
29
+ }
30
+
31
+ const scrollToErrorElement = (keys) => {
32
+ let firstErrorElement = document.getElementById(
33
+ `${keys[0].toLowerCase()}-error-scroll-target`
34
+ );
35
+ if (firstErrorElement == null || firstErrorElement.parentNode == null) {
36
+ return;
37
+ }
38
+ firstErrorElement = firstErrorElement.parentNode;
39
+ const headerOffset = -110;
40
+ const y =
41
+ firstErrorElement.getBoundingClientRect().top +
42
+ window.pageYOffset +
43
+ headerOffset;
44
+ window.scrollTo({ top: y, behavior: 'smooth' });
45
+ setTimeout(() => {
46
+ firstErrorElement.focus();
47
+ }, 500);
48
+ };