import { ArrowCircleDownIcon } from "@heroicons/react/outline"; import { useCallback, useRef } from "react"; import { useDropzone } from "react-dropzone"; import { Form, useSubmit } from "remix"; import invariant from "tiny-invariant"; export function DragAndDropForm() { const formRef = useRef(null); const filenameInputRef = useRef(null); const rawJsonInputRef = useRef(null); const submit = useSubmit(); const onDrop = useCallback( (acceptedFiles: Array) => { if (!formRef.current || !filenameInputRef.current) { return; } if (acceptedFiles.length === 0) { return; } const firstFile = acceptedFiles[0]; const reader = new FileReader(); reader.onabort = () => console.log("file reading was aborted"); reader.onerror = () => console.log("file reading has failed"); reader.onload = () => { if (reader.result == null) { return; } let jsonValue: string | undefined = undefined; if (typeof reader.result === "string") { jsonValue = reader.result; } else { const decoder = new TextDecoder("utf-8"); jsonValue = decoder.decode(reader.result); } invariant(rawJsonInputRef.current, "rawJsonInputRef is null"); invariant(jsonValue, "jsonValue is undefined"); rawJsonInputRef.current.value = jsonValue; submit(formRef.current); }; reader.readAsArrayBuffer(firstFile); filenameInputRef.current.value = firstFile.name; }, [formRef.current, filenameInputRef.current, rawJsonInputRef.current] ); const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDropAccepted: onDrop, maxFiles: 1, maxSize: 1024 * 1024 * 1, multiple: false, accept: "application/json", }); return (

{isDragActive ? "现在释放以打开…" : "在此处拖放 JSON 文件,或点击选择"}

); }