{ "name": "file-upload-direct-upload-demo", "type": "registry:example", "dependencies": [ "lucide-react", "sonner" ], "registryDependencies": [ "button", "file-upload" ], "files": [ { "path": "examples/file-upload-direct-upload-demo.tsx", "type": "registry:example", "content": "\"use client\";\n\nimport { Upload, X } from \"lucide-react\";\nimport * as React from \"react\";\nimport { toast } from \"sonner\";\nimport { Button } from \"@/registry/bases/base/ui/button\";\nimport {\n FileUpload,\n FileUploadDropzone,\n FileUploadItem,\n FileUploadItemDelete,\n FileUploadItemMetadata,\n FileUploadItemPreview,\n FileUploadItemProgress,\n FileUploadList,\n type FileUploadProps,\n FileUploadTrigger,\n} from \"@/registry/bases/base/ui/file-upload\";\n\nexport default function FileUploadDirectUploadDemo() {\n const [files, setFiles] = React.useState([]);\n\n const onUpload: NonNullable = React.useCallback(\n async (files, { onProgress, onSuccess, onError }) => {\n try {\n // Process each file individually\n const uploadPromises = files.map(async (file) => {\n try {\n // Simulate file upload with progress\n const totalChunks = 10;\n let uploadedChunks = 0;\n\n // Simulate chunk upload with delays\n for (let i = 0; i < totalChunks; i++) {\n // Simulate network delay (100-300ms per chunk)\n await new Promise((resolve) =>\n setTimeout(resolve, Math.random() * 200 + 100),\n );\n\n // Update progress for this specific file\n uploadedChunks++;\n const progress = (uploadedChunks / totalChunks) * 100;\n onProgress(file, progress);\n }\n\n // Simulate server processing delay\n await new Promise((resolve) => setTimeout(resolve, 500));\n onSuccess(file);\n } catch (error) {\n onError(\n file,\n error instanceof Error ? error : new Error(\"Upload failed\"),\n );\n }\n });\n\n // Wait for all uploads to complete\n await Promise.all(uploadPromises);\n } catch (error) {\n // This handles any error that might occur outside the individual upload processes\n console.error(\"Unexpected error during upload:\", error);\n }\n },\n [],\n );\n\n const onFileReject = React.useCallback((file: File, message: string) => {\n toast(message, {\n description: `\"${file.name.length > 20 ? `${file.name.slice(0, 20)}...` : file.name}\" has been rejected`,\n });\n }, []);\n\n return (\n \n \n
\n
\n \n
\n

Drag & drop files here

\n

\n Or click to browse (max 2 files)\n

\n
\n (\n \n Browse files\n \n )}\n />\n
\n \n {files.map((file, index) => (\n \n
\n \n \n (\n \n \n \n )}\n />\n
\n \n
\n ))}\n
\n \n );\n}\n", "target": "" } ] }