@mertsolak/react-drop-zone 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
package/.editorconfig ADDED
@@ -0,0 +1,7 @@
1
+ charset = utf-8
2
+ end_of_line = lf
3
+ indent_size = 2
4
+ indent_style = space
5
+ tab_width = 2
6
+ trim_trailing_whitespace = true
7
+ insert_final_newline = true
package/.eslintignore ADDED
@@ -0,0 +1 @@
1
+ /node_modules
package/.eslintrc.js ADDED
@@ -0,0 +1,34 @@
1
+ module.exports = {
2
+ env: {
3
+ browser: true,
4
+ es2021: true,
5
+ },
6
+ extends: ['plugin:react/recommended', 'airbnb'],
7
+ parser: '@typescript-eslint/parser',
8
+ parserOptions: {
9
+ ecmaFeatures: {
10
+ jsx: true,
11
+ },
12
+ ecmaVersion: 12,
13
+ sourceType: 'module',
14
+ },
15
+ plugins: ['react', '@typescript-eslint'],
16
+ rules: {
17
+ 'implicit-arrow-linebreak': 0,
18
+ 'import/extensions': 0,
19
+ 'import/no-extraneous-dependencies': 0,
20
+ 'import/no-unresolved': 0,
21
+ 'import/prefer-default-export': 0,
22
+ 'max-len': [2, { code: 110 }],
23
+ 'no-unused-vars': 0,
24
+ 'no-use-before-define': 0,
25
+ 'object-curly-newline': 0,
26
+ 'operator-linebreak': 0,
27
+ 'react/button-has-type': 0,
28
+ 'react/jsx-filename-extension': [2, { extensions: ['.jsx', '.tsx'] }],
29
+ 'react/prop-types': 0,
30
+ 'jsx-a11y/label-has-associated-control': 0,
31
+ 'no-bitwise': 0,
32
+ 'no-confusing-arrow': 0,
33
+ },
34
+ };
package/.prettierrc ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "tabWidth": 2,
3
+ "useTabs": false,
4
+ "singleQuote": true,
5
+ "trailingComma": "all",
6
+ "printWidth": 110
7
+ }
package/README.md ADDED
@@ -0,0 +1,35 @@
1
+ ## React Drop Zone
2
+
3
+ Package to upload and convert files with drop zone
4
+
5
+ ![npm](https://img.shields.io/npm/v/@mertsolak/react-drop-zone)
6
+ ![license](https://img.shields.io/npm/l/@mertsolak/react-drop-zone)
7
+ ![size](https://img.shields.io/bundlephobia/min/@mertsolak/react-drop-zone)
8
+ ![issue](https://img.shields.io/github/issues/mert-solak/react-drop-zone)
9
+
10
+ ## Installation
11
+
12
+ Use node package manager to install @mertsolak/react-drop-zone.
13
+
14
+ ```bash
15
+ npm i @mertsolak/react-drop-zone
16
+ ```
17
+
18
+ ## Basic Usage
19
+
20
+ ```typescript
21
+ import { DropZone, useDropZone } from '@mertsolak/react-drop-zone';
22
+
23
+ const App = () => {
24
+ // converted files will be available in files array
25
+ // fileInDropZone can be used to style component when any file drag over the drop zone
26
+ // fileList is the original list that comes from event
27
+ // control needs to be given to the component to get updated states
28
+ // 'File' is the default value for the getFilesAs, if it is not provided
29
+ const { files, control, fileList, totalFileSize, fileInDropZone } = useDropZone({ getFilesAs: 'base64' });
30
+
31
+ // default components can be overwritten with buttonComponent
32
+ // and contentComponent or their styles can be updated via classNames
33
+ return <DropZone multiple accept={['.png']} control={control} />;
34
+ };
35
+ ```
@@ -0,0 +1,4 @@
1
+ export interface Props {
2
+ accept?: string[] | undefined;
3
+ multiple?: boolean | undefined;
4
+ }
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { ComponentProps } from '../definitions';
3
+ /**
4
+ * button and content container can be overwritten
5
+ * it can be managed by control object that comes
6
+ * from useDropZone hook
7
+ * @param param @type ComponentProps
8
+ * @returns Rect.ReactNode
9
+ */
10
+ export declare const DropZone: React.FC<ComponentProps>;
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare const DropZone: () => JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { DropZone } from './drop-zone.component';
2
+ export { DropZone };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Configuration object for conversion of Base64
3
+ */
4
+ export declare const base64ToFileConfig: {
5
+ webWorkerBreakpointLength: number;
6
+ };
@@ -0,0 +1,3 @@
1
+ export declare const base64ToFileConfig: {
2
+ webWorkerBreakpointLength: number;
3
+ };
@@ -0,0 +1,2 @@
1
+ import * as conversionConfig from './conversion.config';
2
+ export { conversionConfig };
@@ -0,0 +1,24 @@
1
+ import { conversionDefinitions } from './definitions';
2
+ /**
3
+ * It converts base64 format to File format
4
+ * base64Data has to be in correct format
5
+ * mimeType will overwrite already included
6
+ * in base64Data if provided
7
+ * It uses webWorker if data is bigger
8
+ * then the number specified in config file
9
+ * @param param0 @type Base64Input
10
+ * @returns Promise<File>
11
+ */
12
+ export declare const convertBase64ToFile: ({ base64Data, fileName, mimeType, }: conversionDefinitions.Base64Input) => Promise<File>;
13
+ /**
14
+ * It converts File format to Base64 Format
15
+ * @param file @type File
16
+ * @returns Promise<string>
17
+ */
18
+ export declare const convertFileToBase64: (file: File) => Promise<string>;
19
+ /**
20
+ * It downloads the file in File or Base64 format
21
+ * @param downloadContent @type DownloadContent
22
+ * @returns null
23
+ */
24
+ export declare const download: (downloadContent: conversionDefinitions.DownloadContent) => void;
@@ -0,0 +1,2 @@
1
+ export declare const convertBase64ToFile: (base64URL: string, filename: string) => Promise<File>;
2
+ export declare const convertFileToBase64: (file: File) => Promise<string | ArrayBuffer>;
@@ -0,0 +1,11 @@
1
+ export declare type Base64Input = {
2
+ base64Data: string;
3
+ fileName: string;
4
+ mimeType?: string;
5
+ };
6
+ export declare type Transformation = {
7
+ base64URLParam: string;
8
+ mimeTypeParam?: string;
9
+ };
10
+ export declare type TransformationOutput = [Uint8Array, string];
11
+ export declare type DownloadContent = Base64Input | File;
@@ -0,0 +1,33 @@
1
+ import React, { ChangeEventHandler, DragEvent, DragEventHandler } from 'react';
2
+ export declare type Accept = string[];
3
+ export interface Control {
4
+ onDrop?: (event: DragEvent<HTMLDivElement>, accept: Accept, multiple: boolean) => void | undefined;
5
+ onChange?: ChangeEventHandler<HTMLInputElement> | undefined;
6
+ onDragEnter?: DragEventHandler<HTMLDivElement> | undefined;
7
+ onDragLeave?: DragEventHandler<HTMLDivElement> | undefined;
8
+ fileInDropZone: boolean;
9
+ }
10
+ export interface ButtonComponentProps {
11
+ onClick: () => void;
12
+ }
13
+ export interface ComponentProps extends Omit<Control, 'fileInDropZone'> {
14
+ accept?: Accept | undefined;
15
+ multiple?: boolean | undefined;
16
+ control?: Control | undefined;
17
+ className?: string | undefined;
18
+ buttonClassName?: string | undefined;
19
+ contentClassName?: string | undefined;
20
+ buttonComponent?: React.FunctionComponent<ButtonComponentProps> | undefined;
21
+ contentComponent?: React.FunctionComponent | undefined;
22
+ }
23
+ export declare type GetFilesAs = 'base64' | 'File';
24
+ export interface DropZoneHookProps {
25
+ getFilesAs: GetFilesAs;
26
+ }
27
+ export interface DropZoneHookReturns<T extends DropZoneHookProps> {
28
+ control: Control;
29
+ files: (T['getFilesAs'] extends 'base64' ? string : File)[];
30
+ fileList: FileList;
31
+ totalFileSize: number;
32
+ fileInDropZone: boolean;
33
+ }
@@ -0,0 +1 @@
1
+ export * from './drop-zone.definition';
@@ -0,0 +1,2 @@
1
+ export declare const mergeClassNames: (...classNames: (string | undefined)[]) => string;
2
+ export declare const shouldMergeClassNames: (shouldMerge: boolean, defaultMergeNumber: number, ...classNames: string[]) => string;
@@ -0,0 +1,15 @@
1
+ import { conversionDefinitions } from '../definitions';
2
+ /**
3
+ * it converts base64 url to required format by adding missing parts
4
+ * if base64Data string does not include mimeType,
5
+ * mimeType has to be provided
6
+ * @param param0 @type Omit<Base64Input, 'fileName'>
7
+ * @returns string
8
+ */
9
+ export declare const constructBase64Url: ({ base64Data, mimeType, }: Omit<conversionDefinitions.Base64Input, 'fileName'>) => string;
10
+ /**
11
+ * It checks if base64 data is ObjectURL or not
12
+ * @param base64Data @type string
13
+ * @returns
14
+ */
15
+ export declare const isObjectURL: (base64Data: string) => boolean;
@@ -0,0 +1,3 @@
1
+ import * as variableHelper from './variable.helper';
2
+ import * as attributeHelper from './attribute.helper';
3
+ export { variableHelper, attributeHelper };
@@ -0,0 +1 @@
1
+ export declare const getBas64SizeAsByte: (length: number) => number;
@@ -0,0 +1 @@
1
+ export declare const isDefined: (variable: any) => boolean;
@@ -0,0 +1,2 @@
1
+ import { DragDropHookReturns, DragDropHookProps } from '../definitions';
2
+ export declare const useDragDrop: <T extends DragDropHookProps>({ getFilesAs }?: T) => DragDropHookReturns<T>;
@@ -0,0 +1,9 @@
1
+ import { DropZoneHookReturns, DropZoneHookProps } from '../definitions';
2
+ /**
3
+ * It gives ready to use states if control
4
+ * object is provided to DropZoneComponent
5
+ * as props
6
+ * @param param @type DropZoneHookProps
7
+ * @returns DropZoneHookReturns<DropZoneHookProps>
8
+ */
9
+ export declare const useDropZone: <T extends DropZoneHookProps>({ getFilesAs }?: T) => DropZoneHookReturns<T>;
@@ -0,0 +1,3 @@
1
+ import { useDropZone } from './hooks/use-drop-zone.hook';
2
+ import { DropZone } from './components';
3
+ export { DropZone, useDropZone };
package/dist/index.js ADDED
@@ -0,0 +1,324 @@
1
+ Object.defineProperty(exports, '__esModule', { value: true });
2
+
3
+ var React = require('react');
4
+ var fileHelper = require('@mertsolak/file-helper');
5
+
6
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
7
+
8
+ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
9
+
10
+ /*! *****************************************************************************
11
+ Copyright (c) Microsoft Corporation.
12
+
13
+ Permission to use, copy, modify, and/or distribute this software for any
14
+ purpose with or without fee is hereby granted.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
17
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
19
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
20
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22
+ PERFORMANCE OF THIS SOFTWARE.
23
+ ***************************************************************************** */
24
+
25
+ function __awaiter(thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ }
34
+
35
+ function __generator(thisArg, body) {
36
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
37
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
38
+ function verb(n) { return function (v) { return step([n, v]); }; }
39
+ function step(op) {
40
+ if (f) throw new TypeError("Generator is already executing.");
41
+ while (_) try {
42
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
43
+ if (y = 0, t) op = [op[0] & 2, t.value];
44
+ switch (op[0]) {
45
+ case 0: case 1: t = op; break;
46
+ case 4: _.label++; return { value: op[1], done: false };
47
+ case 5: _.label++; y = op[1]; op = [0]; continue;
48
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
49
+ default:
50
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
51
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
52
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
53
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
54
+ if (t[2]) _.ops.pop();
55
+ _.trys.pop(); continue;
56
+ }
57
+ op = body.call(thisArg, _);
58
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
59
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
60
+ }
61
+ }
62
+
63
+ /**
64
+ * It gives ready to use states if control
65
+ * object is provided to DropZoneComponent
66
+ * as props
67
+ * @param param @type DropZoneHookProps
68
+ * @returns DropZoneHookReturns<DropZoneHookProps>
69
+ */
70
+ var useDropZone = function (_a) {
71
+ var _b = _a === void 0 ? { getFilesAs: 'File' } : _a, getFilesAs = _b.getFilesAs;
72
+ var _c = React.useState(false), fileInDropZone = _c[0], setFileInDropZone = _c[1];
73
+ var _d = React.useState(), totalFileSize = _d[0], setTotalFileSize = _d[1];
74
+ var _e = React.useState(), fileList = _e[0], setFileList = _e[1];
75
+ var _f = React.useState(), files = _f[0], setFiles = _f[1];
76
+ /** It sets file related states and converts files if needed
77
+ * @param eventFileList @type FileList
78
+ */
79
+ var processFiles = React.useCallback(function (eventFileList) { return __awaiter(void 0, void 0, void 0, function () {
80
+ var convertedFiles, conversionPromises, eventFiles, eventTotalFileSize, conversionResults;
81
+ return __generator(this, function (_a) {
82
+ switch (_a.label) {
83
+ case 0:
84
+ convertedFiles = [];
85
+ conversionPromises = [];
86
+ eventFiles = [];
87
+ eventTotalFileSize = 0;
88
+ Object.keys(eventFileList).forEach(function (eachFileKey) {
89
+ var file = eventFileList[eachFileKey];
90
+ eventFiles.push(file);
91
+ eventTotalFileSize += file.size;
92
+ if (getFilesAs === 'base64') {
93
+ conversionPromises.push(fileHelper.convertFileToBase64(file));
94
+ }
95
+ });
96
+ return [4 /*yield*/, Promise.all(conversionPromises)];
97
+ case 1:
98
+ conversionResults = _a.sent();
99
+ eventFiles.forEach(function (file, index) {
100
+ var _a;
101
+ var convertedFile = (_a = conversionResults[index]) !== null && _a !== void 0 ? _a : file;
102
+ convertedFiles.push(convertedFile);
103
+ });
104
+ setTotalFileSize(eventTotalFileSize);
105
+ setFileList(eventFileList);
106
+ setFiles(convertedFiles);
107
+ return [2 /*return*/];
108
+ }
109
+ });
110
+ }); }, [getFilesAs]);
111
+ /**
112
+ * It filters files by looking at accept and multiple
113
+ * and calls processFiles with filtered files
114
+ * @param event @type DragEvent<HtMLDivElement>
115
+ * @param accept @type string[]
116
+ * @param multiple @type boolean
117
+ */
118
+ var handleOnDrop = React.useCallback(function (event, accept, multiple) {
119
+ setFileInDropZone(false);
120
+ var eventFiles = event.dataTransfer.files;
121
+ var newDataTransfer = new DataTransfer();
122
+ Object.values(eventFiles).some(function (file) {
123
+ if (accept.includes("." + file.name.split('.').pop().toLowerCase())) {
124
+ newDataTransfer.items.add(file);
125
+ if (!multiple) {
126
+ return true;
127
+ }
128
+ }
129
+ return false;
130
+ });
131
+ processFiles(newDataTransfer.files);
132
+ }, [processFiles]);
133
+ /**
134
+ * it calls processFiles with files that comes from event
135
+ * @param event @type DragEvent<HtMLDivElement>
136
+ */
137
+ var handleOnChange = React.useCallback(function (event) {
138
+ processFiles(event.currentTarget.files);
139
+ }, [processFiles]);
140
+ /**
141
+ * it sets fileInDropZone state true to notify there is a file
142
+ * inside of the drop zone borders
143
+ */
144
+ var handleOnDragEnter = React.useCallback(function () {
145
+ setFileInDropZone(true);
146
+ }, []);
147
+ /**
148
+ * it sets fileInDropZone state false to notify there is no file
149
+ * inside of the drop zone borders
150
+ */
151
+ var handleOnDragLeave = React.useCallback(function () {
152
+ setFileInDropZone(false);
153
+ }, []);
154
+ /**
155
+ * control object that controls dropZoneComponent to process
156
+ * inputs for the ready to use outputs
157
+ */
158
+ var control = React.useMemo(function () { return ({
159
+ onDrop: handleOnDrop,
160
+ onChange: handleOnChange,
161
+ onDragEnter: handleOnDragEnter,
162
+ onDragLeave: handleOnDragLeave,
163
+ fileInDropZone: fileInDropZone,
164
+ }); }, [handleOnDrop, handleOnChange, handleOnDragEnter, handleOnDragLeave, fileInDropZone]);
165
+ return { control: control, files: files, fileList: fileList, totalFileSize: totalFileSize, fileInDropZone: fileInDropZone };
166
+ };
167
+
168
+ var isDefined = function (variable) { return variable !== undefined && variable !== null; };
169
+
170
+ var mergeClassNames = function () {
171
+ var classNames = [];
172
+ for (var _i = 0; _i < arguments.length; _i++) {
173
+ classNames[_i] = arguments[_i];
174
+ }
175
+ return classNames.join(' ');
176
+ };
177
+ var shouldMergeClassNames = function (shouldMerge, defaultMergeNumber) {
178
+ var classNames = [];
179
+ for (var _i = 2; _i < arguments.length; _i++) {
180
+ classNames[_i - 2] = arguments[_i];
181
+ }
182
+ return shouldMerge
183
+ ? classNames.join(' ')
184
+ : classNames.filter(function () {
185
+ var params = [];
186
+ for (var _i = 0; _i < arguments.length; _i++) {
187
+ params[_i] = arguments[_i];
188
+ }
189
+ return params[1] <= defaultMergeNumber - 1;
190
+ }).join(' ');
191
+ };
192
+
193
+ function styleInject(css, ref) {
194
+ if ( ref === void 0 ) ref = {};
195
+ var insertAt = ref.insertAt;
196
+
197
+ if (!css || typeof document === 'undefined') { return; }
198
+
199
+ var head = document.head || document.getElementsByTagName('head')[0];
200
+ var style = document.createElement('style');
201
+ style.type = 'text/css';
202
+
203
+ if (insertAt === 'top') {
204
+ if (head.firstChild) {
205
+ head.insertBefore(style, head.firstChild);
206
+ } else {
207
+ head.appendChild(style);
208
+ }
209
+ } else {
210
+ head.appendChild(style);
211
+ }
212
+
213
+ if (style.styleSheet) {
214
+ style.styleSheet.cssText = css;
215
+ } else {
216
+ style.appendChild(document.createTextNode(css));
217
+ }
218
+ }
219
+
220
+ var css_248z = ".drop-zone-module_container__24aKE {\n width: fit-content;\n position: relative;\n}\n\n.drop-zone-module_input__2Pzq_ {\n display: none;\n}\n\n.drop-zone-module_button__2a7EM {\n position: absolute;\n margin: auto;\n width: 140px;\n bottom: 25px;\n left: 0;\n right: 0;\n text-align: center;\n cursor: pointer;\n padding: 10px 4px;\n}\n\n.drop-zone-module_contentContainer__2wXPQ {\n padding: 20px;\n width: 300px;\n height: 100px;\n display: flex;\n flex-direction: column;\n align-items: center;\n color: #4a4a4a;\n border: 1px dashed #c8c8c8;\n background-color: #ebebeb;\n}\n.drop-zone-module_contentContainer__2wXPQ * {\n pointer-events: none;\n}\n\n.drop-zone-module_fileInDropZone__3GBPO {\n background-color: white;\n}\n\n.drop-zone-module_text__1fmAO {\n margin: 0px 0px 6px 0px;\n}";
221
+ var styles = {"container":"drop-zone-module_container__24aKE","input":"drop-zone-module_input__2Pzq_","button":"drop-zone-module_button__2a7EM","contentContainer":"drop-zone-module_contentContainer__2wXPQ","fileInDropZone":"drop-zone-module_fileInDropZone__3GBPO","text":"drop-zone-module_text__1fmAO"};
222
+ styleInject(css_248z);
223
+
224
+ /**
225
+ * button and content container can be overwritten
226
+ * it can be managed by control object that comes
227
+ * from useDropZone hook
228
+ * @param param @type ComponentProps
229
+ * @returns Rect.ReactNode
230
+ */
231
+ var DropZone = function (_a) {
232
+ var className = _a.className, buttonClassName = _a.buttonClassName, contentClassName = _a.contentClassName, ButtonComponentParam = _a.buttonComponent, ContentComponentParam = _a.contentComponent, accept = _a.accept, multiple = _a.multiple, control = _a.control, onDrop = _a.onDrop, onChange = _a.onChange, onDragEnter = _a.onDragEnter, onDragLeave = _a.onDragLeave;
233
+ var inputRef = React.useRef();
234
+ /**
235
+ * It redirects event, accept and multiple to onDrop
236
+ * and control.onDrop if they are given and prevents
237
+ * default to make drop zone working
238
+ * @param event @type DragEvent<HTMLDivElement>
239
+ */
240
+ var handleOnDrop = React.useCallback(function (event) {
241
+ event.preventDefault();
242
+ if (isDefined(onDrop)) {
243
+ onDrop(event, accept, multiple);
244
+ }
245
+ if (isDefined(control === null || control === void 0 ? void 0 : control.onDrop)) {
246
+ control === null || control === void 0 ? void 0 : control.onDrop(event, accept, multiple);
247
+ }
248
+ }, [onDrop, control === null || control === void 0 ? void 0 : control.onDrop, accept, multiple]);
249
+ /**
250
+ * It prevents default to make drop zone working
251
+ * @param event: DragEvent<HTMLDivElement>
252
+ */
253
+ var handleOnDragOver = React.useCallback(function (event) {
254
+ event.preventDefault();
255
+ }, []);
256
+ /**
257
+ * It redirects event to onDragEnter and control.onDragEnter if they are given
258
+ * @param event @type DragEvent<HTMLDivElement>
259
+ */
260
+ var handleOnDragEnter = React.useCallback(function (event) {
261
+ if (isDefined(onDragEnter)) {
262
+ onDragEnter(event);
263
+ }
264
+ if (isDefined(control === null || control === void 0 ? void 0 : control.onDragEnter)) {
265
+ control === null || control === void 0 ? void 0 : control.onDragEnter(event);
266
+ }
267
+ }, [onDragEnter, control === null || control === void 0 ? void 0 : control.onDragEnter]);
268
+ /**
269
+ * It redirects event to onDragLeave and control.onDragLeave if they are given
270
+ * @param event @type DragEvent<HTMLDivElement>
271
+ */
272
+ var handleOnDragLeave = React.useCallback(function (event) {
273
+ if (isDefined(onDragLeave)) {
274
+ onDragLeave(event);
275
+ }
276
+ if (isDefined(control === null || control === void 0 ? void 0 : control.onDragLeave)) {
277
+ control === null || control === void 0 ? void 0 : control.onDragLeave(event);
278
+ }
279
+ }, [onDragLeave, control === null || control === void 0 ? void 0 : control.onDragLeave]);
280
+ /**
281
+ * It redirects event to onChange and control.onChange if they are given
282
+ * @param event @type ChangeEvent<HTMLInputElement>
283
+ */
284
+ var handleOnChangeInput = React.useCallback(function (event) {
285
+ if (isDefined(onDrop)) {
286
+ onChange(event);
287
+ }
288
+ if (isDefined(control === null || control === void 0 ? void 0 : control.onChange)) {
289
+ control === null || control === void 0 ? void 0 : control.onChange(event);
290
+ }
291
+ }, [onChange, control === null || control === void 0 ? void 0 : control.onChange]);
292
+ /**
293
+ * It triggers input's click event to upload
294
+ */
295
+ var handleOnClickButton = React.useCallback(function () {
296
+ inputRef.current.click();
297
+ }, [inputRef.current]);
298
+ /**
299
+ * It decides for the button component and
300
+ * assigns onClick method to it
301
+ * @returns React.ReactNode
302
+ */
303
+ var ButtonComponent = React.useCallback(function () {
304
+ return isDefined(ButtonComponentParam) ? (React__default['default'].createElement(ButtonComponentParam, { onClick: handleOnClickButton })) : (React__default['default'].createElement("button", { className: mergeClassNames(styles.button, buttonClassName), onClick: handleOnClickButton }, "Click to Upload"));
305
+ }, [ButtonComponentParam, buttonClassName, handleOnClickButton]);
306
+ /**
307
+ * It decides for the content component ang manage
308
+ * styling by looking at fileInDropZone prop
309
+ * @returns React.ReactNode
310
+ */
311
+ var ContentComponent = React.useCallback(function () {
312
+ return ContentComponentParam ? (React__default['default'].createElement(ContentComponentParam, null)) : (React__default['default'].createElement("div", { className: shouldMergeClassNames(control === null || control === void 0 ? void 0 : control.fileInDropZone, 2, styles.contentContainer, contentClassName, styles.fileInDropZone) },
313
+ React__default['default'].createElement("p", { className: styles.text }, "Drop files here"),
314
+ React__default['default'].createElement("p", { className: styles.text }, "or")));
315
+ }, [ContentComponentParam, contentClassName, control === null || control === void 0 ? void 0 : control.fileInDropZone]);
316
+ return (React__default['default'].createElement("div", { className: mergeClassNames(styles.container, className), onDragOver: handleOnDragOver, onDrop: handleOnDrop, onDragEnter: handleOnDragEnter, onDragLeave: handleOnDragLeave },
317
+ React__default['default'].createElement("input", { className: styles.input, ref: inputRef, multiple: multiple, accept: accept === null || accept === void 0 ? void 0 : accept.join(','), type: "file", onChange: handleOnChangeInput }),
318
+ React__default['default'].createElement(ButtonComponent, null),
319
+ React__default['default'].createElement(ContentComponent, null)));
320
+ };
321
+
322
+ exports.DropZone = DropZone;
323
+ exports.useDropZone = useDropZone;
324
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/hooks/use-drop-zone.hook.ts","../src/helpers/variable.helper.ts","../src/helpers/attribute.helper.ts","../node_modules/style-inject/dist/style-inject.es.js","../src/components/drop-zone.component.tsx"],"sourcesContent":["import { useCallback, useMemo, useState } from 'react';\nimport { convertFileToBase64 } from '@mertsolak/file-helper';\n\nimport { DropZoneHookReturns, DropZoneHookProps, Control } from '../definitions';\n\n/**\n * It gives ready to use states if control\n * object is provided to DropZoneComponent\n * as props\n * @param param @type DropZoneHookProps\n * @returns DropZoneHookReturns<DropZoneHookProps>\n */\nexport const useDropZone = <T extends DropZoneHookProps>(\n { getFilesAs }: T = { getFilesAs: 'File' } as T,\n): DropZoneHookReturns<T> => {\n const [fileInDropZone, setFileInDropZone] = useState<DropZoneHookReturns<T>['fileInDropZone']>(false);\n const [totalFileSize, setTotalFileSize] = useState<DropZoneHookReturns<T>['totalFileSize']>();\n const [fileList, setFileList] = useState<DropZoneHookReturns<T>['fileList']>();\n const [files, setFiles] = useState<DropZoneHookReturns<T>['files']>();\n\n /** It sets file related states and converts files if needed\n * @param eventFileList @type FileList\n */\n const processFiles = useCallback(\n async (eventFileList: FileList) => {\n const convertedFiles: DropZoneHookReturns<T>['files'] = [];\n const conversionPromises: Promise<any>[] = [];\n const eventFiles: File[] = [];\n let eventTotalFileSize = 0;\n\n Object.keys(eventFileList).forEach((eachFileKey) => {\n const file = eventFileList[eachFileKey] as File;\n eventFiles.push(file);\n eventTotalFileSize += file.size;\n\n if (getFilesAs === 'base64') {\n conversionPromises.push(convertFileToBase64(file));\n }\n });\n\n const conversionResults = await Promise.all(conversionPromises);\n\n eventFiles.forEach((file, index) => {\n const convertedFile = conversionResults[index] ?? file;\n convertedFiles.push(convertedFile);\n });\n\n setTotalFileSize(eventTotalFileSize);\n setFileList(eventFileList);\n setFiles(convertedFiles);\n },\n [getFilesAs],\n );\n\n /**\n * It filters files by looking at accept and multiple\n * and calls processFiles with filtered files\n * @param event @type DragEvent<HtMLDivElement>\n * @param accept @type string[]\n * @param multiple @type boolean\n */\n const handleOnDrop = useCallback<Control['onDrop']>(\n (event, accept, multiple) => {\n setFileInDropZone(false);\n\n const eventFiles = event.dataTransfer.files;\n const newDataTransfer = new DataTransfer();\n\n Object.values(eventFiles).some((file) => {\n if (accept.includes(`.${file.name.split('.').pop().toLowerCase()}`)) {\n newDataTransfer.items.add(file);\n if (!multiple) {\n return true;\n }\n }\n\n return false;\n });\n\n processFiles(newDataTransfer.files);\n },\n [processFiles],\n );\n\n /**\n * it calls processFiles with files that comes from event\n * @param event @type DragEvent<HtMLDivElement>\n */\n const handleOnChange = useCallback<Control['onChange']>(\n (event) => {\n processFiles(event.currentTarget.files);\n },\n [processFiles],\n );\n\n /**\n * it sets fileInDropZone state true to notify there is a file\n * inside of the drop zone borders\n */\n const handleOnDragEnter = useCallback<Control['onDragEnter']>(() => {\n setFileInDropZone(true);\n }, []);\n\n /**\n * it sets fileInDropZone state false to notify there is no file\n * inside of the drop zone borders\n */\n const handleOnDragLeave = useCallback<Control['onDragLeave']>(() => {\n setFileInDropZone(false);\n }, []);\n\n /**\n * control object that controls dropZoneComponent to process\n * inputs for the ready to use outputs\n */\n const control: DropZoneHookReturns<T>['control'] = useMemo(\n () => ({\n onDrop: handleOnDrop,\n onChange: handleOnChange,\n onDragEnter: handleOnDragEnter,\n onDragLeave: handleOnDragLeave,\n fileInDropZone,\n }),\n [handleOnDrop, handleOnChange, handleOnDragEnter, handleOnDragLeave, fileInDropZone],\n );\n\n return { control, files, fileList, totalFileSize, fileInDropZone };\n};\n","export const isDefined = (variable: any) => variable !== undefined && variable !== null;\n","export const mergeClassNames = (...classNames: (string | undefined)[]): string => classNames.join(' ');\n\nexport const shouldMergeClassNames = (\n shouldMerge: boolean,\n defaultMergeNumber: number,\n ...classNames: string[]\n) =>\n shouldMerge\n ? classNames.join(' ')\n : classNames.filter((...params) => params[1] <= defaultMergeNumber - 1).join(' ');\n","function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n","import React, { ChangeEventHandler, DragEventHandler, useCallback, useRef } from 'react';\n\nimport { variableHelper, attributeHelper } from '../helpers';\nimport { ComponentProps } from '../definitions';\n\nimport styles from './drop-zone.module.scss';\n\n/**\n * button and content container can be overwritten\n * it can be managed by control object that comes\n * from useDropZone hook\n * @param param @type ComponentProps\n * @returns Rect.ReactNode\n */\nexport const DropZone: React.FC<ComponentProps> = ({\n className,\n buttonClassName,\n contentClassName,\n buttonComponent: ButtonComponentParam,\n contentComponent: ContentComponentParam,\n accept,\n multiple,\n control,\n onDrop,\n onChange,\n onDragEnter,\n onDragLeave,\n}) => {\n const inputRef = useRef<HTMLInputElement>();\n\n /**\n * It redirects event, accept and multiple to onDrop\n * and control.onDrop if they are given and prevents\n * default to make drop zone working\n * @param event @type DragEvent<HTMLDivElement>\n */\n const handleOnDrop: DragEventHandler<HTMLDivElement> = useCallback(\n (event) => {\n event.preventDefault();\n\n if (variableHelper.isDefined(onDrop)) {\n onDrop(event, accept, multiple);\n }\n\n if (variableHelper.isDefined(control?.onDrop)) {\n control?.onDrop(event, accept, multiple);\n }\n },\n [onDrop, control?.onDrop, accept, multiple],\n );\n\n /**\n * It prevents default to make drop zone working\n * @param event: DragEvent<HTMLDivElement>\n */\n const handleOnDragOver: DragEventHandler<HTMLDivElement> = useCallback((event) => {\n event.preventDefault();\n }, []);\n\n /**\n * It redirects event to onDragEnter and control.onDragEnter if they are given\n * @param event @type DragEvent<HTMLDivElement>\n */\n const handleOnDragEnter: DragEventHandler<HTMLDivElement> = useCallback(\n (event) => {\n if (variableHelper.isDefined(onDragEnter)) {\n onDragEnter(event);\n }\n\n if (variableHelper.isDefined(control?.onDragEnter)) {\n control?.onDragEnter(event);\n }\n },\n [onDragEnter, control?.onDragEnter],\n );\n\n /**\n * It redirects event to onDragLeave and control.onDragLeave if they are given\n * @param event @type DragEvent<HTMLDivElement>\n */\n const handleOnDragLeave: DragEventHandler<HTMLDivElement> = useCallback(\n (event) => {\n if (variableHelper.isDefined(onDragLeave)) {\n onDragLeave(event);\n }\n\n if (variableHelper.isDefined(control?.onDragLeave)) {\n control?.onDragLeave(event);\n }\n },\n [onDragLeave, control?.onDragLeave],\n );\n\n /**\n * It redirects event to onChange and control.onChange if they are given\n * @param event @type ChangeEvent<HTMLInputElement>\n */\n const handleOnChangeInput: ChangeEventHandler<HTMLInputElement> = useCallback(\n (event) => {\n if (variableHelper.isDefined(onDrop)) {\n onChange(event);\n }\n\n if (variableHelper.isDefined(control?.onChange)) {\n control?.onChange(event);\n }\n },\n [onChange, control?.onChange],\n );\n\n /**\n * It triggers input's click event to upload\n */\n const handleOnClickButton = useCallback(() => {\n inputRef.current.click();\n }, [inputRef.current]);\n\n /**\n * It decides for the button component and\n * assigns onClick method to it\n * @returns React.ReactNode\n */\n const ButtonComponent = useCallback(\n () =>\n variableHelper.isDefined(ButtonComponentParam) ? (\n <ButtonComponentParam onClick={handleOnClickButton} />\n ) : (\n <button\n className={attributeHelper.mergeClassNames(styles.button, buttonClassName)}\n onClick={handleOnClickButton}\n >\n Click to Upload\n </button>\n ),\n [ButtonComponentParam, buttonClassName, handleOnClickButton],\n );\n\n /**\n * It decides for the content component ang manage\n * styling by looking at fileInDropZone prop\n * @returns React.ReactNode\n */\n const ContentComponent = useCallback(\n () =>\n ContentComponentParam ? (\n <ContentComponentParam />\n ) : (\n <div\n className={attributeHelper.shouldMergeClassNames(\n control?.fileInDropZone,\n 2,\n styles.contentContainer,\n contentClassName,\n styles.fileInDropZone,\n )}\n >\n <p className={styles.text}>Drop files here</p>\n <p className={styles.text}>or</p>\n </div>\n ),\n [ContentComponentParam, contentClassName, control?.fileInDropZone],\n );\n\n return (\n <div\n className={attributeHelper.mergeClassNames(styles.container, className)}\n onDragOver={handleOnDragOver}\n onDrop={handleOnDrop}\n onDragEnter={handleOnDragEnter}\n onDragLeave={handleOnDragLeave}\n >\n <input\n className={styles.input}\n ref={inputRef}\n multiple={multiple}\n accept={accept?.join(',')}\n type=\"file\"\n onChange={handleOnChangeInput}\n />\n <ButtonComponent />\n <ContentComponent />\n </div>\n );\n};\n"],"names":["useState","useCallback","convertFileToBase64","useMemo","useRef","variableHelper.isDefined","React","attributeHelper.mergeClassNames","attributeHelper.shouldMergeClassNames"],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { Operator, PermissionObject } from './types';
2
+ export declare class Permissions<T extends string> {
3
+ private permissionObject;
4
+ private permissionNumber;
5
+ /** It gets permission names and
6
+ * initial permission number in base 16 as optional
7
+ * @param permissionNames @type string(name)[]
8
+ * @param initialPermissionNumber @type string(hex number)
9
+ */
10
+ constructor(permissionNames: T[], initialPermissionNumber?: string);
11
+ /**
12
+ * It creates permission object&enum
13
+ * @param permissionNames @type string(name)[]
14
+ */
15
+ private createPermissionObject;
16
+ /**
17
+ * It gets expected permission names and operator for verification
18
+ * @param expectedPermissions @type string(name)[]
19
+ * @param operator @type string = '|' default
20
+ * @returns boolean
21
+ */
22
+ verifyPermissions: (expectedPermissions: T[], operator?: Operator) => boolean;
23
+ /**
24
+ * It gets permission names to add
25
+ * @param newPermissions @type string(name)[]
26
+ */
27
+ addPermissions: (newPermissions: T[]) => void;
28
+ /**
29
+ * It gets permission names to remove
30
+ * @param removedPermissions @type string(name)[]
31
+ */
32
+ removePermissions: (removedPermissions: T[]) => void;
33
+ /**
34
+ * It returns permission object
35
+ * @returns Record<string(name), string>
36
+ */
37
+ getPermissionObject: () => PermissionObject<T>;
38
+ /**
39
+ * It returns permission number
40
+ * @returns string
41
+ */
42
+ getPermissionNumber: () => string;
43
+ }
@@ -0,0 +1,35 @@
1
+ import { Operator, PermissionObject } from './types';
2
+ /**
3
+ * creates permissionNames array with string literal type
4
+ * @param permissions @type T[]
5
+ * @returns T[]
6
+ */
7
+ export declare const createPermissionNames: <T extends string>(...permissions: T[]) => T[];
8
+ /**
9
+ * It creates permission object&enum
10
+ * @param permissionNames @type string(name)[]
11
+ */
12
+ export declare const createPermissionObject: <T extends string>(permissionNames: T[]) => PermissionObject<T>;
13
+ /**
14
+ * It gets expected permission names, permission number, permission object and operator for verification
15
+ * @param permissionNumber @type string
16
+ * @param permissionObject @type PermissionObject<T>
17
+ * @param expectedPermissions @type string(name)[]
18
+ * @param operator @type string = '|' default
19
+ * @returns boolean
20
+ */
21
+ export declare const verifyPermissions: <T extends string>(permissionNumber: string, permissionObject: PermissionObject<T>, expectedPermissions: T[], operator?: Operator) => boolean;
22
+ /**
23
+ * It gets permission number, permission object and permission names to add permissions
24
+ * @param permissionNumber @type string
25
+ * @param permissionObject @type PermissionObject<T>
26
+ * @param newPermissions @type string(name)[]
27
+ */
28
+ export declare const addPermissions: <T extends string>(permissionNumber: string, permissionObject: PermissionObject<T>, newPermissions: T[]) => string;
29
+ /**
30
+ * It gets permission number, permission object and permission names to remove permissions
31
+ * @param permissionNumber @type string
32
+ * @param permissionObject @type PermissionObject<T>
33
+ * @param removedPermissions @type string(name)[]
34
+ */
35
+ export declare const removePermissions: <T extends string>(permissionNumber: string, permissionObject: PermissionObject<T>, removedPermissions: T[]) => string;
@@ -0,0 +1,2 @@
1
+ export declare type Operator = '&' | '|';
2
+ export declare type PermissionObject<T extends string> = Record<T, string>;
@@ -0,0 +1 @@
1
+ export declare const createWebWorker: <T extends unknown, K extends unknown>(inputData: T, processCallback: (data: T) => K, resultCallback: (data: K) => void) => Worker | null;
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@mertsolak/react-drop-zone",
3
+ "version": "1.0.0",
4
+ "main": "dist/index.js",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "url": "https://github.com/mert-solak/react-drop-zone.git"
8
+ },
9
+ "scripts": {
10
+ "build": "rollup -c",
11
+ "commit": "git-cz",
12
+ "release": "standard-version",
13
+ "lint": "eslint \"{src/**/*.ts, src/**/*.tsx}\""
14
+ },
15
+ "dependencies": {
16
+ "@mertsolak/file-helper": "^1.0.0"
17
+ },
18
+ "devDependencies": {
19
+ "@types/react": "^17.0.36",
20
+ "@typescript-eslint/eslint-plugin": "^4.11.1",
21
+ "@typescript-eslint/parser": "^4.11.1",
22
+ "commitizen": "^4.2.2",
23
+ "cz-conventional-changelog": "^3.3.0",
24
+ "eslint": "^7.17.0",
25
+ "eslint-config-airbnb": "^18.2.1",
26
+ "eslint-plugin-import": "^2.22.1",
27
+ "eslint-plugin-jsx-a11y": "^6.4.1",
28
+ "eslint-plugin-react": "^7.22.0",
29
+ "eslint-plugin-react-hooks": "^4.2.0",
30
+ "ghooks": "^2.0.4",
31
+ "rollup": "^2.36.1",
32
+ "sass": "1.32.0",
33
+ "sass-loader": "10.1.0",
34
+ "style-loader": "2.0.0",
35
+ "css-loader": "5.0.1",
36
+ "rollup-plugin-postcss": "4.0.0",
37
+ "rollup-plugin-peer-deps-external": "^2.2.4",
38
+ "rollup-plugin-typescript2": "^0.29.0",
39
+ "standard-version": "^9.3.0",
40
+ "ts-loader": "^8.0.13",
41
+ "typescript": "^4.1.3"
42
+ },
43
+ "peerDependencies": {
44
+ "react": "^17.0.2",
45
+ "react-dom": "^17.0.2"
46
+ },
47
+ "config": {
48
+ "ghooks": {
49
+ "pre-commit": "npm run lint -s"
50
+ },
51
+ "commitizen": {
52
+ "path": "cz-conventional-changelog"
53
+ }
54
+ }
55
+ }