@popsure/dirty-swan 0.57.9 → 0.58.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.
- package/dist/cjs/index.js +65 -29
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/components/multiDropzone/utils/index.d.ts +9 -2
- package/dist/esm/{TableSection-a26ba0c5.js → TableSection-ebace923.js} +1 -1
- package/dist/esm/{TableSection-a26ba0c5.js.map → TableSection-ebace923.js.map} +1 -1
- package/dist/esm/components/comparisonTable/components/TableInfoButton/index.js +1 -1
- package/dist/esm/components/comparisonTable/components/TableInfoButton/index.js.map +1 -1
- package/dist/esm/components/input/checkbox/index.js +5 -2
- package/dist/esm/components/input/checkbox/index.js.map +1 -1
- package/dist/esm/components/input/index.js +4 -2
- package/dist/esm/components/input/index.js.map +1 -1
- package/dist/esm/components/multiDropzone/UploadFileCell/index.js +6 -7
- package/dist/esm/components/multiDropzone/UploadFileCell/index.js.map +1 -1
- package/dist/esm/components/multiDropzone/index.js +51 -17
- package/dist/esm/components/multiDropzone/index.js.map +1 -1
- package/dist/esm/components/multiDropzone/index.stories.js +1 -0
- package/dist/esm/components/multiDropzone/index.stories.js.map +1 -1
- package/dist/esm/components/multiDropzone/index.test.js +1 -0
- package/dist/esm/components/multiDropzone/index.test.js.map +1 -1
- package/dist/esm/components/table/Table.js +1 -1
- package/dist/esm/components/table/Table.stories.js +1 -1
- package/dist/esm/components/table/Table.test.js +1 -1
- package/dist/esm/components/table/components/TableContents/TableContents.js +1 -1
- package/dist/esm/components/table/components/TableContents/TableContents.test.js +1 -1
- package/dist/esm/components/table/components/TableSection/TableSection.js +1 -1
- package/dist/esm/components/table/components/TableSection/TableSection.test.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/lib/components/multiDropzone/utils/index.d.ts +9 -2
- package/package.json +1 -1
- package/src/lib/components/comparisonTable/components/TableInfoButton/index.tsx +2 -0
- package/src/lib/components/input/checkbox/index.tsx +8 -2
- package/src/lib/components/input/index.tsx +20 -13
- package/src/lib/components/multiDropzone/UploadFileCell/index.tsx +25 -19
- package/src/lib/components/multiDropzone/UploadFileCell/style.module.scss +11 -29
- package/src/lib/components/multiDropzone/index.tsx +17 -5
- package/src/lib/components/multiDropzone/style.module.scss +12 -9
- package/src/lib/components/multiDropzone/utils/index.test.ts +128 -45
- package/src/lib/components/multiDropzone/utils/index.ts +89 -36
|
@@ -1,53 +1,56 @@
|
|
|
1
1
|
import { ErrorCode } from 'react-dropzone';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
3
|
formatAcceptFileList,
|
|
4
4
|
getErrorMessage,
|
|
5
|
-
getFormattedAcceptObject,
|
|
6
|
-
|
|
5
|
+
getFormattedAcceptObject,
|
|
6
|
+
getStatusMessage,
|
|
7
|
+
getUploadStatus,
|
|
7
8
|
} from '.';
|
|
8
9
|
|
|
9
10
|
const documentsAccept = {
|
|
10
11
|
'application/msword': ['.doc'],
|
|
11
12
|
'application/pdf': ['.pdf'],
|
|
12
|
-
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': [
|
|
13
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': [
|
|
14
|
+
'.docx',
|
|
15
|
+
],
|
|
13
16
|
};
|
|
14
17
|
|
|
15
18
|
const imagesAccept = {
|
|
16
|
-
'image/heic': [
|
|
17
|
-
'image/bmp': [
|
|
18
|
-
'image/jpeg': [
|
|
19
|
-
'image/jpg': [
|
|
20
|
-
'image/png': [
|
|
21
|
-
'image/svg+xml': [
|
|
22
|
-
'image/tiff': [
|
|
23
|
-
'image/webp': [
|
|
19
|
+
'image/heic': ['.heic'],
|
|
20
|
+
'image/bmp': ['.bmp'],
|
|
21
|
+
'image/jpeg': ['.jpeg'],
|
|
22
|
+
'image/jpg': ['.jpg'],
|
|
23
|
+
'image/png': ['.png'],
|
|
24
|
+
'image/svg+xml': ['.svg'],
|
|
25
|
+
'image/tiff': ['.tiff'],
|
|
26
|
+
'image/webp': ['.webp'],
|
|
24
27
|
};
|
|
25
28
|
|
|
26
29
|
describe('getUploadStatus', () => {
|
|
27
30
|
it('Should return error status if error is passed', () => {
|
|
28
|
-
expect(getUploadStatus(0,
|
|
31
|
+
expect(getUploadStatus(0, 'Error message')).toEqual('ERROR');
|
|
29
32
|
});
|
|
30
33
|
|
|
31
34
|
it("Should return uploading status if progress hasn't finished", () => {
|
|
32
|
-
expect(getUploadStatus(50)).toEqual(
|
|
35
|
+
expect(getUploadStatus(50)).toEqual('UPLOADING');
|
|
33
36
|
});
|
|
34
37
|
|
|
35
|
-
it(
|
|
36
|
-
expect(getUploadStatus(100)).toEqual(
|
|
38
|
+
it('Should return complete status if progress has finished', () => {
|
|
39
|
+
expect(getUploadStatus(100)).toEqual('COMPLETE');
|
|
37
40
|
});
|
|
38
41
|
});
|
|
39
42
|
|
|
40
43
|
describe('getFormattedAcceptObject', () => {
|
|
41
44
|
it('Should return image accept object if is of type image', () => {
|
|
42
|
-
expect(getFormattedAcceptObject(
|
|
45
|
+
expect(getFormattedAcceptObject('image')).toEqual(imagesAccept);
|
|
43
46
|
});
|
|
44
47
|
|
|
45
48
|
it('Should return documents accept object if is of type document', () => {
|
|
46
|
-
expect(getFormattedAcceptObject(
|
|
49
|
+
expect(getFormattedAcceptObject('document')).toEqual(documentsAccept);
|
|
47
50
|
});
|
|
48
51
|
|
|
49
52
|
it('Should return accept object if it is manually defined', () => {
|
|
50
|
-
const accept = {
|
|
53
|
+
const accept = { 'application/pdf': ['.pdf'] };
|
|
51
54
|
|
|
52
55
|
expect(getFormattedAcceptObject(accept)).toEqual(accept);
|
|
53
56
|
});
|
|
@@ -55,61 +58,141 @@ describe('getFormattedAcceptObject', () => {
|
|
|
55
58
|
|
|
56
59
|
describe('formatAcceptFileList', () => {
|
|
57
60
|
it('Should return empty object if accept is empty', () => {
|
|
58
|
-
expect(formatAcceptFileList({})).toEqual(
|
|
61
|
+
expect(formatAcceptFileList({})).toEqual('');
|
|
59
62
|
});
|
|
60
63
|
|
|
61
64
|
it('Should return documents list if documents accept is passed', () => {
|
|
62
|
-
expect(formatAcceptFileList(documentsAccept)).toEqual(
|
|
65
|
+
expect(formatAcceptFileList(documentsAccept)).toEqual('DOC, PDF, DOCX');
|
|
63
66
|
});
|
|
64
67
|
|
|
65
68
|
it('Should return images list if images accept is passed', () => {
|
|
66
|
-
expect(formatAcceptFileList(imagesAccept)).toEqual(
|
|
69
|
+
expect(formatAcceptFileList(imagesAccept)).toEqual(
|
|
70
|
+
'HEIC, BMP, JPEG, JPG, PNG, SVG, TIFF, WEBP'
|
|
71
|
+
);
|
|
67
72
|
});
|
|
68
73
|
|
|
69
74
|
it('Should return extension based on accept passed', () => {
|
|
70
|
-
const accept = {
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
const accept = {
|
|
76
|
+
'application/pdf': ['.pdf'],
|
|
77
|
+
'image/jpg': ['.jpg'],
|
|
73
78
|
};
|
|
74
79
|
|
|
75
|
-
expect(formatAcceptFileList(accept)).toEqual(
|
|
80
|
+
expect(formatAcceptFileList(accept)).toEqual('PDF, JPG');
|
|
76
81
|
});
|
|
77
82
|
});
|
|
78
83
|
|
|
79
84
|
describe('getErrorMessage', () => {
|
|
80
85
|
it('Should return default error message', () => {
|
|
81
|
-
const defaultMessage =
|
|
86
|
+
const defaultMessage = 'Default Error Message.';
|
|
82
87
|
|
|
83
88
|
expect(
|
|
84
|
-
getErrorMessage(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
getErrorMessage(
|
|
90
|
+
{
|
|
91
|
+
code: 'UNKNOWN',
|
|
92
|
+
message: defaultMessage,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
fileList: '',
|
|
96
|
+
}
|
|
97
|
+
)
|
|
90
98
|
).toEqual(defaultMessage);
|
|
91
99
|
});
|
|
92
100
|
|
|
93
101
|
it('Should return default FileInvalidType default message', () => {
|
|
94
|
-
const fileList =
|
|
102
|
+
const fileList = 'JPG, PDF';
|
|
95
103
|
|
|
96
104
|
expect(
|
|
97
|
-
getErrorMessage(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
105
|
+
getErrorMessage(
|
|
106
|
+
{
|
|
107
|
+
code: ErrorCode.FileInvalidType,
|
|
108
|
+
message: '',
|
|
109
|
+
},
|
|
110
|
+
{ fileList }
|
|
111
|
+
)
|
|
101
112
|
).toEqual(`File type must be ${fileList}`);
|
|
102
113
|
});
|
|
103
114
|
|
|
104
115
|
it('Should return FileInvalidType with textOverride message', () => {
|
|
105
|
-
const fileTypeError =
|
|
106
|
-
const fileList =
|
|
107
|
-
|
|
116
|
+
const fileTypeError = 'File Invalid Error';
|
|
117
|
+
const fileList = 'JPG, PDF';
|
|
118
|
+
|
|
108
119
|
expect(
|
|
109
|
-
getErrorMessage(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
120
|
+
getErrorMessage(
|
|
121
|
+
{
|
|
122
|
+
code: ErrorCode.FileInvalidType,
|
|
123
|
+
message: '',
|
|
124
|
+
},
|
|
125
|
+
{ fileList },
|
|
126
|
+
{ fileTypeError }
|
|
127
|
+
)
|
|
113
128
|
).toEqual(`${fileTypeError} ${fileList}`);
|
|
114
129
|
});
|
|
115
130
|
});
|
|
131
|
+
|
|
132
|
+
describe('getStatusMessage', () => {
|
|
133
|
+
it('returns accepted file message for multiple files', () => {
|
|
134
|
+
const acceptedFiles = [
|
|
135
|
+
new File([''], 'photo.jpg'),
|
|
136
|
+
new File([''], 'invoice.pdf'),
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
const result = getStatusMessage({
|
|
140
|
+
acceptedFiles,
|
|
141
|
+
filesRejected: [],
|
|
142
|
+
maxSize: 5000000,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
expect(result).toBe('Files uploaded: photo.jpg, invoice.pdf.');
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('returns rejection message for invalid file type with default text', () => {
|
|
149
|
+
const filesRejected = [
|
|
150
|
+
{
|
|
151
|
+
file: new File([''], 'script.exe'),
|
|
152
|
+
errors: [
|
|
153
|
+
{ code: ErrorCode.FileInvalidType, message: 'Invalid file type' },
|
|
154
|
+
],
|
|
155
|
+
},
|
|
156
|
+
];
|
|
157
|
+
|
|
158
|
+
const result = getStatusMessage({
|
|
159
|
+
acceptedFiles: [],
|
|
160
|
+
filesRejected,
|
|
161
|
+
maxSize: 5000000,
|
|
162
|
+
fileList: 'PDF, JPG',
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
expect(result).toBe(
|
|
166
|
+
'Could not upload script.exe: File type must be PDF, JPG.'
|
|
167
|
+
);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('returns rejection message for file too large with default text', () => {
|
|
171
|
+
const filesRejected = [
|
|
172
|
+
{
|
|
173
|
+
file: new File([''], 'video.mov'),
|
|
174
|
+
errors: [{ code: ErrorCode.FileTooLarge, message: 'Too big' }],
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
|
|
178
|
+
const result = getStatusMessage({
|
|
179
|
+
acceptedFiles: [],
|
|
180
|
+
filesRejected,
|
|
181
|
+
maxSize: 1048576,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
expect(result).toBe(
|
|
185
|
+
'Could not upload video.mov: File is too large. It must be less than 1 MB.'
|
|
186
|
+
);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('returns fallback when no files are accepted or rejected', () => {
|
|
190
|
+
const result = getStatusMessage({
|
|
191
|
+
acceptedFiles: [],
|
|
192
|
+
filesRejected: [],
|
|
193
|
+
maxSize: 1000000,
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
expect(result).toBe('');
|
|
197
|
+
});
|
|
198
|
+
});
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import { Accept, ErrorCode, FileError } from
|
|
2
|
-
import { formatBytes } from
|
|
3
|
-
import {
|
|
4
|
-
AcceptType,
|
|
5
|
-
DOCUMENT_FILES,
|
|
1
|
+
import { Accept, ErrorCode, FileError, FileRejection } from 'react-dropzone';
|
|
2
|
+
import { formatBytes } from '../../../util/formatBytes';
|
|
3
|
+
import {
|
|
4
|
+
AcceptType,
|
|
5
|
+
DOCUMENT_FILES,
|
|
6
6
|
FileMimeTypes,
|
|
7
7
|
FileType,
|
|
8
|
-
IMAGE_FILES,
|
|
8
|
+
IMAGE_FILES,
|
|
9
9
|
TextOverrides,
|
|
10
10
|
UploadStatus,
|
|
11
|
-
VIDEO_FILES
|
|
12
|
-
} from
|
|
11
|
+
VIDEO_FILES,
|
|
12
|
+
} from '../types';
|
|
13
13
|
|
|
14
|
-
export const getUploadStatus = (
|
|
14
|
+
export const getUploadStatus = (
|
|
15
|
+
progress: number,
|
|
16
|
+
error?: string
|
|
17
|
+
): UploadStatus => {
|
|
15
18
|
if (error) {
|
|
16
19
|
return 'ERROR';
|
|
17
20
|
}
|
|
@@ -23,7 +26,7 @@ export const getUploadStatus = (progress: number, error?: string): UploadStatus
|
|
|
23
26
|
return 'COMPLETE';
|
|
24
27
|
};
|
|
25
28
|
|
|
26
|
-
const formatMimeType = (values: FileType[]): Accept
|
|
29
|
+
const formatMimeType = (values: FileType[]): Accept => {
|
|
27
30
|
const formatedValues = {} as Accept;
|
|
28
31
|
|
|
29
32
|
values.forEach((value) => {
|
|
@@ -36,17 +39,17 @@ const formatMimeType = (values: FileType[]): Accept => {
|
|
|
36
39
|
export const DOCUMENT_FILES_ACCEPT = formatMimeType(DOCUMENT_FILES);
|
|
37
40
|
export const IMAGE_FILES_ACCEPT = formatMimeType(IMAGE_FILES);
|
|
38
41
|
export const VIDEO_FILES_ACCEPT = formatMimeType(VIDEO_FILES);
|
|
39
|
-
|
|
42
|
+
|
|
40
43
|
export const getFormattedAcceptObject = (accept: AcceptType = {}): Accept => {
|
|
41
|
-
if (accept ===
|
|
44
|
+
if (accept === 'document') {
|
|
42
45
|
return DOCUMENT_FILES_ACCEPT;
|
|
43
|
-
}
|
|
46
|
+
}
|
|
44
47
|
|
|
45
|
-
if (accept ===
|
|
48
|
+
if (accept === 'image') {
|
|
46
49
|
return IMAGE_FILES_ACCEPT;
|
|
47
|
-
}
|
|
50
|
+
}
|
|
48
51
|
|
|
49
|
-
if (accept ===
|
|
52
|
+
if (accept === 'video') {
|
|
50
53
|
return VIDEO_FILES_ACCEPT;
|
|
51
54
|
}
|
|
52
55
|
|
|
@@ -57,17 +60,16 @@ export const getFormattedAcceptObject = (accept: AcceptType = {}): Accept => {
|
|
|
57
60
|
return {
|
|
58
61
|
...DOCUMENT_FILES_ACCEPT,
|
|
59
62
|
...IMAGE_FILES_ACCEPT,
|
|
60
|
-
...VIDEO_FILES_ACCEPT
|
|
63
|
+
...VIDEO_FILES_ACCEPT,
|
|
61
64
|
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export const formatAcceptFileList = (accept: Accept): string =>
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const formatAcceptFileList = (accept: Accept): string =>
|
|
65
68
|
Object.values(accept)
|
|
66
69
|
.reduce((acc, value) => [...acc, ...value], [])
|
|
67
|
-
.join(
|
|
70
|
+
.join(', ')
|
|
68
71
|
.replace(/\./g, '')
|
|
69
|
-
.toUpperCase()
|
|
70
|
-
);
|
|
72
|
+
.toUpperCase();
|
|
71
73
|
|
|
72
74
|
export const getPlaceholder = (
|
|
73
75
|
textOverrides?: TextOverrides,
|
|
@@ -78,28 +80,79 @@ export const getPlaceholder = (
|
|
|
78
80
|
maxSize && maxSize > 0
|
|
79
81
|
? `${textOverrides?.sizeUpToText || 'up to'} ${formatBytes(maxSize)}`
|
|
80
82
|
: '';
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
typeof accept === 'string' &&
|
|
84
|
-
['video', 'image', 'document'].includes(accept)
|
|
85
|
-
|
|
86
|
-
const defaultPlaceholder = `${
|
|
87
|
-
|
|
83
|
+
|
|
84
|
+
const isAcceptString =
|
|
85
|
+
typeof accept === 'string' &&
|
|
86
|
+
['video', 'image', 'document'].includes(accept);
|
|
87
|
+
|
|
88
|
+
const defaultPlaceholder = `${
|
|
89
|
+
textOverrides?.supportsTextShort || 'Supports images, videos and documents'
|
|
90
|
+
} ${maxSizePlaceholder}`;
|
|
91
|
+
const acceptPlaceholder = `${
|
|
92
|
+
textOverrides?.supportsTextShort ||
|
|
93
|
+
`Supports ${accept}s ${maxSizePlaceholder}`
|
|
94
|
+
}`;
|
|
88
95
|
|
|
89
96
|
return isAcceptString ? acceptPlaceholder : defaultPlaceholder;
|
|
90
|
-
}
|
|
97
|
+
};
|
|
91
98
|
|
|
92
99
|
export const getErrorMessage = (
|
|
93
100
|
{ code, message }: FileError,
|
|
94
|
-
{ fileList =
|
|
95
|
-
textOverrides?: TextOverrides
|
|
101
|
+
{ fileList = '', maxSize }: { fileList?: string; maxSize?: number },
|
|
102
|
+
textOverrides?: TextOverrides
|
|
96
103
|
): string => {
|
|
97
104
|
switch (code) {
|
|
98
105
|
case ErrorCode.FileInvalidType:
|
|
99
|
-
return `${
|
|
106
|
+
return `${
|
|
107
|
+
textOverrides?.fileTypeError || 'File type must be'
|
|
108
|
+
} ${fileList}`;
|
|
100
109
|
case ErrorCode.FileTooLarge:
|
|
101
|
-
return `${
|
|
110
|
+
return `${
|
|
111
|
+
textOverrides?.fileTooLargeError ||
|
|
112
|
+
'File is too large. It must be less than'
|
|
113
|
+
} ${formatBytes(maxSize || 0)}.`;
|
|
102
114
|
default:
|
|
103
115
|
return message;
|
|
104
116
|
}
|
|
105
|
-
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export const getStatusMessage = ({
|
|
120
|
+
acceptedFiles,
|
|
121
|
+
filesRejected,
|
|
122
|
+
fileList,
|
|
123
|
+
maxSize,
|
|
124
|
+
textOverrides,
|
|
125
|
+
}: {
|
|
126
|
+
acceptedFiles: File[];
|
|
127
|
+
filesRejected: FileRejection[];
|
|
128
|
+
fileList?: string;
|
|
129
|
+
maxSize?: number;
|
|
130
|
+
textOverrides?: TextOverrides;
|
|
131
|
+
}): string => {
|
|
132
|
+
let message = '';
|
|
133
|
+
if (acceptedFiles.length > 0) {
|
|
134
|
+
const fileNames = acceptedFiles.map((file) => file.name).join(', ');
|
|
135
|
+
message += `File${
|
|
136
|
+
acceptedFiles.length > 1 ? 's' : ''
|
|
137
|
+
} uploaded: ${fileNames}. `;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (filesRejected.length > 0) {
|
|
141
|
+
const rejectionMessages = filesRejected.map((rejection) => {
|
|
142
|
+
const firstError = rejection.errors[0];
|
|
143
|
+
const rejectionMessage = getErrorMessage(
|
|
144
|
+
firstError,
|
|
145
|
+
{ fileList, maxSize },
|
|
146
|
+
textOverrides
|
|
147
|
+
);
|
|
148
|
+
return `Could not upload ${rejection.file.name}: ${
|
|
149
|
+
rejectionMessage.endsWith('.')
|
|
150
|
+
? rejectionMessage
|
|
151
|
+
: `${rejectionMessage}.`
|
|
152
|
+
}`;
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
message += rejectionMessages.join('');
|
|
156
|
+
}
|
|
157
|
+
return message.trim();
|
|
158
|
+
};
|