Socket
Socket
Sign inDemoInstall

react-dropzone-esm

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-dropzone-esm - npm Package Compare versions

Comparing version 15.0.0 to 15.0.1

dist/cjs/attr-accept.js

732

dist/cjs/index.js
'use client';
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),s=require("prop-types"),Pe=require("file-selector"),o=require("./utils.js"),xe=Object.defineProperty,ze=Object.defineProperties,Le=Object.getOwnPropertyDescriptors,_=Object.getOwnPropertySymbols,ye=Object.prototype.hasOwnProperty,Fe=Object.prototype.propertyIsEnumerable,he=(c,n,a)=>n in c?xe(c,n,{enumerable:!0,configurable:!0,writable:!0,value:a}):c[n]=a,f=(c,n)=>{for(var a in n||(n={}))ye.call(n,a)&&he(c,a,n[a]);if(_)for(var a of _(n))Fe.call(n,a)&&he(c,a,n[a]);return c},m=(c,n)=>ze(c,Le(n)),M=(c,n)=>{var a={};for(var l in c)ye.call(c,l)&&n.indexOf(l)<0&&(a[l]=c[l]);if(c!=null&&_)for(var l of _(c))n.indexOf(l)<0&&Fe.call(c,l)&&(a[l]=c[l]);return a};const T=t.forwardRef((c,n)=>{var a=c,{children:l}=a,h=M(a,["children"]);const b=Oe(h),{open:d}=b,E=M(b,["open"]);return t.useImperativeHandle(n,()=>({open:d}),[d]),t.createElement(t.Fragment,null,l(m(f({},E),{open:d})))});T.displayName="Dropzone";const Ae={disabled:!1,getFilesFromEvent:Pe.fromEvent,maxSize:1/0,minSize:0,multiple:!0,maxFiles:0,preventDropOnDocument:!0,noClick:!1,noKeyboard:!1,noDrag:!1,noDragEventsBubbling:!1,validator:null,useFsAccessApi:!0,autoFocus:!1};T.defaultProps=Ae,T.propTypes={children:s.func,accept:s.objectOf(s.arrayOf(s.string)),multiple:s.bool,preventDropOnDocument:s.bool,noClick:s.bool,noKeyboard:s.bool,noDrag:s.bool,noDragEventsBubbling:s.bool,minSize:s.number,maxSize:s.number,maxFiles:s.number,disabled:s.bool,getFilesFromEvent:s.func,onFileDialogCancel:s.func,onFileDialogOpen:s.func,useFsAccessApi:s.bool,autoFocus:s.bool,onDragEnter:s.func,onDragLeave:s.func,onDragOver:s.func,onDrop:s.func,onDropAccepted:s.func,onDropRejected:s.func,onError:s.func,validator:s.func};const te={isFocused:!1,isFileDialogActive:!1,isDragActive:!1,isDragAccept:!1,isDragReject:!1,acceptedFiles:[],fileRejections:[]};function Oe(c={}){const{accept:n,disabled:a,getFilesFromEvent:l,maxSize:h,minSize:b,multiple:d,maxFiles:E,onDragEnter:B,onDragLeave:q,onDragOver:W,onDrop:N,onDropAccepted:U,onDropRejected:J,onFileDialogCancel:Y,onFileDialogOpen:G,useFsAccessApi:oe,autoFocus:ce,preventDropOnDocument:Q,noClick:se,noKeyboard:V,noDrag:ae,noDragEventsBubbling:y,onError:X,validator:k}=f(f({},Ae),c),R=t.useMemo(()=>o.acceptPropAsAcceptAttr(n),[n]),ie=t.useMemo(()=>o.pickerOptionsFromAccept(n),[n]),Z=t.useMemo(()=>typeof G=="function"?G:Ce,[G]),x=t.useMemo(()=>typeof Y=="function"?Y:Ce,[Y]),p=t.useRef(null),D=t.useRef(null),[le,v]=t.useReducer(Ie,te),{isFocused:ke,isFileDialogActive:ue}=le,z=t.useRef(typeof window!="undefined"&&window.isSecureContext&&oe&&o.canUseFileSystemAccessAPI()),pe=()=>{!z.current&&ue&&setTimeout(()=>{if(D.current){const{files:e}=D.current;e.length||(v({type:"closeDialog"}),x())}},300)};t.useEffect(()=>(window.addEventListener("focus",pe,!1),()=>{window.removeEventListener("focus",pe,!1)}),[D,ue,x,z]);const A=t.useRef([]),fe=e=>{p.current&&p.current.contains(e.target)||(e.preventDefault(),A.current=[])};t.useEffect(()=>(Q&&(document.addEventListener("dragover",o.onDocumentDragOver,!1),document.addEventListener("drop",fe,!1)),()=>{Q&&(document.removeEventListener("dragover",o.onDocumentDragOver),document.removeEventListener("drop",fe))}),[p,Q]),t.useEffect(()=>(!a&&ce&&p.current&&p.current.focus(),()=>{}),[p,ce,a]);const F=t.useCallback(e=>{X?X(e):console.error(e)},[X]),de=t.useCallback(e=>{e.preventDefault(),e.persist(),K(e),A.current=[...A.current,e.target],o.isEvtWithFiles(e)&&Promise.resolve(l(e)).then(r=>{if(o.isPropagationStopped(e)&&!y)return;const i=r.length,u=i>0&&o.allFilesAccepted({files:r,accept:R,minSize:b,maxSize:h,multiple:d,maxFiles:E,validator:k}),g=i>0&&!u;v({isDragAccept:u,isDragReject:g,isDragActive:!0,type:"setDraggedFiles"}),B&&B(e)}).catch(r=>F(r))},[l,B,F,y,R,b,h,d,E,k]),ve=t.useCallback(e=>{e.preventDefault(),e.persist(),K(e);const r=o.isEvtWithFiles(e);if(r&&e.dataTransfer)try{e.dataTransfer.dropEffect="copy"}catch(i){}return r&&W&&W(e),!1},[W,y]),ge=t.useCallback(e=>{e.preventDefault(),e.persist(),K(e);const r=A.current.filter(u=>p.current&&p.current.contains(u)),i=r.indexOf(e.target);i!==-1&&r.splice(i,1),A.current=r,!(r.length>0)&&(v({type:"setDraggedFiles",isDragActive:!1,isDragAccept:!1,isDragReject:!1}),o.isEvtWithFiles(e)&&q&&q(e))},[p,q,y]),L=t.useCallback((e,r)=>{const i=[],u=[];e.forEach(g=>{const[w,S]=o.fileAccepted(g,R),[ee,re]=o.fileMatchSize(g,b,h),j=k?k(g):null;if(w&&ee&&!j)i.push(g);else{let P=[S,re];j&&(P=P.concat(j)),u.push({file:g,errors:P.filter(ne=>ne)})}}),(!d&&i.length>1||d&&E>=1&&i.length>E)&&(i.forEach(g=>{u.push({file:g,errors:[o.TOO_MANY_FILES_REJECTION]})}),i.splice(0)),v({acceptedFiles:i,fileRejections:u,type:"setFiles"}),N&&N(i,u,r),u.length>0&&J&&J(u,r),i.length>0&&U&&U(i,r)},[v,d,R,b,h,E,N,U,J,k]),I=t.useCallback(e=>{e.preventDefault(),e.persist(),K(e),A.current=[],o.isEvtWithFiles(e)&&Promise.resolve(l(e)).then(r=>{o.isPropagationStopped(e)&&!y||L(r,e)}).catch(r=>F(r)),v({type:"reset"})},[l,L,F,y]),O=t.useCallback(()=>{if(z.current){v({type:"openDialog"}),Z();const e={multiple:d,types:ie};window.showOpenFilePicker(e).then(r=>l(r)).then(r=>{L(r,null),v({type:"closeDialog"})}).catch(r=>{o.isAbort(r)?(x(r),v({type:"closeDialog"})):o.isSecurityError(r)?(z.current=!1,D.current?(D.current.value=null,D.current.click()):F(new Error("Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no <input> was provided."))):F(r)});return}D.current&&(v({type:"openDialog"}),Z(),D.current.value=null,D.current.click())},[v,Z,x,oe,L,F,ie,d]),De=t.useCallback(e=>{!p.current||!p.current.isEqualNode(e.target)||(e.key===" "||e.key==="Enter"||e.keyCode===32||e.keyCode===13)&&(e.preventDefault(),O())},[p,O]),me=t.useCallback(()=>{v({type:"focus"})},[]),be=t.useCallback(()=>{v({type:"blur"})},[]),Ee=t.useCallback(()=>{se||(o.isIeOrEdge()?setTimeout(O,0):O())},[se,O]),C=e=>a?null:e,$=e=>V?null:C(e),H=e=>ae?null:C(e),K=e=>{y&&e.stopPropagation()},Re=t.useMemo(()=>(e={})=>{var r=e,{refKey:i="ref",role:u,onKeyDown:g,onFocus:w,onBlur:S,onClick:ee,onDragEnter:re,onDragOver:j,onDragLeave:P,onDrop:ne}=r,je=M(r,["refKey","role","onKeyDown","onFocus","onBlur","onClick","onDragEnter","onDragOver","onDragLeave","onDrop"]);return f(f({onKeyDown:$(o.composeEventHandlers(g,De)),onFocus:$(o.composeEventHandlers(w,me)),onBlur:$(o.composeEventHandlers(S,be)),onClick:C(o.composeEventHandlers(ee,Ee)),onDragEnter:H(o.composeEventHandlers(re,de)),onDragOver:H(o.composeEventHandlers(j,ve)),onDragLeave:H(o.composeEventHandlers(P,ge)),onDrop:H(o.composeEventHandlers(ne,I)),role:typeof u=="string"&&u!==""?u:"presentation",[i]:p},!a&&!V?{tabIndex:0}:{}),je)},[p,De,me,be,Ee,de,ve,ge,I,V,ae,a]),we=t.useCallback(e=>{e.stopPropagation()},[]),Se=t.useMemo(()=>(e={})=>{var r=e,{refKey:i="ref",onChange:u,onClick:g}=r,w=M(r,["refKey","onChange","onClick"]);const S={accept:R,multiple:d,type:"file",style:{display:"none"},onChange:C(o.composeEventHandlers(u,I)),onClick:C(o.composeEventHandlers(g,we)),tabIndex:-1,[i]:D};return f(f({},S),w)},[D,n,d,I,a]);return m(f({},le),{isFocused:ke&&!a,getRootProps:Re,getInputProps:Se,rootRef:p,inputRef:D,open:C(O)})}function Ie(c,n){switch(n.type){case"focus":return m(f({},c),{isFocused:!0});case"blur":return m(f({},c),{isFocused:!1});case"openDialog":return m(f({},te),{isFileDialogActive:!0});case"closeDialog":return m(f({},c),{isFileDialogActive:!1});case"setDraggedFiles":return m(f({},c),{isDragActive:n.isDragActive,isDragAccept:n.isDragAccept,isDragReject:n.isDragReject});case"setFiles":return m(f({},c),{acceptedFiles:n.acceptedFiles,fileRejections:n.fileRejections});case"reset":return f({},te);default:return c}}function Ce(){}exports.ErrorCode=o.ErrorCode,exports.default=T,exports.useDropzone=Oe;
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var PropTypes = require('prop-types');
var fileSelector = require('./file-selector.js');
var utils = require('./utils.js');
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __objRest = (source, exclude) => {
var target = {};
for (var prop in source)
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
target[prop] = source[prop];
if (source != null && __getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(source)) {
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
target[prop] = source[prop];
}
return target;
};
const Dropzone = React.forwardRef((_a, ref) => {
var _b = _a, { children } = _b, params = __objRest(_b, ["children"]);
const _a2 = useDropzone(params), { open } = _a2, props = __objRest(_a2, ["open"]);
React.useImperativeHandle(ref, () => ({ open }), [open]);
return /* @__PURE__ */ React.createElement(React.Fragment, null, children(__spreadProps(__spreadValues({}, props), { open })));
});
Dropzone.displayName = "Dropzone";
const defaultProps = {
disabled: false,
getFilesFromEvent: fileSelector.fromEvent,
maxSize: Infinity,
minSize: 0,
multiple: true,
maxFiles: 0,
preventDropOnDocument: true,
noClick: false,
noKeyboard: false,
noDrag: false,
noDragEventsBubbling: false,
validator: null,
useFsAccessApi: true,
autoFocus: false
};
Dropzone.defaultProps = defaultProps;
Dropzone.propTypes = {
/**
* Render function that exposes the dropzone state and prop getter fns
*
* @param {object} params
* @param {Function} params.getRootProps Returns the props you should apply to the root drop container you render
* @param {Function} params.getInputProps Returns the props you should apply to hidden file input you render
* @param {Function} params.open Open the native file selection dialog
* @param {boolean} params.isFocused Dropzone area is in focus
* @param {boolean} params.isFileDialogActive File dialog is opened
* @param {boolean} params.isDragActive Active drag is in progress
* @param {boolean} params.isDragAccept Dragged files are accepted
* @param {boolean} params.isDragReject Some dragged files are rejected
* @param {File[]} params.acceptedFiles Accepted files
* @param {FileRejection[]} params.fileRejections Rejected files and why they were rejected
*/
children: PropTypes.func,
/**
* Set accepted file types.
* Checkout https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker types option for more information.
* Keep in mind that mime type determination is not reliable across platforms. CSV files,
* for example, are reported as text/plain under macOS but as application/vnd.ms-excel under
* Windows. In some cases there might not be a mime type set at all (https://github.com/react-dropzone/react-dropzone/issues/276).
*/
accept: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.string)),
/**
* Allow drag 'n' drop (or selection from the file dialog) of multiple files
*/
multiple: PropTypes.bool,
/**
* If false, allow dropped items to take over the current browser window
*/
preventDropOnDocument: PropTypes.bool,
/**
* If true, disables click to open the native file selection dialog
*/
noClick: PropTypes.bool,
/**
* If true, disables SPACE/ENTER to open the native file selection dialog.
* Note that it also stops tracking the focus state.
*/
noKeyboard: PropTypes.bool,
/**
* If true, disables drag 'n' drop
*/
noDrag: PropTypes.bool,
/**
* If true, stops drag event propagation to parents
*/
noDragEventsBubbling: PropTypes.bool,
/**
* Minimum file size (in bytes)
*/
minSize: PropTypes.number,
/**
* Maximum file size (in bytes)
*/
maxSize: PropTypes.number,
/**
* Maximum accepted number of files
* The default value is 0 which means there is no limitation to how many files are accepted.
*/
maxFiles: PropTypes.number,
/**
* Enable/disable the dropzone
*/
disabled: PropTypes.bool,
/**
* Use this to provide a custom file aggregator
*
* @param {(DragEvent|Event)} event A drag event or input change event (if files were selected via the file dialog)
*/
getFilesFromEvent: PropTypes.func,
/**
* Cb for when closing the file dialog with no selection
*/
onFileDialogCancel: PropTypes.func,
/**
* Cb for when opening the file dialog
*/
onFileDialogOpen: PropTypes.func,
/**
* Set to true to use the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API
* to open the file picker instead of using an `<input type="file">` click event.
*/
useFsAccessApi: PropTypes.bool,
/**
* Set to true to focus the root element on render
*/
autoFocus: PropTypes.bool,
/**
* Cb for when the `dragenter` event occurs.
*
* @param {DragEvent} event
*/
onDragEnter: PropTypes.func,
/**
* Cb for when the `dragleave` event occurs
*
* @param {DragEvent} event
*/
onDragLeave: PropTypes.func,
/**
* Cb for when the `dragover` event occurs
*
* @param {DragEvent} event
*/
onDragOver: PropTypes.func,
/**
* Cb for when the `drop` event occurs.
* Note that this callback is invoked after the `getFilesFromEvent` callback is done.
*
* Files are accepted or rejected based on the `accept`, `multiple`, `minSize` and `maxSize` props.
* `accept` must be a valid [MIME type](http://www.iana.org/assignments/media-types/media-types.xhtml) according to [input element specification](https://www.w3.org/wiki/HTML/Elements/input/file) or a valid file extension.
* If `multiple` is set to false and additional files are dropped,
* all files besides the first will be rejected.
* Any file which does not have a size in the [`minSize`, `maxSize`] range, will be rejected as well.
*
* Note that the `onDrop` callback will always be invoked regardless if the dropped files were accepted or rejected.
* If you'd like to react to a specific scenario, use the `onDropAccepted`/`onDropRejected` props.
*
* `onDrop` will provide you with an array of [File](https://developer.mozilla.org/en-US/docs/Web/API/File) objects which you can then process and send to a server.
* For example, with [SuperAgent](https://github.com/visionmedia/superagent) as a http/ajax library:
*
* ```js
* function onDrop(acceptedFiles) {
* const req = request.post('/upload')
* acceptedFiles.forEach(file => {
* req.attach(file.name, file)
* })
* req.end(callback)
* }
* ```
*
* @param {File[]} acceptedFiles
* @param {FileRejection[]} fileRejections
* @param {(DragEvent|Event)} event A drag event or input change event (if files were selected via the file dialog)
*/
onDrop: PropTypes.func,
/**
* Cb for when the `drop` event occurs.
* Note that if no files are accepted, this callback is not invoked.
*
* @param {File[]} files
* @param {(DragEvent|Event)} event
*/
onDropAccepted: PropTypes.func,
/**
* Cb for when the `drop` event occurs.
* Note that if no files are rejected, this callback is not invoked.
*
* @param {FileRejection[]} fileRejections
* @param {(DragEvent|Event)} event
*/
onDropRejected: PropTypes.func,
/**
* Cb for when there's some error from any of the promises.
*
* @param {Error} error
*/
onError: PropTypes.func,
/**
* Custom validation function. It must return null if there's no errors.
* @param {File} file
* @returns {FileError|FileError[]|null}
*/
validator: PropTypes.func
};
const initialState = {
isFocused: false,
isFileDialogActive: false,
isDragActive: false,
isDragAccept: false,
isDragReject: false,
acceptedFiles: [],
fileRejections: []
};
function useDropzone(props = {}) {
const {
accept,
disabled,
getFilesFromEvent,
maxSize,
minSize,
multiple,
maxFiles,
onDragEnter,
onDragLeave,
onDragOver,
onDrop,
onDropAccepted,
onDropRejected,
onFileDialogCancel,
onFileDialogOpen,
useFsAccessApi,
autoFocus,
preventDropOnDocument,
noClick,
noKeyboard,
noDrag,
noDragEventsBubbling,
onError,
validator
} = __spreadValues(__spreadValues({}, defaultProps), props);
const acceptAttr = React.useMemo(() => utils.acceptPropAsAcceptAttr(accept), [accept]);
const pickerTypes = React.useMemo(() => utils.pickerOptionsFromAccept(accept), [accept]);
const onFileDialogOpenCb = React.useMemo(
() => typeof onFileDialogOpen === "function" ? onFileDialogOpen : noop,
[onFileDialogOpen]
);
const onFileDialogCancelCb = React.useMemo(
() => typeof onFileDialogCancel === "function" ? onFileDialogCancel : noop,
[onFileDialogCancel]
);
const rootRef = React.useRef(null);
const inputRef = React.useRef(null);
const [state, dispatch] = React.useReducer(reducer, initialState);
const { isFocused, isFileDialogActive } = state;
const fsAccessApiWorksRef = React.useRef(
typeof window !== "undefined" && window.isSecureContext && useFsAccessApi && utils.canUseFileSystemAccessAPI()
);
const onWindowFocus = () => {
if (!fsAccessApiWorksRef.current && isFileDialogActive) {
setTimeout(() => {
if (inputRef.current) {
const { files } = inputRef.current;
if (!files.length) {
dispatch({ type: "closeDialog" });
onFileDialogCancelCb();
}
}
}, 300);
}
};
React.useEffect(() => {
window.addEventListener("focus", onWindowFocus, false);
return () => {
window.removeEventListener("focus", onWindowFocus, false);
};
}, [inputRef, isFileDialogActive, onFileDialogCancelCb, fsAccessApiWorksRef]);
const dragTargetsRef = React.useRef([]);
const onDocumentDrop = (event) => {
if (rootRef.current && rootRef.current.contains(event.target)) {
return;
}
event.preventDefault();
dragTargetsRef.current = [];
};
React.useEffect(() => {
if (preventDropOnDocument) {
document.addEventListener("dragover", utils.onDocumentDragOver, false);
document.addEventListener("drop", onDocumentDrop, false);
}
return () => {
if (preventDropOnDocument) {
document.removeEventListener("dragover", utils.onDocumentDragOver);
document.removeEventListener("drop", onDocumentDrop);
}
};
}, [rootRef, preventDropOnDocument]);
React.useEffect(() => {
if (!disabled && autoFocus && rootRef.current) {
rootRef.current.focus();
}
return () => {
};
}, [rootRef, autoFocus, disabled]);
const onErrCb = React.useCallback(
(e) => {
if (onError) {
onError(e);
} else {
console.error(e);
}
},
[onError]
);
const onDragEnterCb = React.useCallback(
(event) => {
event.preventDefault();
event.persist();
stopPropagation(event);
dragTargetsRef.current = [...dragTargetsRef.current, event.target];
if (utils.isEvtWithFiles(event)) {
Promise.resolve(getFilesFromEvent(event)).then((files) => {
if (utils.isPropagationStopped(event) && !noDragEventsBubbling) {
return;
}
const fileCount = files.length;
const isDragAccept = fileCount > 0 && utils.allFilesAccepted({
files,
accept: acceptAttr,
minSize,
maxSize,
multiple,
maxFiles,
validator
});
const isDragReject = fileCount > 0 && !isDragAccept;
dispatch({
isDragAccept,
isDragReject,
isDragActive: true,
type: "setDraggedFiles"
});
if (onDragEnter) {
onDragEnter(event);
}
}).catch((e) => onErrCb(e));
}
},
[
getFilesFromEvent,
onDragEnter,
onErrCb,
noDragEventsBubbling,
acceptAttr,
minSize,
maxSize,
multiple,
maxFiles,
validator
]
);
const onDragOverCb = React.useCallback(
(event) => {
event.preventDefault();
event.persist();
stopPropagation(event);
const hasFiles = utils.isEvtWithFiles(event);
if (hasFiles && event.dataTransfer) {
try {
event.dataTransfer.dropEffect = "copy";
} catch (e) {
}
}
if (hasFiles && onDragOver) {
onDragOver(event);
}
return false;
},
[onDragOver, noDragEventsBubbling]
);
const onDragLeaveCb = React.useCallback(
(event) => {
event.preventDefault();
event.persist();
stopPropagation(event);
const targets = dragTargetsRef.current.filter(
(target) => rootRef.current && rootRef.current.contains(target)
);
const targetIdx = targets.indexOf(event.target);
if (targetIdx !== -1) {
targets.splice(targetIdx, 1);
}
dragTargetsRef.current = targets;
if (targets.length > 0) {
return;
}
dispatch({
type: "setDraggedFiles",
isDragActive: false,
isDragAccept: false,
isDragReject: false
});
if (utils.isEvtWithFiles(event) && onDragLeave) {
onDragLeave(event);
}
},
[rootRef, onDragLeave, noDragEventsBubbling]
);
const setFiles = React.useCallback(
(files, event) => {
const acceptedFiles = [];
const fileRejections = [];
files.forEach((file) => {
const [accepted, acceptError] = utils.fileAccepted(file, acceptAttr);
const [sizeMatch, sizeError] = utils.fileMatchSize(file, minSize, maxSize);
const customErrors = validator ? validator(file) : null;
if (accepted && sizeMatch && !customErrors) {
acceptedFiles.push(file);
} else {
let errors = [acceptError, sizeError];
if (customErrors) {
errors = errors.concat(customErrors);
}
fileRejections.push({ file, errors: errors.filter((e) => e) });
}
});
if (!multiple && acceptedFiles.length > 1 || multiple && maxFiles >= 1 && acceptedFiles.length > maxFiles) {
acceptedFiles.forEach((file) => {
fileRejections.push({ file, errors: [utils.TOO_MANY_FILES_REJECTION] });
});
acceptedFiles.splice(0);
}
dispatch({
acceptedFiles,
fileRejections,
type: "setFiles"
});
if (onDrop) {
onDrop(acceptedFiles, fileRejections, event);
}
if (fileRejections.length > 0 && onDropRejected) {
onDropRejected(fileRejections, event);
}
if (acceptedFiles.length > 0 && onDropAccepted) {
onDropAccepted(acceptedFiles, event);
}
},
[
dispatch,
multiple,
acceptAttr,
minSize,
maxSize,
maxFiles,
onDrop,
onDropAccepted,
onDropRejected,
validator
]
);
const onDropCb = React.useCallback(
(event) => {
event.preventDefault();
event.persist();
stopPropagation(event);
dragTargetsRef.current = [];
if (utils.isEvtWithFiles(event)) {
Promise.resolve(getFilesFromEvent(event)).then((files) => {
if (utils.isPropagationStopped(event) && !noDragEventsBubbling) {
return;
}
setFiles(files, event);
}).catch((e) => onErrCb(e));
}
dispatch({ type: "reset" });
},
[getFilesFromEvent, setFiles, onErrCb, noDragEventsBubbling]
);
const openFileDialog = React.useCallback(() => {
if (fsAccessApiWorksRef.current) {
dispatch({ type: "openDialog" });
onFileDialogOpenCb();
const opts = {
multiple,
types: pickerTypes
};
window.showOpenFilePicker(opts).then((handles) => getFilesFromEvent(handles)).then((files) => {
setFiles(files, null);
dispatch({ type: "closeDialog" });
}).catch((e) => {
if (utils.isAbort(e)) {
onFileDialogCancelCb(e);
dispatch({ type: "closeDialog" });
} else if (utils.isSecurityError(e)) {
fsAccessApiWorksRef.current = false;
if (inputRef.current) {
inputRef.current.value = null;
inputRef.current.click();
} else {
onErrCb(
new Error(
"Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no <input> was provided."
)
);
}
} else {
onErrCb(e);
}
});
return;
}
if (inputRef.current) {
dispatch({ type: "openDialog" });
onFileDialogOpenCb();
inputRef.current.value = null;
inputRef.current.click();
}
}, [
dispatch,
onFileDialogOpenCb,
onFileDialogCancelCb,
useFsAccessApi,
setFiles,
onErrCb,
pickerTypes,
multiple
]);
const onKeyDownCb = React.useCallback(
(event) => {
if (!rootRef.current || !rootRef.current.isEqualNode(event.target)) {
return;
}
if (event.key === " " || event.key === "Enter" || event.keyCode === 32 || event.keyCode === 13) {
event.preventDefault();
openFileDialog();
}
},
[rootRef, openFileDialog]
);
const onFocusCb = React.useCallback(() => {
dispatch({ type: "focus" });
}, []);
const onBlurCb = React.useCallback(() => {
dispatch({ type: "blur" });
}, []);
const onClickCb = React.useCallback(() => {
if (noClick) {
return;
}
if (utils.isIeOrEdge()) {
setTimeout(openFileDialog, 0);
} else {
openFileDialog();
}
}, [noClick, openFileDialog]);
const composeHandler = (fn) => {
return disabled ? null : fn;
};
const composeKeyboardHandler = (fn) => {
return noKeyboard ? null : composeHandler(fn);
};
const composeDragHandler = (fn) => {
return noDrag ? null : composeHandler(fn);
};
const stopPropagation = (event) => {
if (noDragEventsBubbling) {
event.stopPropagation();
}
};
const getRootProps = React.useMemo(
() => (_a = {}) => {
var _b = _a, {
refKey = "ref",
role,
onKeyDown,
onFocus,
onBlur,
onClick,
onDragEnter: onDragEnter2,
onDragOver: onDragOver2,
onDragLeave: onDragLeave2,
onDrop: onDrop2
} = _b, rest = __objRest(_b, [
"refKey",
"role",
"onKeyDown",
"onFocus",
"onBlur",
"onClick",
"onDragEnter",
"onDragOver",
"onDragLeave",
"onDrop"
]);
return __spreadValues(__spreadValues({
onKeyDown: composeKeyboardHandler(
utils.composeEventHandlers(onKeyDown, onKeyDownCb)
),
onFocus: composeKeyboardHandler(
utils.composeEventHandlers(onFocus, onFocusCb)
),
onBlur: composeKeyboardHandler(utils.composeEventHandlers(onBlur, onBlurCb)),
onClick: composeHandler(utils.composeEventHandlers(onClick, onClickCb)),
onDragEnter: composeDragHandler(
utils.composeEventHandlers(onDragEnter2, onDragEnterCb)
),
onDragOver: composeDragHandler(
utils.composeEventHandlers(onDragOver2, onDragOverCb)
),
onDragLeave: composeDragHandler(
utils.composeEventHandlers(onDragLeave2, onDragLeaveCb)
),
onDrop: composeDragHandler(utils.composeEventHandlers(onDrop2, onDropCb)),
role: typeof role === "string" && role !== "" ? role : "presentation",
[refKey]: rootRef
}, !disabled && !noKeyboard ? { tabIndex: 0 } : {}), rest);
},
[
rootRef,
onKeyDownCb,
onFocusCb,
onBlurCb,
onClickCb,
onDragEnterCb,
onDragOverCb,
onDragLeaveCb,
onDropCb,
noKeyboard,
noDrag,
disabled
]
);
const onInputElementClick = React.useCallback((event) => {
event.stopPropagation();
}, []);
const getInputProps = React.useMemo(
() => (_a = {}) => {
var _b = _a, { refKey = "ref", onChange, onClick } = _b, rest = __objRest(_b, ["refKey", "onChange", "onClick"]);
const inputProps = {
accept: acceptAttr,
multiple,
type: "file",
style: { display: "none" },
onChange: composeHandler(utils.composeEventHandlers(onChange, onDropCb)),
onClick: composeHandler(
utils.composeEventHandlers(onClick, onInputElementClick)
),
tabIndex: -1,
[refKey]: inputRef
};
return __spreadValues(__spreadValues({}, inputProps), rest);
},
[inputRef, accept, multiple, onDropCb, disabled]
);
return __spreadProps(__spreadValues({}, state), {
isFocused: isFocused && !disabled,
getRootProps,
getInputProps,
rootRef,
inputRef,
open: composeHandler(openFileDialog)
});
}
function reducer(state, action) {
switch (action.type) {
case "focus":
return __spreadProps(__spreadValues({}, state), {
isFocused: true
});
case "blur":
return __spreadProps(__spreadValues({}, state), {
isFocused: false
});
case "openDialog":
return __spreadProps(__spreadValues({}, initialState), {
isFileDialogActive: true
});
case "closeDialog":
return __spreadProps(__spreadValues({}, state), {
isFileDialogActive: false
});
case "setDraggedFiles":
return __spreadProps(__spreadValues({}, state), {
isDragActive: action.isDragActive,
isDragAccept: action.isDragAccept,
isDragReject: action.isDragReject
});
case "setFiles":
return __spreadProps(__spreadValues({}, state), {
acceptedFiles: action.acceptedFiles,
fileRejections: action.fileRejections
});
case "reset":
return __spreadValues({}, initialState);
default:
return state;
}
}
function noop() {
}
exports.ErrorCode = utils.ErrorCode;
exports.default = Dropzone;
exports.useDropzone = useDropzone;

