Fix drag leave event over child elements
When dragging over a child element of the dropzone, a drag leave event from the dropzone is fired. This caused the handleDragLeave function to be called. Before the dragLeave event on the dropzone is fired, first a dragEnter event on the child is fired. By keeping a counter in the state, a premature dragLeave effect in the dropzone is prevented. The dragCount is kept in a local variable in handleOnDragLeave because only the render method gets the most recent state. Reading from state in a regular function will see an old value (and hence think it is still dragged over even though the counter dropped to 0).
This commit is contained in:
parent
7f4bc536b9
commit
aad91c21f6
1 changed files with 24 additions and 22 deletions
|
@ -14,6 +14,7 @@ export default function Upload(props) {
|
||||||
let fileInputRef = useRef(null);
|
let fileInputRef = useRef(null);
|
||||||
let [files, setFiles] = useState([]);
|
let [files, setFiles] = useState([]);
|
||||||
let [dragging, setDragging] = useState(false);
|
let [dragging, setDragging] = useState(false);
|
||||||
|
let [dragCount, setDragCount] = useState(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.addEventListener("dragover",function(e){
|
window.addEventListener("dragover",function(e){
|
||||||
|
@ -95,6 +96,7 @@ export default function Upload(props) {
|
||||||
|
|
||||||
setFiles([...files, ...fileListToArray(evFiles)]);
|
setFiles([...files, ...fileListToArray(evFiles)]);
|
||||||
setDragging(false);
|
setDragging(false);
|
||||||
|
setDragCount(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fileListToArray(fileList) {
|
function fileListToArray(fileList) {
|
||||||
|
@ -110,12 +112,19 @@ export default function Upload(props) {
|
||||||
|
|
||||||
function handleOnDragEnter(ev) {
|
function handleOnDragEnter(ev) {
|
||||||
stopEvent(ev);
|
stopEvent(ev);
|
||||||
setDragging(true);
|
if(dragCount === 0) setDragging(true);
|
||||||
|
|
||||||
|
setDragCount(dragCount+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleOnDragLeave(ev) {
|
function handleOnDragLeave(ev) {
|
||||||
stopEvent(ev);
|
stopEvent(ev);
|
||||||
setDragging(false);
|
let dc = dragCount;
|
||||||
|
|
||||||
|
dc -= 1;
|
||||||
|
setDragCount(dc);
|
||||||
|
|
||||||
|
if(dc === 0) setDragging(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopEvent(ev) {
|
function stopEvent(ev) {
|
||||||
|
@ -137,22 +146,15 @@ export default function Upload(props) {
|
||||||
if(dragging){
|
if(dragging){
|
||||||
return(
|
return(
|
||||||
<>
|
<>
|
||||||
<img className="dropzone-icon" alt="dropzone icon" src={drop}
|
<img className="dropzone-icon" alt="dropzone icon" src={drop} />
|
||||||
onDragLeave={stopEvent} />
|
<h5 className="text-primary">Drop now!</h5>
|
||||||
<h5 className="text-primary"
|
|
||||||
onDragLeave={stopEvent}>
|
|
||||||
Drop now!
|
|
||||||
</h5>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}else {
|
}else {
|
||||||
return(
|
return(
|
||||||
<>
|
<>
|
||||||
<img className="dropzone-icon-upload" alt="dropzone icon" src={upload}
|
<img className="dropzone-icon-upload" alt="dropzone icon" src={upload} />
|
||||||
onDragLeave={stopEvent} />
|
<h5>Click or Drop</h5>
|
||||||
<h5 onDragLeave={stopEvent}>
|
|
||||||
Click or Drop
|
|
||||||
</h5>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -162,17 +164,17 @@ export default function Upload(props) {
|
||||||
<div className="container">
|
<div className="container">
|
||||||
{logFiles()}
|
{logFiles()}
|
||||||
<div className="columns">
|
<div className="columns">
|
||||||
<div className="column col-4 col-sm-12"
|
<div className="column col-4 col-sm-12">
|
||||||
|
<div className="dropzone c-hand py-2"
|
||||||
onDrop={handleDrop}
|
onDrop={handleDrop}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
onDragOver={stopEvent}
|
onDragOver={stopEvent}
|
||||||
onDragEnter={handleOnDragEnter}
|
onDragEnter={handleOnDragEnter}
|
||||||
onDragLeave={handleOnDragLeave}>
|
onDragLeave={handleOnDragLeave}>
|
||||||
|
|
||||||
<div className="dropzone c-hand py-2" >
|
<input className="d-hide" ref={fileInputRef} type="file" multiple onChange={handleFileInputChange} />
|
||||||
<input className="d-hide" ref={fileInputRef} type="file" multiple
|
|
||||||
onDragLeave={stopEvent} onChange={handleFileInputChange} />
|
|
||||||
{zoneContent(dragging)}
|
{zoneContent(dragging)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue