@availity/mui-file-selector 1.8.0 → 1.8.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/CHANGELOG.md +7 -0
- package/dist/index.d.mts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +51 -7
- package/dist/index.mjs +51 -7
- package/package.json +1 -1
- package/src/lib/Dropzone.tsx +38 -3
- package/src/lib/Dropzone2.tsx +32 -4
- package/src/lib/FileSelector.tsx +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [1.8.1](https://github.com/Availity/element/compare/@availity/mui-file-selector@1.8.0...@availity/mui-file-selector@1.8.1) (2025-06-16)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **mui-file-selector:** ensure allowedFileTypes and allowedFileNameCharacters validation ([bb0f3ea](https://github.com/Availity/element/commit/bb0f3eaa1dcab2e82f5037f534e959321366701a))
|
|
11
|
+
|
|
5
12
|
## [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
13
|
|
|
7
14
|
|
package/dist/index.d.mts
CHANGED
|
@@ -38,6 +38,11 @@ type DropzoneProps = {
|
|
|
38
38
|
* List of allowed file extensions (e.g. ['.pdf', '.doc']). Each extension must start with a dot
|
|
39
39
|
*/
|
|
40
40
|
allowedFileTypes?: `.${string}`[];
|
|
41
|
+
/**
|
|
42
|
+
* Regular expression pattern of allowed characters in file names
|
|
43
|
+
* @example "a-zA-Z0-9-_."
|
|
44
|
+
*/
|
|
45
|
+
allowedFileNameCharacters?: string;
|
|
41
46
|
/**
|
|
42
47
|
* Whether the dropzone is disabled
|
|
43
48
|
*/
|
|
@@ -92,7 +97,7 @@ type DropzoneProps = {
|
|
|
92
97
|
validator?: (file: File) => FileError | FileError[] | null;
|
|
93
98
|
};
|
|
94
99
|
declare const DropzoneContainer: typeof MuiBox;
|
|
95
|
-
declare const Dropzone: ({ allowedFileTypes, disabled, enableDropArea, maxFiles, maxSize, maxTotalSize, multiple, name, onChange, onClick, onDrop, setFileRejections, setTotalSize, validator, }: DropzoneProps) => react_jsx_runtime.JSX.Element;
|
|
100
|
+
declare const Dropzone: ({ allowedFileTypes, allowedFileNameCharacters, disabled, enableDropArea, maxFiles, maxSize, maxTotalSize, multiple, name, onChange, onClick, onDrop, setFileRejections, setTotalSize, validator, }: DropzoneProps) => react_jsx_runtime.JSX.Element;
|
|
96
101
|
|
|
97
102
|
type Dropzone2Props = DropzoneProps & {
|
|
98
103
|
uploadOptions: UploadOptions;
|
package/dist/index.d.ts
CHANGED
|
@@ -38,6 +38,11 @@ type DropzoneProps = {
|
|
|
38
38
|
* List of allowed file extensions (e.g. ['.pdf', '.doc']). Each extension must start with a dot
|
|
39
39
|
*/
|
|
40
40
|
allowedFileTypes?: `.${string}`[];
|
|
41
|
+
/**
|
|
42
|
+
* Regular expression pattern of allowed characters in file names
|
|
43
|
+
* @example "a-zA-Z0-9-_."
|
|
44
|
+
*/
|
|
45
|
+
allowedFileNameCharacters?: string;
|
|
41
46
|
/**
|
|
42
47
|
* Whether the dropzone is disabled
|
|
43
48
|
*/
|
|
@@ -92,7 +97,7 @@ type DropzoneProps = {
|
|
|
92
97
|
validator?: (file: File) => FileError | FileError[] | null;
|
|
93
98
|
};
|
|
94
99
|
declare const DropzoneContainer: typeof MuiBox;
|
|
95
|
-
declare const Dropzone: ({ allowedFileTypes, disabled, enableDropArea, maxFiles, maxSize, maxTotalSize, multiple, name, onChange, onClick, onDrop, setFileRejections, setTotalSize, validator, }: DropzoneProps) => react_jsx_runtime.JSX.Element;
|
|
100
|
+
declare const Dropzone: ({ allowedFileTypes, allowedFileNameCharacters, disabled, enableDropArea, maxFiles, maxSize, maxTotalSize, multiple, name, onChange, onClick, onDrop, setFileRejections, setTotalSize, validator, }: DropzoneProps) => react_jsx_runtime.JSX.Element;
|
|
96
101
|
|
|
97
102
|
type Dropzone2Props = DropzoneProps & {
|
|
98
103
|
uploadOptions: UploadOptions;
|
package/dist/index.js
CHANGED
|
@@ -250,6 +250,7 @@ var DropzoneContainer = (0, import_styles.styled)(import_mui_layout.Box, { name:
|
|
|
250
250
|
});
|
|
251
251
|
var Dropzone = ({
|
|
252
252
|
allowedFileTypes = [],
|
|
253
|
+
allowedFileNameCharacters,
|
|
253
254
|
disabled,
|
|
254
255
|
enableDropArea = true,
|
|
255
256
|
maxFiles,
|
|
@@ -284,6 +285,27 @@ var Dropzone = ({
|
|
|
284
285
|
message: `Too many files. You may only upload ${maxFiles} file(s).`
|
|
285
286
|
});
|
|
286
287
|
}
|
|
288
|
+
if (allowedFileNameCharacters) {
|
|
289
|
+
const fileName = file.name.substring(0, file.name.lastIndexOf("."));
|
|
290
|
+
const regExp = new RegExp(`([^${allowedFileNameCharacters}])`, "g");
|
|
291
|
+
if (fileName.match(regExp) !== null) {
|
|
292
|
+
errors.push({
|
|
293
|
+
code: "invalid-file-name-characters",
|
|
294
|
+
message: "File name contains characters not allowed"
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (allowedFileTypes.length > 0) {
|
|
299
|
+
const fileName = file.name;
|
|
300
|
+
const fileExt = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
|
|
301
|
+
const lowerCaseAllowedTypes = allowedFileTypes.map((type) => type.toLowerCase());
|
|
302
|
+
if (!lowerCaseAllowedTypes.includes(fileExt)) {
|
|
303
|
+
errors.push({
|
|
304
|
+
code: "file-invalid-type",
|
|
305
|
+
message: `File type ${fileExt} is not allowed`
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
287
309
|
if (validator) {
|
|
288
310
|
const validatorErrors = validator(file);
|
|
289
311
|
if (validatorErrors) {
|
|
@@ -296,7 +318,7 @@ var Dropzone = ({
|
|
|
296
318
|
}
|
|
297
319
|
return errors.length > 0 ? errors : null;
|
|
298
320
|
},
|
|
299
|
-
[maxFiles, validator]
|
|
321
|
+
[maxFiles, validator, allowedFileNameCharacters, watch, name, allowedFileTypes]
|
|
300
322
|
);
|
|
301
323
|
const handleOnDrop = (0, import_react.useCallback)(
|
|
302
324
|
(acceptedFiles, fileRejections, event) => {
|
|
@@ -375,7 +397,7 @@ var Dropzone = ({
|
|
|
375
397
|
if (setFileRejections) setFileRejections(fileRejections);
|
|
376
398
|
if (onDrop) onDrop(acceptedFiles, fileRejections, event);
|
|
377
399
|
},
|
|
378
|
-
[setFileRejections]
|
|
400
|
+
[setFileRejections, setTotalSize, watch, name, maxTotalSize, maxFiles, setValue, onDrop]
|
|
379
401
|
);
|
|
380
402
|
const accept = allowedFileTypes.join(",");
|
|
381
403
|
const { getRootProps, getInputProps } = (0, import_react_dropzone.useDropzone)({
|
|
@@ -400,7 +422,7 @@ var Dropzone = ({
|
|
|
400
422
|
};
|
|
401
423
|
const handleOnClick = (event) => {
|
|
402
424
|
if (!enableDropArea && rootProps.onClick) rootProps.onClick(event);
|
|
403
|
-
if (onClick) onClick;
|
|
425
|
+
if (onClick) onClick(event);
|
|
404
426
|
};
|
|
405
427
|
const getFieldValue = () => {
|
|
406
428
|
const field = getValues();
|
|
@@ -502,6 +524,27 @@ var Dropzone2 = ({
|
|
|
502
524
|
message: `Too many files. You may only upload ${maxFiles} file(s).`
|
|
503
525
|
});
|
|
504
526
|
}
|
|
527
|
+
if (uploadOptions.allowedFileNameCharacters) {
|
|
528
|
+
const fileName = file.name.substring(0, file.name.lastIndexOf("."));
|
|
529
|
+
const regExp = new RegExp(`([^${uploadOptions.allowedFileNameCharacters}])`, "g");
|
|
530
|
+
if (fileName.match(regExp) !== null) {
|
|
531
|
+
errors.push({
|
|
532
|
+
code: "invalid-file-name-characters",
|
|
533
|
+
message: "File name contains characters not allowed"
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
if (allowedFileTypes.length > 0) {
|
|
538
|
+
const fileName = file.name;
|
|
539
|
+
const fileExt = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
|
|
540
|
+
const lowerCaseAllowedTypes = allowedFileTypes.map((type) => type.toLowerCase());
|
|
541
|
+
if (!lowerCaseAllowedTypes.includes(fileExt)) {
|
|
542
|
+
errors.push({
|
|
543
|
+
code: "file-invalid-type",
|
|
544
|
+
message: `File type ${fileExt} is not allowed`
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
}
|
|
505
548
|
if (validator) {
|
|
506
549
|
const validatorErrors = validator(file);
|
|
507
550
|
if (validatorErrors) {
|
|
@@ -514,7 +557,7 @@ var Dropzone2 = ({
|
|
|
514
557
|
}
|
|
515
558
|
return errors.length > 0 ? dedupeErrors(errors) : null;
|
|
516
559
|
},
|
|
517
|
-
[maxFiles, validator]
|
|
560
|
+
[maxFiles, validator, uploadOptions.allowedFileNameCharacters, allowedFileTypes, watch, name]
|
|
518
561
|
);
|
|
519
562
|
const handleOnDrop = (0, import_react2.useCallback)(
|
|
520
563
|
(acceptedFiles, fileRejections, event) => __async(void 0, null, function* () {
|
|
@@ -527,7 +570,6 @@ var Dropzone2 = ({
|
|
|
527
570
|
const previous = (_a2 = watch(name)) != null ? _a2 : [];
|
|
528
571
|
if (maxTotalSize) {
|
|
529
572
|
const currentTotalSize = previous.reduce((sum, upload) => sum + upload.file.size, 0);
|
|
530
|
-
console.log({ previous });
|
|
531
573
|
let newSize2 = 0;
|
|
532
574
|
const availableSize = Math.max(0, maxTotalSize - currentTotalSize);
|
|
533
575
|
let sizeCounter = 0;
|
|
@@ -595,7 +637,7 @@ var Dropzone2 = ({
|
|
|
595
637
|
if (setFileRejections) setFileRejections(fileRejections);
|
|
596
638
|
if (onDrop) onDrop(acceptedFiles, fileRejections, event);
|
|
597
639
|
}),
|
|
598
|
-
[setFileRejections]
|
|
640
|
+
[setFileRejections, setTotalSize, watch, name, maxTotalSize, maxFiles, uploadOptions, setValue, onDrop]
|
|
599
641
|
);
|
|
600
642
|
const { getRootProps, getInputProps } = (0, import_react_dropzone2.useDropzone)({
|
|
601
643
|
onDrop: handleOnDrop,
|
|
@@ -619,7 +661,7 @@ var Dropzone2 = ({
|
|
|
619
661
|
};
|
|
620
662
|
const handleOnClick = (event) => {
|
|
621
663
|
if (!enableDropArea && rootProps.onClick) rootProps.onClick(event);
|
|
622
|
-
if (onClick) onClick;
|
|
664
|
+
if (onClick) onClick(event);
|
|
623
665
|
};
|
|
624
666
|
const getFieldValue = () => {
|
|
625
667
|
const field = getValues();
|
|
@@ -1283,6 +1325,7 @@ var FileSelector = ({
|
|
|
1283
1325
|
{
|
|
1284
1326
|
name,
|
|
1285
1327
|
allowedFileTypes,
|
|
1328
|
+
allowedFileNameCharacters,
|
|
1286
1329
|
disabled,
|
|
1287
1330
|
enableDropArea,
|
|
1288
1331
|
maxFiles,
|
|
@@ -1329,6 +1372,7 @@ var FileSelector = ({
|
|
|
1329
1372
|
{
|
|
1330
1373
|
name,
|
|
1331
1374
|
allowedFileTypes,
|
|
1375
|
+
allowedFileNameCharacters,
|
|
1332
1376
|
disabled,
|
|
1333
1377
|
enableDropArea,
|
|
1334
1378
|
maxFiles,
|
package/dist/index.mjs
CHANGED
|
@@ -209,6 +209,7 @@ var DropzoneContainer = styled(Box, { name: "AvDropzoneContainer", slot: "root"
|
|
|
209
209
|
});
|
|
210
210
|
var Dropzone = ({
|
|
211
211
|
allowedFileTypes = [],
|
|
212
|
+
allowedFileNameCharacters,
|
|
212
213
|
disabled,
|
|
213
214
|
enableDropArea = true,
|
|
214
215
|
maxFiles,
|
|
@@ -243,6 +244,27 @@ var Dropzone = ({
|
|
|
243
244
|
message: `Too many files. You may only upload ${maxFiles} file(s).`
|
|
244
245
|
});
|
|
245
246
|
}
|
|
247
|
+
if (allowedFileNameCharacters) {
|
|
248
|
+
const fileName = file.name.substring(0, file.name.lastIndexOf("."));
|
|
249
|
+
const regExp = new RegExp(`([^${allowedFileNameCharacters}])`, "g");
|
|
250
|
+
if (fileName.match(regExp) !== null) {
|
|
251
|
+
errors.push({
|
|
252
|
+
code: "invalid-file-name-characters",
|
|
253
|
+
message: "File name contains characters not allowed"
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (allowedFileTypes.length > 0) {
|
|
258
|
+
const fileName = file.name;
|
|
259
|
+
const fileExt = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
|
|
260
|
+
const lowerCaseAllowedTypes = allowedFileTypes.map((type) => type.toLowerCase());
|
|
261
|
+
if (!lowerCaseAllowedTypes.includes(fileExt)) {
|
|
262
|
+
errors.push({
|
|
263
|
+
code: "file-invalid-type",
|
|
264
|
+
message: `File type ${fileExt} is not allowed`
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
246
268
|
if (validator) {
|
|
247
269
|
const validatorErrors = validator(file);
|
|
248
270
|
if (validatorErrors) {
|
|
@@ -255,7 +277,7 @@ var Dropzone = ({
|
|
|
255
277
|
}
|
|
256
278
|
return errors.length > 0 ? errors : null;
|
|
257
279
|
},
|
|
258
|
-
[maxFiles, validator]
|
|
280
|
+
[maxFiles, validator, allowedFileNameCharacters, watch, name, allowedFileTypes]
|
|
259
281
|
);
|
|
260
282
|
const handleOnDrop = useCallback(
|
|
261
283
|
(acceptedFiles, fileRejections, event) => {
|
|
@@ -334,7 +356,7 @@ var Dropzone = ({
|
|
|
334
356
|
if (setFileRejections) setFileRejections(fileRejections);
|
|
335
357
|
if (onDrop) onDrop(acceptedFiles, fileRejections, event);
|
|
336
358
|
},
|
|
337
|
-
[setFileRejections]
|
|
359
|
+
[setFileRejections, setTotalSize, watch, name, maxTotalSize, maxFiles, setValue, onDrop]
|
|
338
360
|
);
|
|
339
361
|
const accept = allowedFileTypes.join(",");
|
|
340
362
|
const { getRootProps, getInputProps } = useDropzone({
|
|
@@ -359,7 +381,7 @@ var Dropzone = ({
|
|
|
359
381
|
};
|
|
360
382
|
const handleOnClick = (event) => {
|
|
361
383
|
if (!enableDropArea && rootProps.onClick) rootProps.onClick(event);
|
|
362
|
-
if (onClick) onClick;
|
|
384
|
+
if (onClick) onClick(event);
|
|
363
385
|
};
|
|
364
386
|
const getFieldValue = () => {
|
|
365
387
|
const field = getValues();
|
|
@@ -461,6 +483,27 @@ var Dropzone2 = ({
|
|
|
461
483
|
message: `Too many files. You may only upload ${maxFiles} file(s).`
|
|
462
484
|
});
|
|
463
485
|
}
|
|
486
|
+
if (uploadOptions.allowedFileNameCharacters) {
|
|
487
|
+
const fileName = file.name.substring(0, file.name.lastIndexOf("."));
|
|
488
|
+
const regExp = new RegExp(`([^${uploadOptions.allowedFileNameCharacters}])`, "g");
|
|
489
|
+
if (fileName.match(regExp) !== null) {
|
|
490
|
+
errors.push({
|
|
491
|
+
code: "invalid-file-name-characters",
|
|
492
|
+
message: "File name contains characters not allowed"
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
if (allowedFileTypes.length > 0) {
|
|
497
|
+
const fileName = file.name;
|
|
498
|
+
const fileExt = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
|
|
499
|
+
const lowerCaseAllowedTypes = allowedFileTypes.map((type) => type.toLowerCase());
|
|
500
|
+
if (!lowerCaseAllowedTypes.includes(fileExt)) {
|
|
501
|
+
errors.push({
|
|
502
|
+
code: "file-invalid-type",
|
|
503
|
+
message: `File type ${fileExt} is not allowed`
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
}
|
|
464
507
|
if (validator) {
|
|
465
508
|
const validatorErrors = validator(file);
|
|
466
509
|
if (validatorErrors) {
|
|
@@ -473,7 +516,7 @@ var Dropzone2 = ({
|
|
|
473
516
|
}
|
|
474
517
|
return errors.length > 0 ? dedupeErrors(errors) : null;
|
|
475
518
|
},
|
|
476
|
-
[maxFiles, validator]
|
|
519
|
+
[maxFiles, validator, uploadOptions.allowedFileNameCharacters, allowedFileTypes, watch, name]
|
|
477
520
|
);
|
|
478
521
|
const handleOnDrop = useCallback2(
|
|
479
522
|
(acceptedFiles, fileRejections, event) => __async(void 0, null, function* () {
|
|
@@ -486,7 +529,6 @@ var Dropzone2 = ({
|
|
|
486
529
|
const previous = (_a2 = watch(name)) != null ? _a2 : [];
|
|
487
530
|
if (maxTotalSize) {
|
|
488
531
|
const currentTotalSize = previous.reduce((sum, upload) => sum + upload.file.size, 0);
|
|
489
|
-
console.log({ previous });
|
|
490
532
|
let newSize2 = 0;
|
|
491
533
|
const availableSize = Math.max(0, maxTotalSize - currentTotalSize);
|
|
492
534
|
let sizeCounter = 0;
|
|
@@ -554,7 +596,7 @@ var Dropzone2 = ({
|
|
|
554
596
|
if (setFileRejections) setFileRejections(fileRejections);
|
|
555
597
|
if (onDrop) onDrop(acceptedFiles, fileRejections, event);
|
|
556
598
|
}),
|
|
557
|
-
[setFileRejections]
|
|
599
|
+
[setFileRejections, setTotalSize, watch, name, maxTotalSize, maxFiles, uploadOptions, setValue, onDrop]
|
|
558
600
|
);
|
|
559
601
|
const { getRootProps, getInputProps } = useDropzone2({
|
|
560
602
|
onDrop: handleOnDrop,
|
|
@@ -578,7 +620,7 @@ var Dropzone2 = ({
|
|
|
578
620
|
};
|
|
579
621
|
const handleOnClick = (event) => {
|
|
580
622
|
if (!enableDropArea && rootProps.onClick) rootProps.onClick(event);
|
|
581
|
-
if (onClick) onClick;
|
|
623
|
+
if (onClick) onClick(event);
|
|
582
624
|
};
|
|
583
625
|
const getFieldValue = () => {
|
|
584
626
|
const field = getValues();
|
|
@@ -1248,6 +1290,7 @@ var FileSelector = ({
|
|
|
1248
1290
|
{
|
|
1249
1291
|
name,
|
|
1250
1292
|
allowedFileTypes,
|
|
1293
|
+
allowedFileNameCharacters,
|
|
1251
1294
|
disabled,
|
|
1252
1295
|
enableDropArea,
|
|
1253
1296
|
maxFiles,
|
|
@@ -1294,6 +1337,7 @@ var FileSelector = ({
|
|
|
1294
1337
|
{
|
|
1295
1338
|
name,
|
|
1296
1339
|
allowedFileTypes,
|
|
1340
|
+
allowedFileNameCharacters,
|
|
1297
1341
|
disabled,
|
|
1298
1342
|
enableDropArea,
|
|
1299
1343
|
maxFiles,
|
package/package.json
CHANGED
package/src/lib/Dropzone.tsx
CHANGED
|
@@ -51,6 +51,11 @@ export type DropzoneProps = {
|
|
|
51
51
|
* List of allowed file extensions (e.g. ['.pdf', '.doc']). Each extension must start with a dot
|
|
52
52
|
*/
|
|
53
53
|
allowedFileTypes?: `.${string}`[];
|
|
54
|
+
/**
|
|
55
|
+
* Regular expression pattern of allowed characters in file names
|
|
56
|
+
* @example "a-zA-Z0-9-_."
|
|
57
|
+
*/
|
|
58
|
+
allowedFileNameCharacters?: string;
|
|
54
59
|
/**
|
|
55
60
|
* Whether the dropzone is disabled
|
|
56
61
|
*/
|
|
@@ -111,6 +116,7 @@ export const DropzoneContainer = styled(Box, { name: 'AvDropzoneContainer', slot
|
|
|
111
116
|
|
|
112
117
|
export const Dropzone = ({
|
|
113
118
|
allowedFileTypes = [],
|
|
119
|
+
allowedFileNameCharacters,
|
|
114
120
|
disabled,
|
|
115
121
|
enableDropArea = true,
|
|
116
122
|
maxFiles,
|
|
@@ -147,6 +153,35 @@ export const Dropzone = ({
|
|
|
147
153
|
message: `Too many files. You may only upload ${maxFiles} file(s).`,
|
|
148
154
|
});
|
|
149
155
|
}
|
|
156
|
+
|
|
157
|
+
// Check for allowed file name characters
|
|
158
|
+
if (allowedFileNameCharacters) {
|
|
159
|
+
const fileName = file.name.substring(0, file.name.lastIndexOf('.'));
|
|
160
|
+
const regExp = new RegExp(`([^${allowedFileNameCharacters}])`, 'g');
|
|
161
|
+
|
|
162
|
+
if (fileName.match(regExp) !== null) {
|
|
163
|
+
errors.push({
|
|
164
|
+
code: 'invalid-file-name-characters',
|
|
165
|
+
message: 'File name contains characters not allowed',
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Explicit check for allowed file types
|
|
171
|
+
if (allowedFileTypes.length > 0) {
|
|
172
|
+
const fileName = file.name;
|
|
173
|
+
const fileExt = fileName.substring(fileName.lastIndexOf('.')).toLowerCase();
|
|
174
|
+
|
|
175
|
+
// Convert all file types to lowercase for comparison
|
|
176
|
+
const lowerCaseAllowedTypes = allowedFileTypes.map(type => type.toLowerCase());
|
|
177
|
+
|
|
178
|
+
if (!lowerCaseAllowedTypes.includes(fileExt)) {
|
|
179
|
+
errors.push({
|
|
180
|
+
code: 'file-invalid-type',
|
|
181
|
+
message: `File type ${fileExt} is not allowed`,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
150
185
|
|
|
151
186
|
if (validator) {
|
|
152
187
|
const validatorErrors = validator(file);
|
|
@@ -161,7 +196,7 @@ export const Dropzone = ({
|
|
|
161
196
|
|
|
162
197
|
return errors.length > 0 ? errors : null;
|
|
163
198
|
},
|
|
164
|
-
[maxFiles, validator]
|
|
199
|
+
[maxFiles, validator, allowedFileNameCharacters, watch, name, allowedFileTypes]
|
|
165
200
|
);
|
|
166
201
|
|
|
167
202
|
const handleOnDrop = useCallback(
|
|
@@ -268,7 +303,7 @@ export const Dropzone = ({
|
|
|
268
303
|
if (setFileRejections) setFileRejections(fileRejections);
|
|
269
304
|
if (onDrop) onDrop(acceptedFiles, fileRejections, event);
|
|
270
305
|
},
|
|
271
|
-
[setFileRejections]
|
|
306
|
+
[setFileRejections, setTotalSize, watch, name, maxTotalSize, maxFiles, setValue, onDrop]
|
|
272
307
|
);
|
|
273
308
|
|
|
274
309
|
const accept = allowedFileTypes.join(',');
|
|
@@ -301,7 +336,7 @@ export const Dropzone = ({
|
|
|
301
336
|
|
|
302
337
|
const handleOnClick = (event: MouseEvent<HTMLButtonElement>) => {
|
|
303
338
|
if (!enableDropArea && rootProps.onClick) rootProps.onClick(event);
|
|
304
|
-
if (onClick) onClick;
|
|
339
|
+
if (onClick) onClick(event);
|
|
305
340
|
};
|
|
306
341
|
|
|
307
342
|
const getFieldValue = () => {
|
package/src/lib/Dropzone2.tsx
CHANGED
|
@@ -94,6 +94,35 @@ export const Dropzone2 = ({
|
|
|
94
94
|
message: `Too many files. You may only upload ${maxFiles} file(s).`,
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
|
+
|
|
98
|
+
// Check for allowed file name characters
|
|
99
|
+
if (uploadOptions.allowedFileNameCharacters) {
|
|
100
|
+
const fileName = file.name.substring(0, file.name.lastIndexOf('.'));
|
|
101
|
+
const regExp = new RegExp(`([^${uploadOptions.allowedFileNameCharacters}])`, 'g');
|
|
102
|
+
|
|
103
|
+
if (fileName.match(regExp) !== null) {
|
|
104
|
+
errors.push({
|
|
105
|
+
code: 'invalid-file-name-characters',
|
|
106
|
+
message: 'File name contains characters not allowed',
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Explicit check for allowed file types
|
|
112
|
+
if (allowedFileTypes.length > 0) {
|
|
113
|
+
const fileName = file.name;
|
|
114
|
+
const fileExt = fileName.substring(fileName.lastIndexOf('.')).toLowerCase();
|
|
115
|
+
|
|
116
|
+
// Convert all file types to lowercase for comparison
|
|
117
|
+
const lowerCaseAllowedTypes = allowedFileTypes.map(type => type.toLowerCase());
|
|
118
|
+
|
|
119
|
+
if (!lowerCaseAllowedTypes.includes(fileExt)) {
|
|
120
|
+
errors.push({
|
|
121
|
+
code: 'file-invalid-type',
|
|
122
|
+
message: `File type ${fileExt} is not allowed`,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
97
126
|
|
|
98
127
|
if (validator) {
|
|
99
128
|
const validatorErrors = validator(file);
|
|
@@ -108,7 +137,7 @@ export const Dropzone2 = ({
|
|
|
108
137
|
|
|
109
138
|
return errors.length > 0 ? dedupeErrors(errors) : null;
|
|
110
139
|
},
|
|
111
|
-
[maxFiles, validator]
|
|
140
|
+
[maxFiles, validator, uploadOptions.allowedFileNameCharacters, allowedFileTypes, watch, name]
|
|
112
141
|
);
|
|
113
142
|
|
|
114
143
|
const handleOnDrop = useCallback(
|
|
@@ -125,7 +154,6 @@ export const Dropzone2 = ({
|
|
|
125
154
|
if (maxTotalSize) {
|
|
126
155
|
// Calculate current total size
|
|
127
156
|
const currentTotalSize = previous.reduce((sum: number, upload: Upload) => sum + upload.file.size, 0);
|
|
128
|
-
console.log({ previous });
|
|
129
157
|
let newSize = 0;
|
|
130
158
|
|
|
131
159
|
const availableSize = Math.max(0, maxTotalSize - currentTotalSize);
|
|
@@ -217,7 +245,7 @@ export const Dropzone2 = ({
|
|
|
217
245
|
if (setFileRejections) setFileRejections(fileRejections);
|
|
218
246
|
if (onDrop) onDrop(acceptedFiles, fileRejections, event);
|
|
219
247
|
},
|
|
220
|
-
[setFileRejections]
|
|
248
|
+
[setFileRejections, setTotalSize, watch, name, maxTotalSize, maxFiles, uploadOptions, setValue, onDrop]
|
|
221
249
|
);
|
|
222
250
|
|
|
223
251
|
const { getRootProps, getInputProps } = useDropzone({
|
|
@@ -248,7 +276,7 @@ export const Dropzone2 = ({
|
|
|
248
276
|
|
|
249
277
|
const handleOnClick = (event: MouseEvent<HTMLButtonElement>) => {
|
|
250
278
|
if (!enableDropArea && rootProps.onClick) rootProps.onClick(event);
|
|
251
|
-
if (onClick) onClick;
|
|
279
|
+
if (onClick) onClick(event);
|
|
252
280
|
};
|
|
253
281
|
|
|
254
282
|
const getFieldValue = () => {
|
package/src/lib/FileSelector.tsx
CHANGED
|
@@ -249,6 +249,7 @@ export const FileSelector = ({
|
|
|
249
249
|
<Dropzone
|
|
250
250
|
name={name}
|
|
251
251
|
allowedFileTypes={allowedFileTypes}
|
|
252
|
+
allowedFileNameCharacters={allowedFileNameCharacters}
|
|
252
253
|
disabled={disabled}
|
|
253
254
|
enableDropArea={enableDropArea}
|
|
254
255
|
maxFiles={maxFiles}
|
|
@@ -289,6 +290,7 @@ export const FileSelector = ({
|
|
|
289
290
|
<Dropzone
|
|
290
291
|
name={name}
|
|
291
292
|
allowedFileTypes={allowedFileTypes}
|
|
293
|
+
allowedFileNameCharacters={allowedFileNameCharacters}
|
|
292
294
|
disabled={disabled}
|
|
293
295
|
enableDropArea={enableDropArea}
|
|
294
296
|
maxFiles={maxFiles}
|