import React, { useEffect, useMemo, useState } from 'react' function toImageFiles(files) { return Array.from(files || []).filter((file) => String(file.type || '').startsWith('image/')) } export default function ScreenshotUploader({ files = [], onChange, min = 1, max = 5, required = false, error = '', }) { const [dragging, setDragging] = useState(false) const previews = useMemo( () => files.map((file) => ({ file, url: window.URL.createObjectURL(file) })), [files] ) useEffect(() => { return () => { previews.forEach((preview) => window.URL.revokeObjectURL(preview.url)) } }, [previews]) const mergeFiles = (incomingFiles) => { const next = [...files, ...toImageFiles(incomingFiles)].slice(0, max) if (typeof onChange === 'function') { onChange(next) } } const replaceFiles = (incomingFiles) => { const next = toImageFiles(incomingFiles).slice(0, max) if (typeof onChange === 'function') { onChange(next) } } const removeAt = (index) => { const next = files.filter((_, idx) => idx !== index) if (typeof onChange === 'function') { onChange(next) } } const move = (from, to) => { if (to < 0 || to >= files.length) return const next = [...files] const [picked] = next.splice(from, 1) next.splice(to, 0, picked) if (typeof onChange === 'function') { onChange(next) } } return (
{ event.preventDefault() setDragging(false) mergeFiles(event.dataTransfer?.files) }} onDragOver={(event) => { event.preventDefault() setDragging(true) }} onDragLeave={() => setDragging(false)} className={`rounded-xl border-2 border-dashed p-3 text-center text-xs transition ${dragging ? 'border-sky-300 bg-sky-500/10' : 'border-white/20 bg-white/5'}`} >

Drag & drop screenshots here

Minimum {min}, maximum {max}

replaceFiles(event.target.files)} /> {error ?

{error}

: null} {previews.length > 0 ? ( ) : null}
) }