@mertsolak/react-drop-zone 1.0.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/.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
+ }