Skip to content
react-mediadrop
Esc
navigateopen⌘Jpreview

Drag states

Every drag flag useMediaDrop returns, read live off one dropzone.

useMediaDrop returns five drag/focus flags. Drag an image over the zone below to watch them flip live.

isDragActiveisDragAcceptisDragRejectisFocusedisDragGlobal
TSX
import { useMediaDrop } from "react-mediadrop";

export function DragStatesExample() {
	const {
		acceptedFiles,
		getRootProps,
		getInputProps,
		isDragActive,
		isDragAccept,
		isDragReject,
		isFocused,
		isDragGlobal,
	} = useMediaDrop({ restrictions: { accept: ["image/*"] } });

	return (
		<div className="w-full space-y-3">
			<div
				{...getRootProps()}
				className={`cursor-pointer rounded-lg border-2 border-dashed px-6 py-10 text-center
          border-zinc-300 dark:border-zinc-700
          ${isDragAccept ? "border-green-500" : ""}
          ${isDragReject ? "border-red-500" : ""}
          ${isDragActive && !isDragAccept && !isDragReject ? "border-sky-500" : ""}`}
			>
				<input {...getInputProps()} />
				<p>Drag an image here, or click to browse</p>
			</div>

			<div className="flex flex-wrap gap-2 text-xs">
				<span>isDragActive: {String(isDragActive)}</span>
				<span>isDragAccept: {String(isDragAccept)}</span>
				<span>isDragReject: {String(isDragReject)}</span>
				<span>isFocused: {String(isFocused)}</span>
				<span>isDragGlobal: {String(isDragGlobal)}</span>
			</div>

			<ul className="m-0 w-full list-none space-y-2 p-0">
				{acceptedFiles.map((file) => (
					<li key={file.id}>
						{file.name}{file.size.toLocaleString()} bytes
					</li>
				))}
			</ul>
		</div>
	);
}

isDragAccept/isDragReject are best-effort — browsers only expose a dragged file’s MIME type, not its name, until drop. An extension-based accept (like .png) can’t be evaluated mid-drag, so use MIME types (image/*) if you want this preview to work. isDragGlobal tracks drags anywhere on the document, not just this dropzone’s root. See Core concepts.

Last updated on September 5, 2026

Was this page helpful?