@availity/mui-file-selector 1.7.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/index.d.mts +32 -7
- package/dist/index.d.ts +32 -7
- package/dist/index.js +164 -60
- package/dist/index.mjs +172 -68
- package/package.json +1 -1
- package/src/lib/Dropzone.tsx +63 -1
- package/src/lib/Dropzone2.tsx +60 -2
- package/src/lib/ErrorAlert.tsx +1 -0
- package/src/lib/FileSelector.tsx +19 -1
- package/src/lib/FileSelector2.tsx +8 -1
- package/src/lib/FileTypesMessage.tsx +14 -0
- package/src/lib/HeaderMessage.tsx +8 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [1.8.0](https://github.com/Availity/element/compare/@availity/mui-file-selector@1.7.1...@availity/mui-file-selector@1.8.0) (2025-06-16)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **mui-file-selector:** add maxTotalSize check to FileSelector ([03f78d6](https://github.com/Availity/element/commit/03f78d674243a76cc6d3e65a20b6e8ce3a46b8ca))
|
|
11
|
+
* **mui-file-selector:** add maxTotalSize check to FileSelector ([802e2ae](https://github.com/Availity/element/commit/802e2ae502aa8727037e2998849acf01a6ea0382))
|
|
12
|
+
* **mui-file-selector:** add maxTotalSize check to FileSelector2 ([ccd0cfa](https://github.com/Availity/element/commit/ccd0cfa95610d6e354402a3fa698b63b6659644c))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **mui-file-selector:** ensure only the maximum amount of files are uploaded ([5d80d2b](https://github.com/Availity/element/commit/5d80d2b046ea928ea432d7f269d1bfc99dd43782))
|
|
18
|
+
|
|
5
19
|
## [1.7.1](https://github.com/Availity/element/compare/@availity/mui-file-selector@1.7.0...@availity/mui-file-selector@1.7.1) (2025-05-30)
|
|
6
20
|
|
|
7
21
|
|
package/dist/index.d.mts
CHANGED
|
@@ -54,6 +54,10 @@ type DropzoneProps = {
|
|
|
54
54
|
* Maximum size of each file in bytes
|
|
55
55
|
*/
|
|
56
56
|
maxSize?: number;
|
|
57
|
+
/**
|
|
58
|
+
* Maximum size of total upload in bytes
|
|
59
|
+
*/
|
|
60
|
+
maxTotalSize?: number;
|
|
57
61
|
/**
|
|
58
62
|
* Whether multiple file selection is allowed
|
|
59
63
|
*/
|
|
@@ -88,7 +92,7 @@ type DropzoneProps = {
|
|
|
88
92
|
validator?: (file: File) => FileError | FileError[] | null;
|
|
89
93
|
};
|
|
90
94
|
declare const DropzoneContainer: typeof MuiBox;
|
|
91
|
-
declare const Dropzone: ({ allowedFileTypes, disabled, enableDropArea, maxFiles, maxSize, multiple, name, onChange, onClick, onDrop, setFileRejections, setTotalSize, validator, }: DropzoneProps) => react_jsx_runtime.JSX.Element;
|
|
95
|
+
declare const Dropzone: ({ allowedFileTypes, disabled, enableDropArea, maxFiles, maxSize, maxTotalSize, multiple, name, onChange, onClick, onDrop, setFileRejections, setTotalSize, validator, }: DropzoneProps) => react_jsx_runtime.JSX.Element;
|
|
92
96
|
|
|
93
97
|
type Dropzone2Props = DropzoneProps & {
|
|
94
98
|
uploadOptions: UploadOptions;
|
|
@@ -101,7 +105,7 @@ type Dropzone2Props = DropzoneProps & {
|
|
|
101
105
|
* `<Dropzone2 />` adds the `uploadOptions` prop that previously existed on
|
|
102
106
|
* `<FileSelector />`.
|
|
103
107
|
*/
|
|
104
|
-
declare const Dropzone2: ({ allowedFileTypes, disabled, enableDropArea, maxFiles, maxSize, multiple, name, onChange, onClick, onDrop, setFileRejections, setTotalSize, uploadOptions, validator, }: Dropzone2Props) => react_jsx_runtime.JSX.Element;
|
|
108
|
+
declare const Dropzone2: ({ allowedFileTypes, disabled, enableDropArea, maxFiles, maxSize, maxTotalSize, multiple, name, onChange, onClick, onDrop, setFileRejections, setTotalSize, uploadOptions, validator, }: Dropzone2Props) => react_jsx_runtime.JSX.Element;
|
|
105
109
|
|
|
106
110
|
type ErrorAlertProps = {
|
|
107
111
|
/**
|
|
@@ -268,6 +272,10 @@ type FileSelectorProps = {
|
|
|
268
272
|
* Overrides the standard file size message
|
|
269
273
|
*/
|
|
270
274
|
customSizeMessage?: React.ReactNode;
|
|
275
|
+
/**
|
|
276
|
+
* Overrides the standard total upload size message
|
|
277
|
+
*/
|
|
278
|
+
customTotalSizeMessage?: React.ReactNode;
|
|
271
279
|
/**
|
|
272
280
|
* Overrides the standard file types message
|
|
273
281
|
*/
|
|
@@ -307,6 +315,11 @@ type FileSelectorProps = {
|
|
|
307
315
|
* Use Kibi or Mibibytes. eg: 1kb = 1024 bytes; 1mb = 1024kb
|
|
308
316
|
*/
|
|
309
317
|
maxSize: number;
|
|
318
|
+
/**
|
|
319
|
+
* Maximum size allowed for total upload in bytes
|
|
320
|
+
* Use Kibi or Mibibytes. eg: 1kb = 1024 bytes; 1mb = 1024kb
|
|
321
|
+
*/
|
|
322
|
+
maxTotalSize?: number;
|
|
310
323
|
/**
|
|
311
324
|
* Whether multiple file selection is allowed
|
|
312
325
|
* @default true
|
|
@@ -347,7 +360,7 @@ type FileSelectorProps = {
|
|
|
347
360
|
*/
|
|
348
361
|
disableRemove?: boolean;
|
|
349
362
|
};
|
|
350
|
-
declare const FileSelector: ({ name, allowedFileNameCharacters, allowedFileTypes, bucketId, clientId, children, customSizeMessage, customTypesMessage, customerId, customFileRow, disabled, enableDropArea, endpoint, isCloud, label, maxFiles, maxSize, multiple, onChange, onDrop, onUploadRemove, queryOptions, uploadOptions, validator, disableRemove, }: FileSelectorProps) => react_jsx_runtime.JSX.Element;
|
|
363
|
+
declare const FileSelector: ({ name, allowedFileNameCharacters, allowedFileTypes, bucketId, clientId, children, customSizeMessage, customTotalSizeMessage, customTypesMessage, customerId, customFileRow, disabled, enableDropArea, endpoint, isCloud, label, maxFiles, maxSize, maxTotalSize, multiple, onChange, onDrop, onUploadRemove, queryOptions, uploadOptions, validator, disableRemove, }: FileSelectorProps) => react_jsx_runtime.JSX.Element;
|
|
351
364
|
|
|
352
365
|
type FileSelector2Props = Omit<FileSelectorProps, 'onUploadRemove' | 'queryOptions'> & {
|
|
353
366
|
onUploadRemove?: (uploads: Upload[], removedUploadId: string) => void;
|
|
@@ -361,7 +374,7 @@ type FileSelector2Props = Omit<FileSelectorProps, 'onUploadRemove' | 'queryOptio
|
|
|
361
374
|
* `<FileSelector2 />` removes the reliance on `@tanstack/react-query`. The
|
|
362
375
|
* `Upload` object can now be accessed from the form state.
|
|
363
376
|
*/
|
|
364
|
-
declare const FileSelector2: ({ name, allowedFileNameCharacters, allowedFileTypes, bucketId, clientId, children, customSizeMessage, customTypesMessage, customerId, customFileRow, disabled, enableDropArea, endpoint, isCloud, label, maxFiles, maxSize, multiple, onChange, onDrop, onUploadRemove, uploadOptions, validator, disableRemove, }: FileSelector2Props) => react_jsx_runtime.JSX.Element;
|
|
377
|
+
declare const FileSelector2: ({ name, allowedFileNameCharacters, allowedFileTypes, bucketId, clientId, children, customSizeMessage, customTotalSizeMessage, customTypesMessage, customerId, customFileRow, disabled, enableDropArea, endpoint, isCloud, label, maxFiles, maxSize, maxTotalSize, multiple, onChange, onDrop, onUploadRemove, uploadOptions, validator, disableRemove, }: FileSelector2Props) => react_jsx_runtime.JSX.Element;
|
|
365
378
|
|
|
366
379
|
type FileTypesMessageProps = {
|
|
367
380
|
/**
|
|
@@ -372,6 +385,10 @@ type FileTypesMessageProps = {
|
|
|
372
385
|
* Overrides the standard file size message
|
|
373
386
|
*/
|
|
374
387
|
customSizeMessage?: React.ReactNode;
|
|
388
|
+
/**
|
|
389
|
+
* Overrides the standard total upload size message
|
|
390
|
+
*/
|
|
391
|
+
customTotalSizeMessage?: React.ReactNode;
|
|
375
392
|
/**
|
|
376
393
|
* Overrides the standard file types message
|
|
377
394
|
*/
|
|
@@ -380,9 +397,13 @@ type FileTypesMessageProps = {
|
|
|
380
397
|
* Maximum size per file in bytes. This will be formatted. eg: 1024 * 20 = 20 KB
|
|
381
398
|
*/
|
|
382
399
|
maxFileSize?: number;
|
|
400
|
+
/**
|
|
401
|
+
* Maximum size of the total upload in bytes. This will be formatted. eg: 1024 * 20 = 20 KB
|
|
402
|
+
*/
|
|
403
|
+
maxTotalSize?: number;
|
|
383
404
|
variant?: 'caption' | 'body2';
|
|
384
405
|
};
|
|
385
|
-
declare const FileTypesMessage: ({ allowedFileTypes, customSizeMessage, customTypesMessage, maxFileSize, variant, }: FileTypesMessageProps) => react_jsx_runtime.JSX.Element;
|
|
406
|
+
declare const FileTypesMessage: ({ allowedFileTypes, customSizeMessage, customTotalSizeMessage, customTypesMessage, maxFileSize, maxTotalSize, variant, }: FileTypesMessageProps) => react_jsx_runtime.JSX.Element;
|
|
386
407
|
|
|
387
408
|
type HeaderMessageProps = {
|
|
388
409
|
/**
|
|
@@ -390,11 +411,15 @@ type HeaderMessageProps = {
|
|
|
390
411
|
*/
|
|
391
412
|
maxFiles: number;
|
|
392
413
|
/**
|
|
393
|
-
* Maximum
|
|
414
|
+
* Maximum size of each file
|
|
394
415
|
*/
|
|
395
416
|
maxSize: number;
|
|
417
|
+
/**
|
|
418
|
+
* Maximum combined total size of all files
|
|
419
|
+
*/
|
|
420
|
+
maxTotalSize?: number;
|
|
396
421
|
};
|
|
397
|
-
declare const HeaderMessage: ({ maxFiles, maxSize }: HeaderMessageProps) => react_jsx_runtime.JSX.Element;
|
|
422
|
+
declare const HeaderMessage: ({ maxFiles, maxSize, maxTotalSize }: HeaderMessageProps) => react_jsx_runtime.JSX.Element;
|
|
398
423
|
|
|
399
424
|
type UploadProgressBarProps = {
|
|
400
425
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -54,6 +54,10 @@ type DropzoneProps = {
|
|
|
54
54
|
* Maximum size of each file in bytes
|
|
55
55
|
*/
|
|
56
56
|
maxSize?: number;
|
|
57
|
+
/**
|
|
58
|
+
* Maximum size of total upload in bytes
|
|
59
|
+
*/
|
|
60
|
+
maxTotalSize?: number;
|
|
57
61
|
/**
|
|
58
62
|
* Whether multiple file selection is allowed
|
|
59
63
|
*/
|
|
@@ -88,7 +92,7 @@ type DropzoneProps = {
|
|
|
88
92
|
validator?: (file: File) => FileError | FileError[] | null;
|
|
89
93
|
};
|
|
90
94
|
declare const DropzoneContainer: typeof MuiBox;
|
|
91
|
-
declare const Dropzone: ({ allowedFileTypes, disabled, enableDropArea, maxFiles, maxSize, multiple, name, onChange, onClick, onDrop, setFileRejections, setTotalSize, validator, }: DropzoneProps) => react_jsx_runtime.JSX.Element;
|
|
95
|
+
declare const Dropzone: ({ allowedFileTypes, disabled, enableDropArea, maxFiles, maxSize, maxTotalSize, multiple, name, onChange, onClick, onDrop, setFileRejections, setTotalSize, validator, }: DropzoneProps) => react_jsx_runtime.JSX.Element;
|
|
92
96
|
|
|
93
97
|
type Dropzone2Props = DropzoneProps & {
|
|
94
98
|
uploadOptions: UploadOptions;
|
|
@@ -101,7 +105,7 @@ type Dropzone2Props = DropzoneProps & {
|
|
|
101
105
|
* `<Dropzone2 />` adds the `uploadOptions` prop that previously existed on
|
|
102
106
|
* `<FileSelector />`.
|
|
103
107
|
*/
|
|
104
|
-
declare const Dropzone2: ({ allowedFileTypes, disabled, enableDropArea, maxFiles, maxSize, multiple, name, onChange, onClick, onDrop, setFileRejections, setTotalSize, uploadOptions, validator, }: Dropzone2Props) => react_jsx_runtime.JSX.Element;
|
|
108
|
+
declare const Dropzone2: ({ allowedFileTypes, disabled, enableDropArea, maxFiles, maxSize, maxTotalSize, multiple, name, onChange, onClick, onDrop, setFileRejections, setTotalSize, uploadOptions, validator, }: Dropzone2Props) => react_jsx_runtime.JSX.Element;
|
|
105
109
|
|
|
106
110
|
type ErrorAlertProps = {
|
|
107
111
|
/**
|
|
@@ -268,6 +272,10 @@ type FileSelectorProps = {
|
|
|
268
272
|
* Overrides the standard file size message
|
|
269
273
|
*/
|
|
270
274
|
customSizeMessage?: React.ReactNode;
|
|
275
|
+
/**
|
|
276
|
+
* Overrides the standard total upload size message
|
|
277
|
+
*/
|
|
278
|
+
customTotalSizeMessage?: React.ReactNode;
|
|
271
279
|
/**
|
|
272
280
|
* Overrides the standard file types message
|
|
273
281
|
*/
|
|
@@ -307,6 +315,11 @@ type FileSelectorProps = {
|
|
|
307
315
|
* Use Kibi or Mibibytes. eg: 1kb = 1024 bytes; 1mb = 1024kb
|
|
308
316
|
*/
|
|
309
317
|
maxSize: number;
|
|
318
|
+
/**
|
|
319
|
+
* Maximum size allowed for total upload in bytes
|
|
320
|
+
* Use Kibi or Mibibytes. eg: 1kb = 1024 bytes; 1mb = 1024kb
|
|
321
|
+
*/
|
|
322
|
+
maxTotalSize?: number;
|
|
310
323
|
/**
|
|
311
324
|
* Whether multiple file selection is allowed
|
|
312
325
|
* @default true
|
|
@@ -347,7 +360,7 @@ type FileSelectorProps = {
|
|
|
347
360
|
*/
|
|
348
361
|
disableRemove?: boolean;
|
|
349
362
|
};
|
|
350
|
-
declare const FileSelector: ({ name, allowedFileNameCharacters, allowedFileTypes, bucketId, clientId, children, customSizeMessage, customTypesMessage, customerId, customFileRow, disabled, enableDropArea, endpoint, isCloud, label, maxFiles, maxSize, multiple, onChange, onDrop, onUploadRemove, queryOptions, uploadOptions, validator, disableRemove, }: FileSelectorProps) => react_jsx_runtime.JSX.Element;
|
|
363
|
+
declare const FileSelector: ({ name, allowedFileNameCharacters, allowedFileTypes, bucketId, clientId, children, customSizeMessage, customTotalSizeMessage, customTypesMessage, customerId, customFileRow, disabled, enableDropArea, endpoint, isCloud, label, maxFiles, maxSize, maxTotalSize, multiple, onChange, onDrop, onUploadRemove, queryOptions, uploadOptions, validator, disableRemove, }: FileSelectorProps) => react_jsx_runtime.JSX.Element;
|
|
351
364
|
|
|
352
365
|
type FileSelector2Props = Omit<FileSelectorProps, 'onUploadRemove' | 'queryOptions'> & {
|
|
353
366
|
onUploadRemove?: (uploads: Upload[], removedUploadId: string) => void;
|
|
@@ -361,7 +374,7 @@ type FileSelector2Props = Omit<FileSelectorProps, 'onUploadRemove' | 'queryOptio
|
|
|
361
374
|
* `<FileSelector2 />` removes the reliance on `@tanstack/react-query`. The
|
|
362
375
|
* `Upload` object can now be accessed from the form state.
|
|
363
376
|
*/
|
|
364
|
-
declare const FileSelector2: ({ name, allowedFileNameCharacters, allowedFileTypes, bucketId, clientId, children, customSizeMessage, customTypesMessage, customerId, customFileRow, disabled, enableDropArea, endpoint, isCloud, label, maxFiles, maxSize, multiple, onChange, onDrop, onUploadRemove, uploadOptions, validator, disableRemove, }: FileSelector2Props) => react_jsx_runtime.JSX.Element;
|
|
377
|
+
declare const FileSelector2: ({ name, allowedFileNameCharacters, allowedFileTypes, bucketId, clientId, children, customSizeMessage, customTotalSizeMessage, customTypesMessage, customerId, customFileRow, disabled, enableDropArea, endpoint, isCloud, label, maxFiles, maxSize, maxTotalSize, multiple, onChange, onDrop, onUploadRemove, uploadOptions, validator, disableRemove, }: FileSelector2Props) => react_jsx_runtime.JSX.Element;
|
|
365
378
|
|
|
366
379
|
type FileTypesMessageProps = {
|
|
367
380
|
/**
|
|
@@ -372,6 +385,10 @@ type FileTypesMessageProps = {
|
|
|
372
385
|
* Overrides the standard file size message
|
|
373
386
|
*/
|
|
374
387
|
customSizeMessage?: React.ReactNode;
|
|
388
|
+
/**
|
|
389
|
+
* Overrides the standard total upload size message
|
|
390
|
+
*/
|
|
391
|
+
customTotalSizeMessage?: React.ReactNode;
|
|
375
392
|
/**
|
|
376
393
|
* Overrides the standard file types message
|
|
377
394
|
*/
|
|
@@ -380,9 +397,13 @@ type FileTypesMessageProps = {
|
|
|
380
397
|
* Maximum size per file in bytes. This will be formatted. eg: 1024 * 20 = 20 KB
|
|
381
398
|
*/
|
|
382
399
|
maxFileSize?: number;
|
|
400
|
+
/**
|
|
401
|
+
* Maximum size of the total upload in bytes. This will be formatted. eg: 1024 * 20 = 20 KB
|
|
402
|
+
*/
|
|
403
|
+
maxTotalSize?: number;
|
|
383
404
|
variant?: 'caption' | 'body2';
|
|
384
405
|
};
|
|
385
|
-
declare const FileTypesMessage: ({ allowedFileTypes, customSizeMessage, customTypesMessage, maxFileSize, variant, }: FileTypesMessageProps) => react_jsx_runtime.JSX.Element;
|
|
406
|
+
declare const FileTypesMessage: ({ allowedFileTypes, customSizeMessage, customTotalSizeMessage, customTypesMessage, maxFileSize, maxTotalSize, variant, }: FileTypesMessageProps) => react_jsx_runtime.JSX.Element;
|
|
386
407
|
|
|
387
408
|
type HeaderMessageProps = {
|
|
388
409
|
/**
|
|
@@ -390,11 +411,15 @@ type HeaderMessageProps = {
|
|
|
390
411
|
*/
|
|
391
412
|
maxFiles: number;
|
|
392
413
|
/**
|
|
393
|
-
* Maximum
|
|
414
|
+
* Maximum size of each file
|
|
394
415
|
*/
|
|
395
416
|
maxSize: number;
|
|
417
|
+
/**
|
|
418
|
+
* Maximum combined total size of all files
|
|
419
|
+
*/
|
|
420
|
+
maxTotalSize?: number;
|
|
396
421
|
};
|
|
397
|
-
declare const HeaderMessage: ({ maxFiles, maxSize }: HeaderMessageProps) => react_jsx_runtime.JSX.Element;
|
|
422
|
+
declare const HeaderMessage: ({ maxFiles, maxSize, maxTotalSize }: HeaderMessageProps) => react_jsx_runtime.JSX.Element;
|
|
398
423
|
|
|
399
424
|
type UploadProgressBarProps = {
|
|
400
425
|
/**
|
package/dist/index.js
CHANGED
|
@@ -108,7 +108,7 @@ var import_styles = require("@mui/material/styles");
|
|
|
108
108
|
var import_react_dropzone = require("react-dropzone");
|
|
109
109
|
var import_react_hook_form2 = require("react-hook-form");
|
|
110
110
|
var import_mui_divider = require("@availity/mui-divider");
|
|
111
|
-
var
|
|
111
|
+
var import_mui_icon2 = require("@availity/mui-icon");
|
|
112
112
|
var import_mui_layout = require("@availity/mui-layout");
|
|
113
113
|
var import_mui_typography = require("@availity/mui-typography");
|
|
114
114
|
|
|
@@ -166,6 +166,55 @@ var FilePickerBtn = (_a) => {
|
|
|
166
166
|
] });
|
|
167
167
|
};
|
|
168
168
|
|
|
169
|
+
// src/lib/util.ts
|
|
170
|
+
var import_mui_icon = require("@availity/mui-icon");
|
|
171
|
+
function formatBytes(bytes, decimals = 2) {
|
|
172
|
+
if (!+bytes) return "0 Bytes";
|
|
173
|
+
const k = 1024;
|
|
174
|
+
const dm = decimals < 0 ? 0 : decimals;
|
|
175
|
+
const sizes = ["Bytes", "KB", "MB", "GB"];
|
|
176
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
177
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
|
178
|
+
}
|
|
179
|
+
var FILE_EXT_ICONS = {
|
|
180
|
+
png: import_mui_icon.FileImageIcon,
|
|
181
|
+
jpg: import_mui_icon.FileImageIcon,
|
|
182
|
+
jpeg: import_mui_icon.FileImageIcon,
|
|
183
|
+
gif: import_mui_icon.FileImageIcon,
|
|
184
|
+
csv: import_mui_icon.FileCsvIcon,
|
|
185
|
+
ppt: import_mui_icon.FilePowerpointIcon,
|
|
186
|
+
pptx: import_mui_icon.FilePowerpointIcon,
|
|
187
|
+
xls: import_mui_icon.FileExcelIcon,
|
|
188
|
+
xlsx: import_mui_icon.FileExcelIcon,
|
|
189
|
+
doc: import_mui_icon.FileWordIcon,
|
|
190
|
+
docx: import_mui_icon.FileWordIcon,
|
|
191
|
+
txt: import_mui_icon.FileLinesIcon,
|
|
192
|
+
text: import_mui_icon.FileLinesIcon,
|
|
193
|
+
zip: import_mui_icon.FileArchiveIcon,
|
|
194
|
+
"7zip": import_mui_icon.FileArchiveIcon,
|
|
195
|
+
xml: import_mui_icon.FileCodeIcon,
|
|
196
|
+
html: import_mui_icon.FileCodeIcon,
|
|
197
|
+
pdf: import_mui_icon.FilePdfIcon
|
|
198
|
+
};
|
|
199
|
+
var isValidKey = (key) => key ? key in FILE_EXT_ICONS : false;
|
|
200
|
+
var getFileExtension = (fileName) => {
|
|
201
|
+
var _a;
|
|
202
|
+
return ((_a = fileName.split(".").pop()) == null ? void 0 : _a.toLowerCase()) || "";
|
|
203
|
+
};
|
|
204
|
+
var getFileExtIcon = (fileName) => {
|
|
205
|
+
const ext = getFileExtension(fileName);
|
|
206
|
+
return isValidKey(ext) ? FILE_EXT_ICONS[ext] : import_mui_icon.FileIcon;
|
|
207
|
+
};
|
|
208
|
+
var dedupeErrors = (errors) => {
|
|
209
|
+
const dedupedErrors = errors.reduce((acc, error) => {
|
|
210
|
+
if (!acc.find((err) => err.code === error.code)) {
|
|
211
|
+
acc.push(error);
|
|
212
|
+
}
|
|
213
|
+
return acc;
|
|
214
|
+
}, []);
|
|
215
|
+
return dedupedErrors;
|
|
216
|
+
};
|
|
217
|
+
|
|
169
218
|
// src/lib/Dropzone.tsx
|
|
170
219
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
171
220
|
var outerBoxStyles = {
|
|
@@ -205,6 +254,7 @@ var Dropzone = ({
|
|
|
205
254
|
enableDropArea = true,
|
|
206
255
|
maxFiles,
|
|
207
256
|
maxSize,
|
|
257
|
+
maxTotalSize,
|
|
208
258
|
multiple,
|
|
209
259
|
name,
|
|
210
260
|
onChange,
|
|
@@ -257,7 +307,48 @@ var Dropzone = ({
|
|
|
257
307
|
}
|
|
258
308
|
setTotalSize((prev) => prev + newSize);
|
|
259
309
|
const previous = (_a2 = watch(name)) != null ? _a2 : [];
|
|
260
|
-
|
|
310
|
+
if (maxTotalSize) {
|
|
311
|
+
const currentTotalSize = previous.reduce((sum, file) => sum + file.size, 0);
|
|
312
|
+
let newSize2 = 0;
|
|
313
|
+
const availableSize = Math.max(0, maxTotalSize - currentTotalSize);
|
|
314
|
+
let sizeCounter = 0;
|
|
315
|
+
const cutoffIndex = acceptedFiles.findIndex((file) => {
|
|
316
|
+
sizeCounter += file.size;
|
|
317
|
+
return sizeCounter > availableSize;
|
|
318
|
+
});
|
|
319
|
+
if (cutoffIndex !== -1) {
|
|
320
|
+
const filesToAdd2 = acceptedFiles.slice(0, cutoffIndex === 0 ? 0 : cutoffIndex);
|
|
321
|
+
fileRejections.push({
|
|
322
|
+
file: acceptedFiles[cutoffIndex],
|
|
323
|
+
errors: [
|
|
324
|
+
{
|
|
325
|
+
code: "upload-too-large",
|
|
326
|
+
message: `Total upload size exceeds the limit of ${formatBytes(maxTotalSize)}.`
|
|
327
|
+
}
|
|
328
|
+
],
|
|
329
|
+
id: counter.increment()
|
|
330
|
+
});
|
|
331
|
+
acceptedFiles = filesToAdd2;
|
|
332
|
+
}
|
|
333
|
+
newSize2 = acceptedFiles.reduce((sum, file) => sum + file.size, 0);
|
|
334
|
+
setTotalSize((prev) => prev + newSize2);
|
|
335
|
+
}
|
|
336
|
+
const remainingSlots = maxFiles ? Math.max(0, maxFiles - previous.length) : acceptedFiles.length;
|
|
337
|
+
const filesToAdd = acceptedFiles.slice(0, remainingSlots);
|
|
338
|
+
setValue(name, previous.concat(filesToAdd));
|
|
339
|
+
if (maxFiles && acceptedFiles.length > remainingSlots) {
|
|
340
|
+
fileRejections.push({
|
|
341
|
+
file: acceptedFiles[remainingSlots],
|
|
342
|
+
// Use the first excess file
|
|
343
|
+
errors: [
|
|
344
|
+
{
|
|
345
|
+
code: "too-many-files",
|
|
346
|
+
message: `Too many files. You may only upload ${maxFiles} file(s).`
|
|
347
|
+
}
|
|
348
|
+
],
|
|
349
|
+
id: counter.increment()
|
|
350
|
+
});
|
|
351
|
+
}
|
|
261
352
|
if (fileRejections.length > 0) {
|
|
262
353
|
const TOO_MANY_FILES_CODE = "too-many-files";
|
|
263
354
|
let hasTooManyFiles = false;
|
|
@@ -317,7 +408,7 @@ var Dropzone = ({
|
|
|
317
408
|
};
|
|
318
409
|
const hasFiles = getFieldValue().length > 0;
|
|
319
410
|
return enableDropArea ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DropzoneContainer, __spreadProps(__spreadValues({ sx: outerBoxStyles }, rootProps), { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_layout.Box, { sx: innerBoxStyles, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_layout.Stack, { spacing: 2, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
320
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
411
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_icon2.CloudUploadIcon, { fontSize: "xlarge", color: "secondary" }),
|
|
321
412
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_typography.Typography, { variant: "subtitle2", fontWeight: "700", children: "Drag and Drop Files Here" }),
|
|
322
413
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_divider.Divider, { flexItem: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_typography.Typography, { variant: "subtitle2", children: "OR" }) }),
|
|
323
414
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
@@ -343,7 +434,7 @@ var Dropzone = ({
|
|
|
343
434
|
onClick: handleOnClick,
|
|
344
435
|
inputProps,
|
|
345
436
|
onChange: handleOnChange,
|
|
346
|
-
startIcon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
437
|
+
startIcon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_mui_icon2.PlusIcon, {}),
|
|
347
438
|
children: hasFiles ? "Add More Files" : "Add File(s)"
|
|
348
439
|
}
|
|
349
440
|
);
|
|
@@ -358,57 +449,6 @@ var import_mui_icon3 = require("@availity/mui-icon");
|
|
|
358
449
|
var import_mui_layout2 = require("@availity/mui-layout");
|
|
359
450
|
var import_mui_typography2 = require("@availity/mui-typography");
|
|
360
451
|
var import_upload_core = __toESM(require("@availity/upload-core"));
|
|
361
|
-
|
|
362
|
-
// src/lib/util.ts
|
|
363
|
-
var import_mui_icon2 = require("@availity/mui-icon");
|
|
364
|
-
function formatBytes(bytes, decimals = 2) {
|
|
365
|
-
if (!+bytes) return "0 Bytes";
|
|
366
|
-
const k = 1024;
|
|
367
|
-
const dm = decimals < 0 ? 0 : decimals;
|
|
368
|
-
const sizes = ["Bytes", "KB", "MB", "GB"];
|
|
369
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
370
|
-
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
|
371
|
-
}
|
|
372
|
-
var FILE_EXT_ICONS = {
|
|
373
|
-
png: import_mui_icon2.FileImageIcon,
|
|
374
|
-
jpg: import_mui_icon2.FileImageIcon,
|
|
375
|
-
jpeg: import_mui_icon2.FileImageIcon,
|
|
376
|
-
gif: import_mui_icon2.FileImageIcon,
|
|
377
|
-
csv: import_mui_icon2.FileCsvIcon,
|
|
378
|
-
ppt: import_mui_icon2.FilePowerpointIcon,
|
|
379
|
-
pptx: import_mui_icon2.FilePowerpointIcon,
|
|
380
|
-
xls: import_mui_icon2.FileExcelIcon,
|
|
381
|
-
xlsx: import_mui_icon2.FileExcelIcon,
|
|
382
|
-
doc: import_mui_icon2.FileWordIcon,
|
|
383
|
-
docx: import_mui_icon2.FileWordIcon,
|
|
384
|
-
txt: import_mui_icon2.FileLinesIcon,
|
|
385
|
-
text: import_mui_icon2.FileLinesIcon,
|
|
386
|
-
zip: import_mui_icon2.FileArchiveIcon,
|
|
387
|
-
"7zip": import_mui_icon2.FileArchiveIcon,
|
|
388
|
-
xml: import_mui_icon2.FileCodeIcon,
|
|
389
|
-
html: import_mui_icon2.FileCodeIcon,
|
|
390
|
-
pdf: import_mui_icon2.FilePdfIcon
|
|
391
|
-
};
|
|
392
|
-
var isValidKey = (key) => key ? key in FILE_EXT_ICONS : false;
|
|
393
|
-
var getFileExtension = (fileName) => {
|
|
394
|
-
var _a;
|
|
395
|
-
return ((_a = fileName.split(".").pop()) == null ? void 0 : _a.toLowerCase()) || "";
|
|
396
|
-
};
|
|
397
|
-
var getFileExtIcon = (fileName) => {
|
|
398
|
-
const ext = getFileExtension(fileName);
|
|
399
|
-
return isValidKey(ext) ? FILE_EXT_ICONS[ext] : import_mui_icon2.FileIcon;
|
|
400
|
-
};
|
|
401
|
-
var dedupeErrors = (errors) => {
|
|
402
|
-
const dedupedErrors = errors.reduce((acc, error) => {
|
|
403
|
-
if (!acc.find((err) => err.code === error.code)) {
|
|
404
|
-
acc.push(error);
|
|
405
|
-
}
|
|
406
|
-
return acc;
|
|
407
|
-
}, []);
|
|
408
|
-
return dedupedErrors;
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
// src/lib/Dropzone2.tsx
|
|
412
452
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
413
453
|
var counter2 = createCounter();
|
|
414
454
|
function startUpload(file, options) {
|
|
@@ -430,6 +470,7 @@ var Dropzone2 = ({
|
|
|
430
470
|
enableDropArea = true,
|
|
431
471
|
maxFiles,
|
|
432
472
|
maxSize,
|
|
473
|
+
maxTotalSize,
|
|
433
474
|
multiple,
|
|
434
475
|
name,
|
|
435
476
|
onChange,
|
|
@@ -484,8 +525,50 @@ var Dropzone2 = ({
|
|
|
484
525
|
}
|
|
485
526
|
setTotalSize((prev) => prev + newSize);
|
|
486
527
|
const previous = (_a2 = watch(name)) != null ? _a2 : [];
|
|
487
|
-
|
|
528
|
+
if (maxTotalSize) {
|
|
529
|
+
const currentTotalSize = previous.reduce((sum, upload) => sum + upload.file.size, 0);
|
|
530
|
+
console.log({ previous });
|
|
531
|
+
let newSize2 = 0;
|
|
532
|
+
const availableSize = Math.max(0, maxTotalSize - currentTotalSize);
|
|
533
|
+
let sizeCounter = 0;
|
|
534
|
+
const cutoffIndex = acceptedFiles.findIndex((file) => {
|
|
535
|
+
sizeCounter += file.size;
|
|
536
|
+
return sizeCounter > availableSize;
|
|
537
|
+
});
|
|
538
|
+
if (cutoffIndex !== -1) {
|
|
539
|
+
const filesToAdd2 = acceptedFiles.slice(0, cutoffIndex === 0 ? 0 : cutoffIndex);
|
|
540
|
+
fileRejections.push({
|
|
541
|
+
file: acceptedFiles[cutoffIndex],
|
|
542
|
+
errors: [
|
|
543
|
+
{
|
|
544
|
+
code: "upload-too-large",
|
|
545
|
+
message: `Total upload size exceeds the limit of ${formatBytes(maxTotalSize)}.`
|
|
546
|
+
}
|
|
547
|
+
],
|
|
548
|
+
id: counter2.increment()
|
|
549
|
+
});
|
|
550
|
+
acceptedFiles = filesToAdd2;
|
|
551
|
+
}
|
|
552
|
+
newSize2 = acceptedFiles.reduce((sum, file) => sum + file.size, 0);
|
|
553
|
+
setTotalSize((prev) => prev + newSize2);
|
|
554
|
+
}
|
|
555
|
+
const remainingSlots = maxFiles ? Math.max(0, maxFiles - previous.length) : acceptedFiles.length;
|
|
556
|
+
const filesToAdd = acceptedFiles.slice(0, remainingSlots);
|
|
557
|
+
const uploads = filesToAdd.map((file) => startUpload(file, uploadOptions));
|
|
488
558
|
setValue(name, previous.concat(yield Promise.all(uploads)));
|
|
559
|
+
if (maxFiles && acceptedFiles.length > remainingSlots) {
|
|
560
|
+
fileRejections.push({
|
|
561
|
+
file: acceptedFiles[remainingSlots],
|
|
562
|
+
// Use the first excess file
|
|
563
|
+
errors: [
|
|
564
|
+
{
|
|
565
|
+
code: "too-many-files",
|
|
566
|
+
message: `Too many files. You may only upload ${maxFiles} file(s).`
|
|
567
|
+
}
|
|
568
|
+
],
|
|
569
|
+
id: counter2.increment()
|
|
570
|
+
});
|
|
571
|
+
}
|
|
489
572
|
if (fileRejections.length > 0) {
|
|
490
573
|
const TOO_MANY_FILES_CODE = "too-many-files";
|
|
491
574
|
let hasTooManyFiles = false;
|
|
@@ -582,6 +665,7 @@ var import_mui_list = require("@availity/mui-list");
|
|
|
582
665
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
583
666
|
var codes = {
|
|
584
667
|
"file-too-large": "File exceeds maximum size",
|
|
668
|
+
"upload-too-large": "File causes maximum total upload size to be exceeded",
|
|
585
669
|
"file-invalid-type": "File has an invalid type",
|
|
586
670
|
"file-too-small": "File is smaller than minimum size",
|
|
587
671
|
"too-many-file": "Too many files",
|
|
@@ -1087,14 +1171,18 @@ var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
|
1087
1171
|
var FileTypesMessage = ({
|
|
1088
1172
|
allowedFileTypes = [],
|
|
1089
1173
|
customSizeMessage,
|
|
1174
|
+
customTotalSizeMessage,
|
|
1090
1175
|
customTypesMessage,
|
|
1091
1176
|
maxFileSize,
|
|
1177
|
+
maxTotalSize,
|
|
1092
1178
|
variant = "caption"
|
|
1093
1179
|
}) => {
|
|
1094
1180
|
const fileSizeMsg = customSizeMessage || (typeof maxFileSize === "number" ? `Maximum file size is ${formatBytes(maxFileSize)}. ` : null);
|
|
1181
|
+
const totalFileSizeMsg = customTotalSizeMessage || (typeof maxTotalSize === "number" ? `Maximum total upload size is ${formatBytes(maxTotalSize)}. ` : null);
|
|
1095
1182
|
const fileTypesMsg = customTypesMessage || (allowedFileTypes.length > 0 ? `Supported file types include: ${allowedFileTypes.join(", ")}` : "All file types allowed.");
|
|
1096
1183
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_mui_typography4.Typography, { variant, children: [
|
|
1097
1184
|
fileSizeMsg,
|
|
1185
|
+
totalFileSizeMsg,
|
|
1098
1186
|
fileTypesMsg
|
|
1099
1187
|
] });
|
|
1100
1188
|
};
|
|
@@ -1102,12 +1190,14 @@ var FileTypesMessage = ({
|
|
|
1102
1190
|
// src/lib/HeaderMessage.tsx
|
|
1103
1191
|
var import_mui_typography5 = require("@availity/mui-typography");
|
|
1104
1192
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1105
|
-
var HeaderMessage = ({ maxFiles, maxSize }) => {
|
|
1193
|
+
var HeaderMessage = ({ maxFiles, maxSize, maxTotalSize }) => {
|
|
1106
1194
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_mui_typography5.Typography, { variant: "h6", children: [
|
|
1107
1195
|
"Attach up to ",
|
|
1108
1196
|
maxFiles,
|
|
1109
1197
|
" file(s), with a maximum individual size of ",
|
|
1110
|
-
formatBytes(maxSize)
|
|
1198
|
+
formatBytes(maxSize),
|
|
1199
|
+
" ",
|
|
1200
|
+
maxTotalSize && `and a maximum total size of ${formatBytes(maxTotalSize)}`
|
|
1111
1201
|
] });
|
|
1112
1202
|
};
|
|
1113
1203
|
|
|
@@ -1122,6 +1212,7 @@ var FileSelector = ({
|
|
|
1122
1212
|
clientId,
|
|
1123
1213
|
children,
|
|
1124
1214
|
customSizeMessage,
|
|
1215
|
+
customTotalSizeMessage,
|
|
1125
1216
|
customTypesMessage,
|
|
1126
1217
|
customerId,
|
|
1127
1218
|
customFileRow,
|
|
@@ -1132,6 +1223,7 @@ var FileSelector = ({
|
|
|
1132
1223
|
label = "Upload file",
|
|
1133
1224
|
maxFiles,
|
|
1134
1225
|
maxSize,
|
|
1226
|
+
maxTotalSize,
|
|
1135
1227
|
multiple = true,
|
|
1136
1228
|
onChange,
|
|
1137
1229
|
onDrop,
|
|
@@ -1195,6 +1287,7 @@ var FileSelector = ({
|
|
|
1195
1287
|
enableDropArea,
|
|
1196
1288
|
maxFiles,
|
|
1197
1289
|
maxSize,
|
|
1290
|
+
maxTotalSize,
|
|
1198
1291
|
multiple,
|
|
1199
1292
|
onChange,
|
|
1200
1293
|
onDrop,
|
|
@@ -1208,7 +1301,9 @@ var FileSelector = ({
|
|
|
1208
1301
|
{
|
|
1209
1302
|
allowedFileTypes,
|
|
1210
1303
|
maxFileSize: maxSize,
|
|
1304
|
+
maxTotalSize,
|
|
1211
1305
|
customSizeMessage,
|
|
1306
|
+
customTotalSizeMessage,
|
|
1212
1307
|
customTypesMessage,
|
|
1213
1308
|
variant: "caption"
|
|
1214
1309
|
}
|
|
@@ -1216,11 +1311,12 @@ var FileSelector = ({
|
|
|
1216
1311
|
children
|
|
1217
1312
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_mui_layout7.Grid, { container: true, rowSpacing: 3, flexDirection: "column", children: [
|
|
1218
1313
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_mui_layout7.Grid, { children: [
|
|
1219
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(HeaderMessage, { maxFiles, maxSize }),
|
|
1314
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(HeaderMessage, { maxFiles, maxSize, maxTotalSize }),
|
|
1220
1315
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1221
1316
|
FileTypesMessage,
|
|
1222
1317
|
{
|
|
1223
1318
|
allowedFileTypes,
|
|
1319
|
+
customTotalSizeMessage,
|
|
1224
1320
|
customSizeMessage,
|
|
1225
1321
|
customTypesMessage,
|
|
1226
1322
|
variant: "body2"
|
|
@@ -1237,6 +1333,7 @@ var FileSelector = ({
|
|
|
1237
1333
|
enableDropArea,
|
|
1238
1334
|
maxFiles,
|
|
1239
1335
|
maxSize,
|
|
1336
|
+
maxTotalSize,
|
|
1240
1337
|
multiple,
|
|
1241
1338
|
onChange,
|
|
1242
1339
|
onDrop,
|
|
@@ -1298,6 +1395,7 @@ var FileSelector2 = ({
|
|
|
1298
1395
|
clientId,
|
|
1299
1396
|
children,
|
|
1300
1397
|
customSizeMessage,
|
|
1398
|
+
customTotalSizeMessage,
|
|
1301
1399
|
customTypesMessage,
|
|
1302
1400
|
customerId,
|
|
1303
1401
|
customFileRow,
|
|
@@ -1308,6 +1406,7 @@ var FileSelector2 = ({
|
|
|
1308
1406
|
label = "Upload file",
|
|
1309
1407
|
maxFiles,
|
|
1310
1408
|
maxSize,
|
|
1409
|
+
maxTotalSize,
|
|
1311
1410
|
multiple = true,
|
|
1312
1411
|
onChange,
|
|
1313
1412
|
onDrop,
|
|
@@ -1368,6 +1467,7 @@ var FileSelector2 = ({
|
|
|
1368
1467
|
enableDropArea,
|
|
1369
1468
|
maxFiles,
|
|
1370
1469
|
maxSize,
|
|
1470
|
+
maxTotalSize,
|
|
1371
1471
|
multiple,
|
|
1372
1472
|
onChange,
|
|
1373
1473
|
onDrop,
|
|
@@ -1382,7 +1482,9 @@ var FileSelector2 = ({
|
|
|
1382
1482
|
{
|
|
1383
1483
|
allowedFileTypes,
|
|
1384
1484
|
maxFileSize: maxSize,
|
|
1485
|
+
maxTotalSize,
|
|
1385
1486
|
customSizeMessage,
|
|
1487
|
+
customTotalSizeMessage,
|
|
1386
1488
|
customTypesMessage,
|
|
1387
1489
|
variant: "caption"
|
|
1388
1490
|
}
|
|
@@ -1390,12 +1492,13 @@ var FileSelector2 = ({
|
|
|
1390
1492
|
children
|
|
1391
1493
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_mui_layout8.Grid, { container: true, rowSpacing: 3, flexDirection: "column", children: [
|
|
1392
1494
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_mui_layout8.Grid, { children: [
|
|
1393
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(HeaderMessage, { maxFiles, maxSize }),
|
|
1495
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(HeaderMessage, { maxFiles, maxSize, maxTotalSize }),
|
|
1394
1496
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1395
1497
|
FileTypesMessage,
|
|
1396
1498
|
{
|
|
1397
1499
|
allowedFileTypes,
|
|
1398
1500
|
customSizeMessage,
|
|
1501
|
+
customTotalSizeMessage,
|
|
1399
1502
|
customTypesMessage,
|
|
1400
1503
|
variant: "body2"
|
|
1401
1504
|
}
|
|
@@ -1411,6 +1514,7 @@ var FileSelector2 = ({
|
|
|
1411
1514
|
enableDropArea,
|
|
1412
1515
|
maxFiles,
|
|
1413
1516
|
maxSize,
|
|
1517
|
+
maxTotalSize,
|
|
1414
1518
|
multiple,
|
|
1415
1519
|
onChange,
|
|
1416
1520
|
onDrop,
|