File Upload
prompt-kit/file-uploadFreeComponent
A component for creating drag-and-drop file upload interfaces with support for single or multiple files, custom triggers, and visual feedback during file dragging operations.
Live preview
live · rendered by the registry
Rendered by prompt-kit on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://raw.githubusercontent.com/ibelick/prompt-kit/HEAD/public/c/file-upload.jsonSource
1"use client"23import { cn } from "@/lib/utils"4import {5 Children,6 cloneElement,7 createContext,8 useCallback,9 useContext,10 useEffect,11 useRef,12 useState,13} from "react"14import { createPortal } from "react-dom"1516type FileUploadContextValue = {17 isDragging: boolean18 inputRef: React.RefObject<HTMLInputElement | null>19 multiple?: boolean20 disabled?: boolean21}2223const FileUploadContext = createContext<FileUploadContextValue | null>(null)2425export type FileUploadProps = {26 onFilesAdded: (files: File[]) => void27 children: React.ReactNode28 multiple?: boolean29 accept?: string30 disabled?: boolean31}3233function FileUpload({34 onFilesAdded,35 children,36 multiple = true,37 accept,38 disabled = false,39}: FileUploadProps) {40 const inputRef = useRef<HTMLInputElement>(null)41 const [isDragging, setIsDragging] = useState(false)42 const dragCounter = useRef(0)4344 const handleFiles = useCallback(45 (files: FileList) => {46 const newFiles = Array.from(files)47 if (multiple) {48 onFilesAdded(newFiles)49 } else {50 onFilesAdded(newFiles.slice(0, 1))51 }52 },53 [multiple, onFilesAdded]54 )5556 useEffect(() => {57 const handleDrag = (e: DragEvent) => {58 e.preventDefault()59 e.stopPropagation()60 }6162 const handleDragIn = (e: DragEvent) => {63 handleDrag(e)64 dragCounter.current++65 if (e.dataTransfer?.items.length) setIsDragging(true)66 }6768 const handleDragOut = (e: DragEvent) => {69 handleDrag(e)70 dragCounter.current--71 if (dragCounter.current === 0) setIsDragging(false)72 }7374 const handleDrop = (e: DragEvent) => {75 handleDrag(e)76 setIsDragging(false)77 dragCounter.current = 078 if (e.dataTransfer?.files.length) {79 handleFiles(e.dataTransfer.files)80 }81 }8283 window.addEventListener("dragenter", handleDragIn)84 window.addEventListener("dragleave", handleDragOut)85 window.addEventListener("dragover", handleDrag)86 window.addEventListener("drop", handleDrop)8788 return () => {89 window.removeEventListener("dragenter", handleDragIn)90 window.removeEventListener("dragleave", handleDragOut)91 window.removeEventListener("dragover", handleDrag)92 window.removeEventListener("drop", handleDrop)93 }94 }, [handleFiles, onFilesAdded, multiple])9596 const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {97 if (e.target.files?.length) {98 handleFiles(e.target.files)99 e.target.value = ""100 }101 }102103 return (104// … truncated
Files it writes
More from prompt-kit
All 23 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Chain Of Thoughtchain-of-thought | prompt-kit | Components | Free | 1 dep | |
| Chat Containerchat-container | prompt-kit | Components | Free | 1 dep | |
| Code Blockcode-block | prompt-kit | Components | Free | 1 dep | |
| Feedback Barfeedback-bar | prompt-kit | Components | Free | 1 dep | |
| Imageimage | prompt-kit | Components | Free | no deps | |
| Jsx Previewjsx-preview | prompt-kit | Components | Free | 1 dep | |
| Loaderloader | prompt-kit | Components | Free | no deps | |
| Markdownmarkdown | prompt-kit | Components | Free | 5 deps · 2 files |