@@ -1,1 +0,216 @@

"use strict";var _=require("attr-accept"),M=Object.defineProperty,L=Object.defineProperties,P=Object.getOwnPropertyDescriptors,g=Object.getOwnPropertySymbols,j=Object.prototype.hasOwnProperty,R=Object.prototype.propertyIsEnumerable,m=(e,t,r)=>t in e?M(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,w=(e,t)=>{for(var r in t||(t={}))j.call(t,r)&&m(e,r,t[r]);if(g)for(var r of g(t))R.call(t,r)&&m(e,r,t[r]);return e},x=(e,t)=>L(e,P(t));const a="file-invalid-type",c="file-too-large",s="file-too-small",l="too-many-files",h={FileInvalidType:a,FileTooLarge:c,FileTooSmall:s,TooManyFiles:l},T=e=>{e=Array.isArray(e)&&e.length===1?e[0]:e;const t=Array.isArray(e)?`one of ${e.join(", ")}`:e;return{code:a,message:`File type must be ${t}`}},p=e=>({code:c,message:`File is larger than ${e} ${e===1?"byte":"bytes"}`}),u=e=>({code:s,message:`File is smaller than ${e} ${e===1?"byte":"bytes"}`}),z={code:l,message:"Too many files"};function I(e,t){const r=e.type==="application/x-moz-file"||_(e,t);return[r,r?null:T(t)]}function v(e,t,r){if(n(e.size))if(n(t)&&n(r)){if(e.size>r)return[!1,p(r)];if(e.size<t)return[!1,u(t)]}else{if(n(t)&&e.size<t)return[!1,u(t)];if(n(r)&&e.size>r)return[!1,p(r)]}return[!0,null]}function n(e){return e!=null}function D({files:e,accept:t,minSize:r,maxSize:i,multiple:y,maxFiles:O,validator:A}){return!y&&e.length>1||y&&O>=1&&e.length>O?!1:e.every(o=>{const[F]=I(o,t),[b]=v(o,r,i),S=A?A(o):null;return F&&b&&!S})}function f(e){return typeof e.isPropagationStopped=="function"?e.isPropagationStopped():typeof e.cancelBubble!="undefined"?e.cancelBubble:!1}function $(e){return e.dataTransfer?Array.prototype.some.call(e.dataTransfer.types,t=>t==="Files"||t==="application/x-moz-file"):!!e.target&&!!e.target.files}function N(e){e.preventDefault()}function C(e){return e.indexOf("MSIE")!==-1||e.indexOf("Trident/")!==-1}function Y(e){return e.indexOf("Edge/")!==-1}function k(e=window.navigator.userAgent){return C(e)||Y(e)}function B(...e){return(t,...r)=>e.some(i=>(!f(t)&&i&&i(t,...r),f(t)))}function H(){return"showOpenFilePicker"in window}function U(e){return n(e)?[{description:"Files",accept:Object.entries(e).filter(([t,r])=>{let i=!0;return d(t)||(console.warn(`Skipped "${t}" because it is not a valid MIME type. Check https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types for a list of valid MIME types.`),i=!1),(!Array.isArray(r)||!r.every(E))&&(console.warn(`Skipped "${t}" because an invalid file extension was provided.`),i=!1),i}).reduce((t,[r,i])=>x(w({},t),{[r]:i}),{})}]:e}function W(e){if(n(e))return Object.entries(e).reduce((t,[r,i])=>[...t,r,...i],[]).filter(t=>d(t)||E(t)).join(",")}function G(e){return e instanceof DOMException&&(e.name==="AbortError"||e.code===e.ABORT_ERR)}function J(e){return e instanceof DOMException&&(e.name==="SecurityError"||e.code===e.SECURITY_ERR)}function d(e){return e==="audio/*"||e==="video/*"||e==="image/*"||e==="text/*"||/\w+\/[-+.\w]+/g.test(e)}function E(e){return/^.*\.[\w]+$/.test(e)}exports.ErrorCode=h,exports.FILE_INVALID_TYPE=a,exports.FILE_TOO_LARGE=c,exports.FILE_TOO_SMALL=s,exports.TOO_MANY_FILES=l,exports.TOO_MANY_FILES_REJECTION=z,exports.acceptPropAsAcceptAttr=W,exports.allFilesAccepted=D,exports.canUseFileSystemAccessAPI=H,exports.composeEventHandlers=B,exports.fileAccepted=I,exports.fileMatchSize=v,exports.getInvalidTypeRejectionErr=T,exports.getTooLargeRejectionErr=p,exports.getTooSmallRejectionErr=u,exports.isAbort=G,exports.isEvtWithFiles=$,exports.isExt=E,exports.isIeOrEdge=k,exports.isMIMEType=d,exports.isPropagationStopped=f,exports.isSecurityError=J,exports.onDocumentDragOver=N,exports.pickerOptionsFromAccept=U;
'use strict';
var attrAccept = require('./attr-accept.js');
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
const FILE_INVALID_TYPE = "file-invalid-type";
const FILE_TOO_LARGE = "file-too-large";
const FILE_TOO_SMALL = "file-too-small";
const TOO_MANY_FILES = "too-many-files";
const ErrorCode = {
FileInvalidType: FILE_INVALID_TYPE,
FileTooLarge: FILE_TOO_LARGE,
FileTooSmall: FILE_TOO_SMALL,
TooManyFiles: TOO_MANY_FILES
};
const getInvalidTypeRejectionErr = (accept) => {
accept = Array.isArray(accept) && accept.length === 1 ? accept[0] : accept;
const messageSuffix = Array.isArray(accept) ? `one of ${accept.join(", ")}` : accept;
return {
code: FILE_INVALID_TYPE,
message: `File type must be ${messageSuffix}`
};
};
const getTooLargeRejectionErr = (maxSize) => {
return {
code: FILE_TOO_LARGE,
message: `File is larger than ${maxSize} ${maxSize === 1 ? "byte" : "bytes"}`
};
};
const getTooSmallRejectionErr = (minSize) => {
return {
code: FILE_TOO_SMALL,
message: `File is smaller than ${minSize} ${minSize === 1 ? "byte" : "bytes"}`
};
};
const TOO_MANY_FILES_REJECTION = {
code: TOO_MANY_FILES,
message: "Too many files"
};
function fileAccepted(file, accept) {
const isAcceptable = file.type === "application/x-moz-file" || attrAccept.default(file, accept);
return [
isAcceptable,
isAcceptable ? null : getInvalidTypeRejectionErr(accept)
];
}
function fileMatchSize(file, minSize, maxSize) {
if (isDefined(file.size)) {
if (isDefined(minSize) && isDefined(maxSize)) {
if (file.size > maxSize)
return [false, getTooLargeRejectionErr(maxSize)];
if (file.size < minSize)
return [false, getTooSmallRejectionErr(minSize)];
} else if (isDefined(minSize) && file.size < minSize)
return [false, getTooSmallRejectionErr(minSize)];
else if (isDefined(maxSize) && file.size > maxSize)
return [false, getTooLargeRejectionErr(maxSize)];
}
return [true, null];
}
function isDefined(value) {
return value !== void 0 && value !== null;
}
function allFilesAccepted({
files,
accept,
minSize,
maxSize,
multiple,
maxFiles,
validator
}) {
if (!multiple && files.length > 1 || multiple && maxFiles >= 1 && files.length > maxFiles) {
return false;
}
return files.every((file) => {
const [accepted] = fileAccepted(file, accept);
const [sizeMatch] = fileMatchSize(file, minSize, maxSize);
const customErrors = validator ? validator(file) : null;
return accepted && sizeMatch && !customErrors;
});
}
function isPropagationStopped(event) {
if (typeof event.isPropagationStopped === "function") {
return event.isPropagationStopped();
} else if (typeof event.cancelBubble !== "undefined") {
return event.cancelBubble;
}
return false;
}
function isEvtWithFiles(event) {
if (!event.dataTransfer) {
return !!event.target && !!event.target.files;
}
return Array.prototype.some.call(
event.dataTransfer.types,
(type) => type === "Files" || type === "application/x-moz-file"
);
}
function onDocumentDragOver(event) {
event.preventDefault();
}
function isIe(userAgent) {
return userAgent.indexOf("MSIE") !== -1 || userAgent.indexOf("Trident/") !== -1;
}
function isEdge(userAgent) {
return userAgent.indexOf("Edge/") !== -1;
}
function isIeOrEdge(userAgent = window.navigator.userAgent) {
return isIe(userAgent) || isEdge(userAgent);
}
function composeEventHandlers(...fns) {
return (event, ...args) => fns.some((fn) => {
if (!isPropagationStopped(event) && fn) {
fn(event, ...args);
}
return isPropagationStopped(event);
});
}
function canUseFileSystemAccessAPI() {
return "showOpenFilePicker" in window;
}
function pickerOptionsFromAccept(accept) {
if (isDefined(accept)) {
const acceptForPicker = Object.entries(accept).filter(([mimeType, ext]) => {
let ok = true;
if (!isMIMEType(mimeType)) {
console.warn(
`Skipped "${mimeType}" because it is not a valid MIME type. Check https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types for a list of valid MIME types.`
);
ok = false;
}
if (!Array.isArray(ext) || !ext.every(isExt)) {
console.warn(
`Skipped "${mimeType}" because an invalid file extension was provided.`
);
ok = false;
}
return ok;
}).reduce(
(agg, [mimeType, ext]) => __spreadProps(__spreadValues({}, agg), {
[mimeType]: ext
}),
{}
);
return [
{
// description is required due to https://crbug.com/1264708
description: "Files",
accept: acceptForPicker
}
];
}
return accept;
}
function acceptPropAsAcceptAttr(accept) {
if (isDefined(accept)) {
return Object.entries(accept).reduce((a, [mimeType, ext]) => [...a, mimeType, ...ext], []).filter((v) => isMIMEType(v) || isExt(v)).join(",");
}
return void 0;
}
function isAbort(v) {
return v instanceof DOMException && (v.name === "AbortError" || v.code === v.ABORT_ERR);
}
function isSecurityError(v) {
return v instanceof DOMException && (v.name === "SecurityError" || v.code === v.SECURITY_ERR);
}
function isMIMEType(v) {
return v === "audio/*" || v === "video/*" || v === "image/*" || v === "text/*" || /\w+\/[-+.\w]+/g.test(v);
}
function isExt(v) {
return /^.*\.[\w]+$/.test(v);
}
exports.ErrorCode = ErrorCode;
exports.FILE_INVALID_TYPE = FILE_INVALID_TYPE;
exports.FILE_TOO_LARGE = FILE_TOO_LARGE;
exports.FILE_TOO_SMALL = FILE_TOO_SMALL;
exports.TOO_MANY_FILES = TOO_MANY_FILES;
exports.TOO_MANY_FILES_REJECTION = TOO_MANY_FILES_REJECTION;
exports.acceptPropAsAcceptAttr = acceptPropAsAcceptAttr;
exports.allFilesAccepted = allFilesAccepted;
exports.canUseFileSystemAccessAPI = canUseFileSystemAccessAPI;
exports.composeEventHandlers = composeEventHandlers;
exports.fileAccepted = fileAccepted;
exports.fileMatchSize = fileMatchSize;
exports.getInvalidTypeRejectionErr = getInvalidTypeRejectionErr;
exports.getTooLargeRejectionErr = getTooLargeRejectionErr;
exports.getTooSmallRejectionErr = getTooSmallRejectionErr;
exports.isAbort = isAbort;
exports.isEvtWithFiles = isEvtWithFiles;
exports.isExt = isExt;
exports.isIeOrEdge = isIeOrEdge;
exports.isMIMEType = isMIMEType;
exports.isPropagationStopped = isPropagationStopped;
exports.isSecurityError = isSecurityError;
exports.onDocumentDragOver = onDocumentDragOver;
exports.pickerOptionsFromAccept = pickerOptionsFromAccept;

4

package.json
{
"name": "react-dropzone-esm",
"description": "Simple HTML5 drag-drop zone with React.js",
"version": "15.0.0",
"version": "15.0.1",
"types": "./types/react-dropzone.d.ts",

@@ -57,4 +57,2 @@ "main": "./dist/cjs/index.js",

"dependencies": {
"attr-accept": "^2.2.2",
"file-selector": "^0.6.0",
"prop-types": "^15.8.1"

@@ -61,0 +59,0 @@ },

@@ -10,2 +10,16 @@ # react-dropzone-esm

## Installation
With yarn:
```bash
yarn add react-dropzone-esm
```
With npm:
```bash
npm install react-dropzone-esm
```
## Differences from react-dropzone

@@ -12,0 +26,0 @@

import * as React from "react";
export { FileWithPath } from "file-selector";
export interface FileWithPath extends File {
readonly path?: string;
}
export default function Dropzone(

@@ -5,0 +8,0 @@ props: DropzoneProps & React.RefAttributes<DropzoneRef>

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc