@@ -2,50 +2,48 @@ import 'react-app-polyfill/ie11';
22import * as React from 'react' ;
33import * as ReactDOM from 'react-dom' ;
44import { useFilePicker } from '../src' ;
5- import type { Validator } from '../src' ;
5+ import { Validator , ImageDimensionsValidator , FileAmountLimitValidator } from '../src/validators' ;
6+ import { UseFilePickerConfig } from '../src/types' ;
67import Imperative from './imperative' ;
8+ import { FileWithPath } from 'file-selector' ;
79
8- const customValidator : Validator = {
10+ class CustomValidator extends Validator {
911 /**
1012 * Validation takes place before parsing. You have access to config passed as argument to useFilePicker hook
1113 * and all plain file objects of selected files by user. Called once for all files after selection.
1214 * Example validator below allowes only even amount of files
1315 * @returns {Promise } resolve means that file passed validation, reject means that file did not pass
1416 */
15- validateBeforeParsing : async ( config , plainFiles ) =>
16- new Promise ( ( res , rej ) => ( plainFiles . length % 2 === 0 ? res ( undefined ) : rej ( { oddNumberOfFiles : true } ) ) ) ,
17+ async validateBeforeParsing ( config : UseFilePickerConfig , plainFiles : File [ ] ) : Promise < void > {
18+ return new Promise ( ( res , rej ) => ( plainFiles . length % 2 === 0 ? res ( undefined ) : rej ( { oddNumberOfFiles : true } ) ) ) ;
19+ }
1720 /**
1821 * Validation takes place after parsing (or is never called if readFilesContent is set to false).
1922 * You have access to config passed as argument to useFilePicker hook, FileWithPath object that is currently
2023 * being validated and the reader object that has loaded that file. Called individually for every file.
2124 * Example validator below allowes only if file hasn't been modified in last 24 hours
2225 * @returns {Promise } resolve means that file passed validation, reject means that file did not pass
2326 */
24- validateAfterParsing : async ( config , file , reader ) =>
25- new Promise ( ( res , rej ) =>
27+ async validateAfterParsing ( config : UseFilePickerConfig , file : FileWithPath , reader : FileReader ) : Promise < void > {
28+ return new Promise ( ( res , rej ) =>
2629 file . lastModified < new Date ( ) . getTime ( ) - 24 * 60 * 60 * 1000
2730 ? res ( undefined )
2831 : rej ( { fileRecentlyModified : true , lastModified : file . lastModified } )
29- ) ,
30- } ;
32+ ) ;
33+ }
34+ }
3135
3236const App = ( ) => {
33- const [ openFileSelector , { filesContent, loading, errors, plainFiles, clear } ] = useFilePicker ( {
37+ const { openFilePicker , filesContent, loading, errors, plainFiles, clear } = useFilePicker ( {
3438 multiple : true ,
3539 readAs : 'DataURL' , // availible formats: "Text" | "BinaryString" | "ArrayBuffer" | "DataURL"
36- // accept: '.ics,.pdf',
3740 accept : [ '.png' , '.jpeg' , '.heic' ] ,
38- limitFilesConfig : { min : 2 , max : 3 } ,
39- // minFileSize: 1, // in megabytes
40- // maxFileSize: 1,
41- // imageSizeRestrictions: {
42- // maxHeight: 1024, // in pixels
43- // maxWidth: 1024,
44- // minHeight: 768,
45- // minWidth: 768,
46- // },
4741 // readFilesContent: false, // ignores file content,
48- // validators: [customValidator],
42+ validators : [
43+ new FileAmountLimitValidator ( { min : 1 , max : 3 } ) ,
44+ // new FileSizeValidator({ maxFileSize: 100_000 /* 100kb in bytes */ }),
45+ new ImageDimensionsValidator ( { maxHeight : 600 } ) ,
46+ ] ,
4947 onFilesSelected : ( { plainFiles, filesContent, errors } ) => {
5048 // this callback is always called, even if there are errors
5149 console . log ( 'onFilesSelected' , plainFiles , filesContent , errors ) ;
@@ -54,42 +52,42 @@ const App = () => {
5452 // this callback is called when there were validation errors
5553 console . log ( 'onFilesRejected' , errors ) ;
5654 } ,
57- onFilesSuccessfulySelected : ( { plainFiles, filesContent } ) => {
55+ onFilesSuccessfullySelected : ( { plainFiles, filesContent } ) => {
5856 // this callback is called when there were no validation errors
59- console . log ( 'onFilesSuccessfulySelected ' , plainFiles , filesContent ) ;
57+ console . log ( 'onFilesSuccessfullySelected ' , plainFiles , filesContent ) ;
6058 } ,
6159 } ) ;
6260
63- if ( errors . length ) {
64- return (
65- < div >
66- < button onClick = { ( ) => openFileSelector ( ) } > Something went wrong, retry! </ button >
67- < div style = { { display : 'flex' , flexDirection : 'column' } } >
68- { console . log ( errors ) }
69- { Object . entries ( errors [ 0 ] )
70- . filter ( ( [ key , value ] ) => key !== 'name' && value )
71- . map ( ( [ key ] ) => (
72- < div key = { key } > { key } </ div >
73- ) ) }
74- </ div >
75- </ div >
76- ) ;
77- }
78-
7961 if ( loading ) {
8062 return < div > Loading...</ div > ;
8163 }
8264
8365 return (
8466 < div >
85- < button onClick = { async ( ) => openFileSelector ( ) } > Select file</ button >
67+ < button onClick = { async ( ) => openFilePicker ( ) } > Select file</ button >
8668 < button onClick = { ( ) => clear ( ) } > Clear</ button >
8769 < br />
8870 Amount of selected files:
8971 { plainFiles . length }
9072 < br />
73+ { errors . length ? (
74+ < div style = { { display : 'flex' , flexDirection : 'column' } } >
75+ < div style = { { marginTop : '10px' } } > Errors:</ div >
76+ { errors . map ( ( error , index ) => (
77+ < div key = { error . name } >
78+ < span > { index + 1 } .</ span >
79+ { Object . entries ( error ) . map ( ( [ key , value ] ) => (
80+ < div key = { key } >
81+ { key } : { typeof value === 'string' ? value : Array . isArray ( value ) ? value . join ( ', ' ) : null }
82+ </ div >
83+ ) ) }
84+ </ div >
85+ ) ) }
86+ </ div >
87+ ) : null }
9188 { /* If readAs is set to DataURL, You can display an image */ }
92- { ! ! filesContent . length && < img src = { filesContent [ 0 ] . content } /> }
89+ { ! ! filesContent . length ? < img src = { filesContent [ 0 ] . content } /> : null }
90+ { ! ! filesContent . length ? < div > { filesContent [ 0 ] . content } </ div > : null }
9391 < br />
9492 { plainFiles . map ( file => (
9593 < div key = { file . name } > { file . name } </ div >
0 commit comments