All hooks / Events and input
useFileDrop
Turns an element into a drop zone for files, and reports when files are dragged over it.
isOver does not flicker when the pointer moves over child elements (it counts enter/leave pairs). Only reacts to drags that carry files, so dragging text or links inside the page is unaffected. Prevents the browser from opening a file dropped on the zone. Returns a callback ref for the element.
Import
import { useFileDrop } from '@vincent.ri/react-tils'
// or only this hook
import { useFileDrop } from '@vincent.ri/react-tils/useFileDrop'Usage
const [ref, isOver] = useFileDrop((files) => upload(files.filter((f) => f.type.startsWith('image/'))))
return (
<div ref={ref} className={isOver ? 'zone active' : 'zone'}>
Drop images here, or <input type="file" accept="image/*" multiple onChange={(e) => upload([...e.target.files!])} />
</div>
)Live demo
Drag files from your desktop onto the box.
When to use it
An upload area, an "import file" panel, or dropping images into an editor.
When not to
A plain <input type="file"> is enough; keep one anyway as the keyboard and screen-reader accessible way to pick files. Filter file types and sizes in onDrop; the browser doesn't.
API
function useFileDrop<T extends HTMLElement = HTMLElement>(onDrop: (files: File[], event: DragEvent) => void, options?: {
enabled?: boolean;
}): [(element: T | null) => void, boolean]| Parameter | Description |
|---|---|
onDrop | Called with the dropped files. Can change every render. |
options | enabled: accept drops while true. Default true. |
Returns [ref, isOver]. Pass ref to the drop zone's ref prop.
Browser support
| Uses | Chrome | Edge | Firefox | Safari | Chrome Android | Safari iOS |
|---|---|---|---|---|---|---|
| Drag and drop filesWidely available | 3+ | 12+ | 3.6+ | 4+ | 18+ | 3.2+ |
First version with support, from MDN's compatibility data (web-features 3.42.0, @mdn/browser-compat-data 8.1.5).