UNPKG

mui2-file-dropzone

Version:

A Material-UI file-upload dropzone. Written in TypeScript.

116 lines 4.86 kB
import { __awaiter, __rest } from "tslib"; import PropTypes from "prop-types"; import React, { PureComponent } from "react"; import { createFileFromUrl, readFile } from "../helpers"; import DropzoneAreaBase from "./DropzoneAreaBase"; const splitDropzoneAreaProps = (props) => { const { clearOnUnmount, initialFiles, onChange, onDelete } = props, dropzoneAreaBaseProps = __rest(props, ["clearOnUnmount", "initialFiles", "onChange", "onDelete"]); const dropzoneAreaProps = { clearOnUnmount, initialFiles, onChange, onDelete, }; const splitProps = [ dropzoneAreaProps, dropzoneAreaBaseProps, ]; return splitProps; }; /** * This components creates an uncontrolled Material-UI Dropzone, with previews and snackbar notifications. * * It supports all props of `DropzoneAreaBase` but keeps the files state internally. * * **Note** To listen to file changes use `onChange` event handler and notice that `onDelete` returns a `File` instance instead of `FileObject`. */ class DropzoneArea extends PureComponent { constructor() { super(...arguments); this.state = { fileObjects: [], }; this.notifyFileChange = () => { const { onChange } = this.props; const { fileObjects } = this.state; if (onChange) { onChange(fileObjects.map((fileObject) => fileObject.file)); } }; this.loadInitialFiles = () => __awaiter(this, void 0, void 0, function* () { const { initialFiles = DropzoneArea.defaultProps.initialFiles } = this.props; try { const fileObjs = yield Promise.all(initialFiles.map((initialFile) => __awaiter(this, void 0, void 0, function* () { let file; if (typeof initialFile === "string") { file = yield createFileFromUrl(initialFile); } else { file = initialFile; } const data = yield readFile(file); const fileObj = { file, data }; return fileObj; }))); this.setState((prevState) => ({ fileObjects: [...prevState.fileObjects, ...fileObjs], }), this.notifyFileChange); } catch (err) { console.log(err); } }); this.addFiles = (newFileObjects) => __awaiter(this, void 0, void 0, function* () { const { filesLimit } = this.props; // Update component state this.setState((prevState) => { // Handle a single file if (filesLimit && filesLimit <= 1) { return { fileObjects: [newFileObjects[0]], }; } // Handle multiple files return { fileObjects: [...prevState.fileObjects, ...newFileObjects], }; }, this.notifyFileChange); }); this.deleteFile = (removedFileObj, removedFileObjIdx) => { event === null || event === void 0 ? void 0 : event.stopPropagation(); const { onDelete } = this.props; const { fileObjects } = this.state; // Calculate remaining fileObjects array const remainingFileObjs = fileObjects.filter((fileObject, i) => { return i !== removedFileObjIdx; }); // Notify removed file if (onDelete) { onDelete(removedFileObj.file); } // Update local state this.setState({ fileObjects: remainingFileObjs }, this.notifyFileChange); }; } componentDidMount() { this.loadInitialFiles(); } componentWillUnmount() { const { clearOnUnmount } = this.props; if (clearOnUnmount) { this.setState({ fileObjects: [] }, this.notifyFileChange); } } render() { const [, dropzoneAreaBaseProps] = splitDropzoneAreaProps(this.props); const { fileObjects } = this.state; return (React.createElement(DropzoneAreaBase, Object.assign({}, dropzoneAreaBaseProps, { fileObjects: fileObjects, onAdd: this.addFiles, onDelete: this.deleteFile }))); } } DropzoneArea.propTypes = Object.assign(Object.assign({}, DropzoneAreaBase.propTypes), { clearOnUnmount: PropTypes.bool, initialFiles: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.any])), filesLimit: PropTypes.number, onChange: PropTypes.func, onDelete: PropTypes.func }); DropzoneArea.defaultProps = { clearOnUnmount: true, initialFiles: [], }; export default DropzoneArea; //# sourceMappingURL=DropzoneArea.js.map