react-use
react-use copied to clipboard
New hook: useDragAndDrop
Happy to see this hook added to this project!
import * as React from 'react'
/**
* Usage:
* const { dragListeners, fileOnChange, dragStatus, fileRef } = useDragAndDrop()
* return <div {...dragEvents}> // Now you can drag into this div
* <input type="file" onChange={fileReceiver} /> // Also provide a way to select manually!
* { dragStatus === 'drag-enter' && 'Dragging!' } // Status of dragging
* <button onClick={upload(fileRef.current)}>Upload</button> // Get the file!
* </div>
*/
export function useDragAndDrop(onChangeOuter?: (file: File[]) => void) {
const [status, setStatus] = React.useState<undefined | 'drag-enter' | 'selected'>(undefined)
const fileRef = React.useRef<File[]>([])
const onChange = React.useCallback(
(event: React.ChangeEvent<HTMLInputElement> | React.DragEvent) => {
const files = (
(event as React.DragEvent).dataTransfer || (event as React.ChangeEvent<HTMLInputElement>).currentTarget
).files
if (!files) return
fileRef.current = Array.from(files)
if (onChangeOuter) onChangeOuter(fileRef.current)
setStatus('selected')
},
[onChangeOuter]
)
const onEnter = React.useCallback((e: React.DragEvent) => {
e.preventDefault()
setStatus('drag-enter')
}, [])
const onLeave = React.useCallback((e: React.DragEvent) => {
setStatus(undefined)
}, [])
const onCapture = React.useCallback(
(e: React.DragEvent) => {
e.preventDefault()
onChange(e)
setTimeout(onLeave, 200)
},
[onChange, onLeave]
)
return {
dragListeners: {
onDragEnterCapture: onEnter,
onDragLeaveCapture: onLeave,
onDropCapture: onCapture,
onDragOverCapture: onEnter
},
fileOnChange: onChange,
fileRef: fileRef,
dragStatus: status
}
}
@streamich :+1:
why can't useDragAndDrop be found?