react-use icon indicating copy to clipboard operation
react-use copied to clipboard

New hook: useDragAndDrop

Open Jack-Works opened this issue 6 years ago • 2 comments

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
    }
}

Jack-Works avatar Jan 06 '20 14:01 Jack-Works

@streamich :+1:

dextermb avatar Jun 20 '20 18:06 dextermb

why can't useDragAndDrop be found?

linchen1987 avatar Dec 17 '23 02:12 linchen1987