80 lines
2.0 KiB
TypeScript
80 lines
2.0 KiB
TypeScript
import React from "react"
|
|
import { useState } from "react"
|
|
import { useEffect } from "react"
|
|
|
|
interface Props {
|
|
onDrop?: ()=>void
|
|
onEnter?: (event: DragEvent)=>void
|
|
onLeave?: (event: DragEvent)=>void
|
|
onDragOver?: (event: DragEvent)=>void
|
|
handleDrop?: (files: FileList)=>void
|
|
}
|
|
|
|
const DragAndDrop: React.FC<Props> = (props) => {
|
|
const dropRef = React.createRef<HTMLDivElement>()
|
|
const [hover,setHover] = useState(false)
|
|
|
|
function handleDragEnter(event: DragEvent) {
|
|
// console.debug("dragenter",event)
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
setHover(true)
|
|
props.onEnter?.(event)
|
|
}
|
|
|
|
function handleDragLeave(event: DragEvent) {
|
|
// console.debug("dragleave",event)
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
setHover(false)
|
|
props.onLeave?.(event)
|
|
}
|
|
|
|
function handleDragOver(event:DragEvent) {
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
setHover(true)
|
|
props.onDragOver?.(event)
|
|
}
|
|
|
|
function handleDrop(event: DragEvent) {
|
|
console.debug("drop",event)
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
setHover(false)
|
|
props.onDrop?.()
|
|
if (event.dataTransfer?.files && event.dataTransfer.files.length > 0) {
|
|
props.handleDrop?.(event.dataTransfer.files)
|
|
}
|
|
}
|
|
|
|
useEffect(()=>{
|
|
if(dropRef.current){
|
|
dropRef.current.addEventListener("dragenter",handleDragEnter)
|
|
dropRef.current.addEventListener("dragleave",handleDragLeave)
|
|
dropRef.current.addEventListener("dragover",handleDragOver)
|
|
dropRef.current.addEventListener("drop",handleDrop)
|
|
|
|
return ()=>{
|
|
if (dropRef.current){
|
|
dropRef.current.removeEventListener("dragenter",handleDragEnter)
|
|
dropRef.current.removeEventListener("dragleave",handleDragLeave)
|
|
dropRef.current.removeEventListener("dragover",handleDragOver)
|
|
dropRef.current.removeEventListener("drop",handleDrop)
|
|
}
|
|
}
|
|
}
|
|
},[])
|
|
|
|
return (
|
|
<div ref={dropRef}
|
|
className={`fixed top-0 left-0 w-full h-full z-10
|
|
${hover? "border-dashed border-gray-600 border-4":""}`}
|
|
>
|
|
{props.children}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default DragAndDrop
|