/
index.js
124 lines (108 loc) · 3.06 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import React, { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import { useDropzone } from 'react-dropzone';
import Box from 'react/components/UI/Box';
import Text from 'react/components/UI/Text';
import Link from 'react/components/UI/Link';
import FileUploader from 'react/components/UI/FileUploader';
import FileUploaderProgressList from 'react/components/UI/FileUploaderProgressList';
const DropZone = styled(Box)`
${props => `display: ${{ resting: 'none', active: 'block' }[props.mode]};`}
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 2;
`;
const Backdrop = styled(Box).attrs({
bg: 'utility.translucent',
})`
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 3;
`;
const DropZoneUploader = ({
children,
onUpload,
onComplete,
}) => {
const [mode, setMode] = useState('resting');
const handleDrop = useCallback((acceptedFiles) => {
if (acceptedFiles.length > 0) setMode('active');
}, []);
const handleErrors = (err) => {
console.error(err);
setMode('error');
};
const {
getRootProps,
getInputProps,
isDragActive,
open: openUploadDialog,
acceptedFiles,
} = useDropzone({
onDrop: handleDrop,
onDragLeave: () => setMode('resting'),
noClick: true,
noKeyboard: true,
});
// Use `dragenter` event on `window` to trigger the actual drop-zone,
// instead of the Component's element.
const showDropZone = () => setMode('active');
useEffect(() => {
window.addEventListener('dragenter', showDropZone);
return () => window.removeEventListener('dragenter', showDropZone);
});
return (
<React.Fragment>
<DropZone {...getRootProps()} mode={mode}>
<input {...getInputProps()} />
<Backdrop>
{isDragActive &&
<Text f={9} color="gray.base" textAlign="center">
Drop files to add
</Text>
}
{mode === 'error' &&
<Text mb={6} f={8} color="state.alert" textAlign="center" underlineLinks>
There was a problem uploading your files.{' '}
<Link onClick={onComplete}>
Close
</Link>
</Text>
}
{acceptedFiles.length > 0 && mode !== 'error' &&
<FileUploader
files={acceptedFiles}
onUpload={onUpload}
onComplete={onComplete}
onError={handleErrors}
>
{({ files }) => (
<FileUploaderProgressList p={6} files={files} />
)}
</FileUploader>
}
</Backdrop>
</DropZone>
{children({ isDragActive, openUploadDialog })}
</React.Fragment>
);
};
DropZoneUploader.propTypes = {
children: PropTypes.func.isRequired,
onUpload: PropTypes.func.isRequired,
onComplete: PropTypes.func.isRequired,
};
DropZoneUploader.defaultProps = {
};
export default DropZoneUploader;