File Upload
ファイルアップロード
A single-file drop target that carries its own state: validation, progress and the error message. The whole of the drag and drop API↗↗ is wired by hand, which means dealing with the one thing it gets wrong — dragleave↗↗ also fires when the pointer crosses onto a child element, so the target flickers back to idle while the file is still over it. A depth counter incremented on enter and decremented on leave decides when the pointer has genuinely left. Clicking is a real file input, only visually hidden, with the button as its label — so it opens from the keyboard and takes a focus ring. Where Dropzone↗↗ wraps react-dropzone and hands the state back to you as slots, this is one self-contained file that owns the state itself. The progress bar is a stand-in: swap the interval for the events of whatever actually moves the bytes. Adapted from Kokonut UI↗↗ under the MIT licence.
Drag and drop a file
PNG, JPEG, PDF up to 2 MB
Installation
Install the following dependencies:1
npm install framer-motionnpm install lucide-reactCopy and paste the following code into a new component file:2
How to use it3
Props
FileUpload
| Name | Default | Description |
|---|---|---|
| accept | [] | string[] Accepted MIME types, wildcards allowed; empty accepts anything |
| maxSize | 5242880 | number Largest accepted file in bytes |
| uploadDelay | 2000 | number Milliseconds the simulated transfer takes; 0 completes at once |
| validate | — | (file: File) => string | null Extra check; return a message to reject the file |
| onSelect | — | (file: File) => void Called once a file has passed validation |
| onComplete | — | (file: File) => void Called when the transfer reaches 100% |
| onError | — | (error: FileUploadError) => void Called with the code and message of a rejection |
| onRemove | — | () => void Called when the file is cancelled or removed |
| dark | false | boolean Render the dark palette |