sarink / react-file-drop Goto Github PK
View Code? Open in Web Editor NEWReact component for Gmail or Facebook -like drag and drop file uploader
Home Page: https://www.sarink.net
React component for Gmail or Facebook -like drag and drop file uploader
Home Page: https://www.sarink.net
I have a DropzoneJs component on a page on which you can click and choose some files for upload
Also I have wrapped page with react-file-drop. When I drag files over the page, some elements listen to mouse events, and if I drag files over DropzoneJs and then move mouse without dropping files to other part of page, react-file-drop will stop adding class .file-drop-dragging-over-target
This is just a nice to have, but it would be great if we can passthough an onClick
callback (and perhaps other common react props) to the inner
Hey guys, I am working on a v2 of this library which will fix all issues, and work with the latest React. Please stay tuned the next couple of weeks!
Until then, happy to accept PRs that would contain a temporary fix for any problems (maybe through a flag or some option, as to not break backwards compatibility)
Thanks!
Hello, I am implementing a file dropper that has conditional rendering depending on if the dropper is being currently being dragged-over. It's not just styling changes, but the components rendered under a drag are different.
There is one state where the user drags a file onto the frame (which is the entire document), and another when the drop zone is being dragged over.
Because there appears to be no onEnter prop to use for the drop zone, I am trying to make the switch using onDragOver, which appears to be working fine. The issue is that I need to detect when the user has dragged out of the drop zone and back into a different part of the frame, and respond to that. From my understanding I should be using the onLeave event to handle this, and change the state then. However as I drag over the drop zone, onLeave fire sporadically alongside the onDragOver event. These two events setting opposite states is making the drop zone flash rapidly between the two states and appears really buggy.
I was wondering if there is an issue with the onLeave event, which I suspect would have to do with children elements and event bubbling, and if there is something I can do to get around this issue.
Thank you.
First: nice module I found it useful for using whole document as target without changing the style of the app.
The problem I found is, as you can try it in your demo, if you drag and drop a file with extension app
(I use mac) the size is reported as 96.
Regards,
Adrian
In typescript I'm getting this message -> "import FileDrop, JSX element type 'FileDrop' does not have any construct or call signatures.ts(2604)." Which seems very odd. I haven't looked through your source code yet. But I suspect the issue lies somewhere in the way you are overloading the FileDrop.
Hi,
I try to create a test with enzyme for rendering a component using FileDrop.
import { shallow } from 'enzyme'
import expect from 'expect'
import React from 'react'
import SomeInput from './SomeInput.jsx'
describe('Component: SomeInput', () => {
it('should render self and subcomponents', () => {
const wrapper = shallow(<SomeInput />)
expect(wrapper.props().className).toBe('someInput')
expect(wrapper.find(<textarea />).length).toBe(1)
})
})
I got:
Test suite failed to run
ReferenceError: document is not defined
at
import FileDrop from 'react-file-drop'
at Function.getDefaultProps (node_modules/react-file-drop/FileDrop.js:44:24)
at createClass (node_modules/create-react-class/factory.js:869:46)
at node_modules/react-file-drop/FileDrop.js:18:20
at Object.<anonymous>.createReactClass.displayName (node_modules/react-file-drop/FileDrop.js:6:26)
at Object.<anonymous> (node_modules/react-file-drop/FileDrop.js:16:2)
at Object.<anonymous> (src/components/chat/someInput/someInput.jsx:8:22)
there at line 44 is the frame...
getDefaultProps: function () {
return {
dropEffect: "copy",
frame: document,
targetAlwaysVisible: false
};
},
can you please have that document be an empty object if no global document exists, or any solution because I really do not want to use jDom.
It doesn't work in both my current app and in the demo http://sarink.github.io/react-file-drop/demo/
Here is the code from FileDrop.js
_handleDragOver: function (event) {
event.preventDefault();
event.stopPropagation();
event.dataTransfer.dropEffect = this.props.dropEffect;
// set active drag state only when file is dragged into
// (in mozilla when file is dragged effect is "uninitialized")
var effectAllowed = event.dataTransfer.effectAllowed;
if (effectAllowed === "all" || effectAllowed === "uninitialized") {
this.setState({draggingOverTarget: true});
}
if (this.props.onDragOver) this.props.onDragOver(event);
}
To me it looks like the problem is that condition effectAllowed === "all" || effectAllowed === "uninitialized"
is never true because effectsAllowed === "copy" in Chrome on Linux.
I could be wrong, I haven't tested it very carefully, but to me this looks like the cause of the issue.
IE has a bug: https://stackoverflow.com/questions/40680879/dragleave-is-not-firing-in-ie
See for example https://jsfiddle.net/1m0gbL4d/4/
Due to this bug library does not work correctly in IE. If you begin dragging file, and then move file away - drag state preserves, frameDragCounter still more the zero, and next drag does not begin.
I have made hotfix in local copy of library installation:
This fix not ideal - it only cover case, when you cancel drag, then move a mouse over page, then begin another drag. Do not know, how to fix whole case.
Hi,
We use Jest for our unit testing. When I try to test a component which imports react-file-drop, Jest throws an error coming from /node_modules/react-file-drop/dist/FileDrop/FileDrop.js:11
:
import PropTypes from 'prop-types';
^^^^^^
SyntaxError: Unexpected token import
I've tried installing proptypes with npm, but to no avail. Is there any way to fix or circumvent this?
P.s. I don't know if it has anything to do with it, but we use Typescript for type checking in our application.
I'm just logging out the triggered function's parameter... happens six times.
Hello!!
I using react-file-drop in next 12, but I don't know why the console is returning this warning.
This is my custom component
import { Box, CircularProgress, Typography } from '@mui/material'
import { useRef } from 'react'
import { FileDrop } from 'react-file-drop'
import UploadFileIcon from '@mui/icons-material/UploadFile'
export interface DragAndDropInterface {
handleOnChangeFiles(e: FileList): void
loading: boolean
}
export const DragAndDrop = ({
handleOnChangeFiles,
loading,
}: DragAndDropInterface) => {
const fileInputRef: any = useRef(null)
const onTargetClick = () => {
if (!loading) {
fileInputRef.current.click()
}
}
const onFileInputChange = (event: { target: HTMLInputElement }) => {
const { files } = event.target
onChangeFile(files)
}
const onChangeFile = async (files: FileList[] | any) => {
if (files) {
handleOnChangeFiles(files)
}
}
return (
<Box className={loading ? 'loading' : ''} height="100%" width="100%">
<FileDrop
onTargetClick={onTargetClick}
onDrop={(files) => onChangeFile(files)}
>
{loading ? (
<>
<CircularProgress />
<Typography variant="subtitle2" mt="0.62rem">
Loading...
</Typography>
</>
) : (
<>
<UploadFileIcon
sx={{ fontSize: '2.62rem', color: 'primary.dark' }}
/>
<Typography variant="subtitle2" mt="0.62rem">
Choose or drop your file here
</Typography>
<input type="file" hidden />
<input
onChange={onFileInputChange}
ref={fileInputRef}
type="file"
hidden
/>
</>
)}
</FileDrop>
</Box>
)
}
Warning: Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://reactjs.org/link/unsafe-component-lifecycles for details.
Please update the following components: FileDrop
see: https://fb.me/react-legacyfactory
I get this warning using react-file-drop
with [email protected]
I guess that using react.createClass
is deprecated..
Using react-scripts 5.0.0 to bundle a JavaScript project and getting the following error:
WARNING in ./node_modules/react-file-drop/FileDrop.js
Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from '<full path>/node_modules/src/FileDrop.tsx' file: Error: ENOENT: no such file or directory, open '<full path>/node_modules/src/FileDrop.tsx'
Seems like it's caused by these changes v3.0.1...v3.0.3
Similar problems have been happening with other packages facebook/create-react-app#11767
I get the list of file objects when they are dropped. when a folder (contains multiple) is dropped, I get only one single file object(which is the folder) from the onDrop event . Is there any way to get the list of file objects from the event?.
This is a feature suggestion.
What do you think about broadening the library so that it also allows dropping images or text directly? ie allow an image to be dragged from another app without having to save it as a file first. It seems this would only add a small amount of code.
I have this error when using concurrent mode in React. It works fine btw! :)
A handful projects nowadays are making their css classes unique to avoid conflicts if their project is used in another bigger project.
Using the css-loader localIdentName is one way to solve that problem for an entire project that imports SCSS files. The classes for react-file-drop are hard coded into the module. If I were to define '.fileDrop', the css-loader might be configured to change the name to '.fileDrop_a24f2' for example. react-file-drop will not recognize this class and ignore it.
If there were props for supplying custom classnames like:
targetClassName
draggingOverFrameClassName
draggingOverTargetClassName
That would solve this problem.
What do you think?
I can create a PR if you would like.
Warning: componentWillReceiveProps has been renamed, and is not recommended for use.
Please update the following components: FileDrop
printWarning @ react-dom.development.js:88
warn @ react-dom.development.js:51
push../node_modules/react-dom/cjs/react-dom.development.js.ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings @ react-dom.development.js:11377
flushRenderPhaseStrictModeWarningsInDEV @ react-dom.development.js:23112
commitRootImpl @ react-dom.development.js:22396
unstable_runWithPriority @ scheduler.development.js:653
runWithPriority$1 @ react-dom.development.js:11039
commitRoot @ react-dom.development.js:22381
finishSyncRender @ react-dom.development.js:21807
performSyncWorkOnRoot @ react-dom.development.js:21793
(anonymous) @ react-dom.development.js:11089
unstable_runWithPriority @ scheduler.development.js:653
runWithPriority$1 @ react-dom.development.js:11039
flushSyncCallbackQueueImpl @ react-dom.development.js:11084
workLoop @ scheduler.development.js:597
flushWork @ scheduler.development.js:552
performWorkUntilDeadline @ scheduler.development.js:164
Seems like there's some issue about the drag leave event handling.
I think there is a problem here, causing a drag observer not to be removed when the component unmoungts. Seems like it might have been accidental?
pr: #64
I want the drop frame to only be visible if the user drags a file.
I tried adding return false
to onDragOver
and to onFrameDragEnter
in case event.dragTransfer.types.indexOf('Files') === (-1)
but the return value is ignored so there's no way to stop the drop zone from showing up.
This is how my code looks like:
_handleFileDrop(files, event) {
console.log(files, event);
}
render() {
return (
<div className="content">
<FileDrop frame={document} onDrop={this._handleFileDrop}>Drop some files here!</FileDrop>
</div>
);
}
css: (css from your example is not working as well)
.file-drop {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 0;
}
.file-drop > .file-drop-target {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
border-radius: 2px;
transition: all 150ms linear;
opacity: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
align-content: center;
text-align: center;
}
.file-drop > .file-drop-target.file-drop-dragging-over-frame {
border: 5px dashed #ccc;
background-color: rgba(255, 255, 255, .2);
box-shadow: none;
z-index: 50;
opacity: 1;
}
onDrop
callback is never called even that I see the proper styling (but file-drop-dragging-over-frameclass is not added) when hovering the file over document.
I suspect its probably because it things that files was not dropped over file-drop-target
however Im not sure why as it fills the 100% of its parent.
React 0.14.3
This component is exactly what I need. But most of these components you can see online still have normal button to upload a file instead of only drag and drop. I don't see a way to do this with this component. Or are we supposed to just add another file element with the file dropper if we want this behaviour?
The workflow ci.yml is referencing action actions/checkout using references v1. However this reference is missing the commit a6747255bd19d7a757dbdda8c654a9f84db19839 which may contain fix to the some vulnerability.
The vulnerability fix that is missing by actions version could be related to:
(1) CVE fix
(2) upgrade of vulnerable dependency
(3) fix to secret leak and others.
Please consider to update the reference to the action.
I followed proper installation guides but receive this warning in console:
index.js:1
Warning: Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://reactjs.org/link/unsafe-component-lifecycles for details.
Please update the following components: FileDrop
This is my code:
<FileDrop onDrop={processDroppedFiles} onTargetClick={onTargetClick} className="kpFilesDrag position-relative p-5 rounded-3"/>
How do I fix it?
Hello I am trying to use the "frame" prop without any success.
Frame must be of the type HTMLDocument but how can I generate an HTMLDocument inside render()? I was going to use document.getElementById, but I quickly realized that isn't an option since the HTML isn't yet rendered on the page in the render() function. So how can I create an HTMLElement inside the render function itself?
Could you please provide an example
Considering you already use TS it seems obsolete to me.
The main value proposition of your lib IMO is that it has fewer dependencies and a smaller bundle size compared to react-dropzone
.
Removing all dependencies and reducing the bundle size further will sweeten the deal even further.
So I'm trying to prerender my react component server side and whenever I do so I receive this error.
document is not defined.
getDefaultProps: function () { return { dropEffect: "copy", frame: document, targetAlwaysVisible: false }; }
Has any thought been given as to how to make this component work when rendered server side? I thought it would be as easy as changing getDefaultProps so it doesn't reference document but that just pushes the error to propTypes and then to startFrameListeners and so on.
I was trying to use this library in a create-react-app application using the Typescript scripts. However, When I insert the component as such:
<FileDrop onDrop={this.handleDrop}> <div className="file-drop-target"> Drop the file you would like to upload here </div> </FileDrop>
I get the following error:
JSX element class does not support attributes because it does not have a 'props' property.ts(2607) (JSX attribute) onDrop: (files: any, event: any) => void
Hi,
Dropping folders onto the dropzone doesn't work (and that's fine by me). However, to avoid the whole page from breaking, I'd like to be able to handle this somehow. I've looked into the file
and event
objects, but couldn't find anything that indicates whether the thing that was dropped is a folder or (a) file(s).
Default file events from <input type="file"/>
elements have the properties isDirectory: true/false
and isFile: true/false
. Could you add this to the events of the dropped items? That would be really useful and appreciated :)
Great library otherwise!!
This is a great little library but we can't use it because for some reason FileDrop.js contains what looks like ES6 code, even though the target is set to ES5:
https://github.com/sarink/react-file-drop/blob/master/dist/FileDrop/FileDrop.js#L11
This means that it won't compile for Jest Storybook tests.
is there any method to make the whole page dropable.
no example containing frame as HTMLElement
The plugin works great. I tried to figure it out how to detect one time only event when I drag files and your solution with counting dragenters was the best.
Just tell me if you would like me to write couple tests in this repo!
Cheers.
Hi,
this is about the closed one ->
if you drag and drop a file with extension app
(at least on mac) the size is reported as 96
:
I tested it with this component: react-dropzone and there it works with app type files, shows the good
size, but even your demo: http://sarink.github.io/react-file-drop/dist/Demo/,
i you tested on mac and chrome and it shows 96, but please don't change the extension because
somehow that is not giving the same result...
I used iTerm.app as file to drag and drop: here
Since my project is limited to react 15, I was wondering why the older versions are not on this repository anymore? I was assuming that there were running versions of react-file-drop before the release of react 16.
Is there a way to use the older versions with react 15 dependecies?
This lib seems to have a peer dependency on React 16, which with the current version, doesn't fly with the newest React:
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR! react@"17.0.2" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.13.1" from [email protected]
npm ERR! node_modules/react-file-drop
npm ERR! react-file-drop@"3.1.2" from the root project
Is the library still updated, and if so, are there any plans to support React 17?
Building reactjs app. However after including react-file-drop library, getting the below error for yarn test (jest framework). However yarn build, start etc works good and no issues found in runtime.
Error:
/web/node_modules/react-
file-drop/dist/FileDrop/FileDrop.js:23
import React from 'react'
^^^^^^
SyntaxError: Unexpected token import
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/ScriptTransformer.js:289:17)
This is my Package.json (removed few entries not relevant to this)
{
"name": "xxxxxxxx",
"version": "0.1.0",
"private": true,
"dependencies": {
"@types/react": "^16.4.4",
"prop-types": "^15.6.2",
"react": "^16.4.1",
"react-file-drop": "^0.2.6",
"react-scripts": "1.1.4",
"webpack": "^3.12.0"
},
"scripts": {
"test": "react-scripts test --env=jsdom",
},
"jest": {
"coverageReporters": [
"json",
"text",
"lcov",
"cobertura"
]
}
}
Please look at the line below
Line 108 in 24f306c
_handleDrop
handler gets fired two times when dropping to target:
onDrop
event gets fired on div.file-drop
element, so its handler _handleDrop
is called_handleFrameDrop
gets fired on frames' drop
event (Line 170 in 24f306c
_handleDrop
once again.And this _handleDrop
handler invokes this.props.onDrop
handler which usually uploads files to the server, so any file gets uploaded to the backend 2 times.
The general idea is: you should not call a drop-to-target
handler when drop to a frame-not-target
is performed. I think removing line
Line 108 in 24f306c
_handleFrameDrop
(up to my opinion) represents the drop to a frame-not-target
area, especially if (!this.state.draggingOverTarget)
part. I think there shouldn't be else
branch (or code except inside this if
statement) because it may lead to the situations like I described.
So as a workaround I will stick to version 0.1.8
until it is fixed.
P.S. I understand that you've made this change because of #17. I don't know the use case behind this PR, but I assume that the solution should be other than this one.
<FileDrop
onDrop={(files, event) => console.log('DropEd on Main Folder!', files, event)}
>
{files.map((f, i) => (
<Row key={i} >
<Col span={12} >
{f.isDir ?
<span style={stylesDir}>
<FileDrop onDrop={(files, event) => console.log(`DropEd on child Folder ${f.name}`, files, event)}>
{f.name}
</FileDrop>
</span>
: f.name}
</Col>
<Col span={12} >
{f.size}
</Col>
</Row>
))}
</FileDrop>
Trying to get this to only allow csv/xlxs files and I couldn't find anything about the accept attribute in the docs. Is it supported?
This library works like a charm Kabir, thanks for sharing!
I noticed one React deprecation warning when using the library:
Warning: componentWillReceiveProps has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details.
* Move data fetching code or side effects to componentDidUpdate.
* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state
* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.
Please update the following components: FileDrop
It would be great if you can update the library not to use this deprecated method anymore. If needed I may be able to create a PR for this.
When the FileDrop
component has many children, dragging a file between the children causes it to rapidly flash between having the file-drop-dragging-over-target
class, and not having that class. When CSS styling for the two states are very different (say, the colors are inverted), this results in a visible "flicker" in some browsers (such as Debian 10/Chromium).
Example setup:
<FileDrop
onDragLeave={() => console.log("foobar")}
>
<label
for={id}
>
<SomeIcon />
<div>
<div>Some Title</div>
<div>Some file name display</div>
</div>
</label>
<input
id={id}
type={"file"}
/>
</FileDrop>
If you run a dragged file within the FileDrop, but in between different children, you can see foobar
being logged repeatedly to console. You could also flesh out this example with contrasting styles to see the visual flicker.
(Incidentally, I believe this is the root cause of #60.)
This appears to be due to this code:
handleDragLeave: ReactDragEventHandler<HTMLDivElement> = (event) => {
this.setState({ draggingOverTarget: false });
if (this.props.onDragLeave) this.props.onDragLeave(event);
};
This will fire whenever a dragLeave
event bubbles up from children of FileDrop
. Of course, the corresponding dragEnter
event bubbles up shortly afterward, but this brief period of draggingOverTarget: false
state causes a visual flicker.
Attempts to mitigate this by putting event.stopPropagation();
on children seem to break part of the state, resulting in the possibility of leaving the FileDrop
stuck in a state where it thinks the file is still being dragged over the target or the frame, even after it's not.
The best way I've found to mitigate this problem is to have my CSS run a transition animation between states so that the flicker doesn't show as much.
It would be nice if FileDrop didn't flicker due to bubbling DragLeave events. Currently, by my testing, this affects Debian 10/Chromium, but not Debian 10/Firefox. I haven't been able to test it on other mainstream browsers.
This component looks really promising, but I'm unable to get a working version.
https://jsfiddle.net/westhomas/rr1xbapc/7/
I'm using the component from this file in my fiddle: https://sarink.github.io/react-file-drop/FileDrop.js
Hello, if a client drop a js file this stop my server in nodejs, how i can filter this? Using this library?
thanks for the Component, it does a good job!
In the "Styling" section is the link to the Demo Css not working, just wanted to let you know
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.