{
  "name": "file-upload-direct-upload-demo",
  "type": "registry:example",
  "dependencies": [
    "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\";\n\nimport { Button } from \"@/registry/bases/radix/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/radix/ui/file-upload\";\n\nexport default function FileUploadDirectUploadDemo() {\n  const [files, setFiles] = React.useState<File[]>([]);\n\n  const onUpload: NonNullable<FileUploadProps[\"onUpload\"]> = 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    <FileUpload\n      value={files}\n      onValueChange={setFiles}\n      onUpload={onUpload}\n      onFileReject={onFileReject}\n      maxFiles={2}\n      className=\"w-full max-w-md\"\n      multiple\n    >\n      <FileUploadDropzone>\n        <div className=\"flex flex-col items-center gap-1 text-center\">\n          <div className=\"flex items-center justify-center rounded-full border p-2.5\">\n            <Upload className=\"size-6 text-muted-foreground\" />\n          </div>\n          <p className=\"text-sm font-medium\">Drag & drop files here</p>\n          <p className=\"text-xs text-muted-foreground\">\n            Or click to browse (max 2 files)\n          </p>\n        </div>\n        <FileUploadTrigger asChild>\n          <Button variant=\"outline\" size=\"sm\" className=\"mt-2 w-fit\">\n            Browse files\n          </Button>\n        </FileUploadTrigger>\n      </FileUploadDropzone>\n      <FileUploadList>\n        {files.map((file, index) => (\n          <FileUploadItem key={index} value={file} className=\"flex-col\">\n            <div className=\"flex w-full items-center gap-2\">\n              <FileUploadItemPreview />\n              <FileUploadItemMetadata />\n              <FileUploadItemDelete asChild>\n                <Button variant=\"ghost\" size=\"icon\" className=\"size-7\">\n                  <X />\n                </Button>\n              </FileUploadItemDelete>\n            </div>\n            <FileUploadItemProgress />\n          </FileUploadItem>\n        ))}\n      </FileUploadList>\n    </FileUpload>\n  );\n}\n",
      "target": ""
    }
  ]
}