react-drag-drop-files
Version:
Light React Drag & Drop files and images library styled by styled-components
146 lines • 6.73 kB
JavaScript
import { __assign } from "tslib";
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { Description, DescriptionWrapper, HoverMsg, UploaderWrapper } from './style';
import { acceptedExt, checkType, getFileSizeMB } from './utils';
import { useEffect, useRef, useState } from 'react';
import DrawTypes from './DrawTypes';
import ImageAdd from './ImageAdd';
import useDragging from './useDragging';
/**
*
* Draw a description on the frame
* @param currFile - The uploaded file
* @param uploaded - boolean to check if the file uploaded or not yet
* @param typeError - boolean to check if the file has type errors
* @param disabled - boolean to check if input is disabled
* @param label - string to add custom label
* @param uploadedLabel - string to add custom label when a file was uploaded
* @returns JSX Element
*
* @internal
*
*/
var drawDescription = function (currFile, uploaded, typeError, disabled, label, uploadedLabel) {
return typeError ? (_jsx("span", { children: "File type/size error, Hovered on types!" })) : (_jsx(Description, { children: disabled ? (_jsx("span", { children: "Upload disabled" })) : !currFile && !uploaded ? (_jsx(_Fragment, { children: label ? (_jsxs(_Fragment, { children: [_jsx("span", { children: label.split(' ')[0] }), ' ', label.substr(label.indexOf(' ') + 1)] })) : (_jsxs(_Fragment, { children: [_jsx("span", { children: "Upload" }), " or drop a file right here"] })) })) : (_jsx(_Fragment, { children: uploadedLabel ? (_jsx(_Fragment, { children: _jsx("span", { children: uploadedLabel }) })) : (_jsxs(_Fragment, { children: [_jsx("span", { children: "Uploaded Successfully!" }), " Upload another?"] })) })) }));
};
/**
* File uploading main function
* @param props - {name,
hoverTitle,
types,
handleChange,
classes,
children,
maxSize,
minSize,
fileOrFiles,
onSizeError,
onTypeError,
onSelect,
onDrop,
onTypeError,
disabled,
label,
multiple,
required,
onDraggingStateChange
}
* @returns JSX Element
*/
var FileUploader = function (props) {
var name = props.name, hoverTitle = props.hoverTitle, types = props.types, handleChange = props.handleChange, classes = props.classes, children = props.children, maxSize = props.maxSize, minSize = props.minSize, fileOrFiles = props.fileOrFiles, onSizeError = props.onSizeError, onTypeError = props.onTypeError, onSelect = props.onSelect, onDrop = props.onDrop, disabled = props.disabled, label = props.label, uploadedLabel = props.uploadedLabel, multiple = props.multiple, required = props.required, onDraggingStateChange = props.onDraggingStateChange, dropMessageStyle = props.dropMessageStyle, ariaLabel = props.ariaLabel, ariaDescribedby = props.ariaDescribedby;
var labelRef = useRef(null);
var inputRef = useRef(null);
var _a = useState(false), uploaded = _a[0], setUploaded = _a[1];
var _b = useState(null), currFiles = _b[0], setFile = _b[1];
var _c = useState(false), error = _c[0], setError = _c[1];
var validateFile = function (file) {
if (types && !checkType(file, types)) {
// types included and type not in them
setError(true);
if (onTypeError)
onTypeError('File type is not supported');
return false;
}
if (maxSize && getFileSizeMB(file.size) > maxSize) {
setError(true);
if (onSizeError)
onSizeError('File size is too big');
return false;
}
if (minSize && getFileSizeMB(file.size) < minSize) {
setError(true);
if (onSizeError)
onSizeError('File size is too small');
return false;
}
return true;
};
var handleChanges = function (files) {
var checkError = false;
if (files) {
if (files instanceof File) {
checkError = !validateFile(files);
}
else {
for (var i = 0; i < files.length; i++) {
var file = files[i];
checkError = !validateFile(file) || checkError;
}
}
if (checkError)
return false;
if (handleChange)
handleChange(files);
setFile(files);
setUploaded(true);
setError(false);
return true;
}
return false;
};
var blockEvent = function (ev) {
ev.preventDefault();
ev.stopPropagation();
};
var handleClick = function (ev) {
ev.stopPropagation();
// eslint-disable-next-line no-param-reassign
if (inputRef && inputRef.current) {
inputRef.current.value = '';
inputRef.current.click();
}
};
var handleInputChange = function (ev) {
var allFiles = ev.target.files;
var files = multiple ? allFiles : allFiles[0];
var success = handleChanges(files);
if (onSelect && success)
onSelect(files);
};
var dragging = useDragging({
labelRef: labelRef,
inputRef: inputRef,
multiple: multiple,
handleChanges: handleChanges,
onDrop: onDrop
});
useEffect(function () {
onDraggingStateChange === null || onDraggingStateChange === void 0 ? void 0 : onDraggingStateChange(dragging);
}, [dragging]);
useEffect(function () {
if (fileOrFiles) {
setUploaded(true);
setFile(fileOrFiles);
}
else {
if (inputRef.current)
inputRef.current.value = '';
setUploaded(false);
setFile(null);
}
}, [fileOrFiles]);
return (_jsxs(UploaderWrapper, __assign({ override: children, className: "".concat(classes || '', " ").concat(disabled ? 'is-disabled' : ''), ref: labelRef, htmlFor: name, onClick: blockEvent, "aria-describedby": ariaDescribedby, role: "button", "aria-label": ariaLabel }, { children: [_jsx("input", { onClick: handleClick, onChange: handleInputChange, accept: acceptedExt(types), ref: inputRef, type: "file", id: name, name: name, disabled: disabled, multiple: multiple, required: required }), dragging && (_jsx(HoverMsg, __assign({ style: dropMessageStyle }, { children: _jsx("span", { children: hoverTitle || 'Drop Here' }) }))), !children && (_jsxs(_Fragment, { children: [_jsx(ImageAdd, {}), _jsxs(DescriptionWrapper, __assign({ "$error": error }, { children: [drawDescription(currFiles, uploaded, error, disabled, label, uploadedLabel), _jsx(DrawTypes, { types: types, minSize: minSize, maxSize: maxSize })] }))] })), children] })));
};
export default FileUploader;
//# sourceMappingURL=FileUploader.js.map