File Upload Drag & Drop
blocks/file-upload-04FreeBlock
A file upload drag & drop block.
Install it
npx shadcn@latest add https://blocks.so/r/file-upload-04.jsonSource
1'use client';23import { File, FileSpreadsheet, X } from 'lucide-react';4import { type ChangeEvent, type DragEvent, useRef, useState } from 'react';5import { toast } from 'sonner';67import { Button } from '@/components/ui/button';8import { Card } from '@/components/ui/card';9import { Progress } from '@/components/ui/progress';1011export default function FileUpload04() {12 const [uploadState, setUploadState] = useState<{13 file: File | null;14 progress: number;15 uploading: boolean;16 }>({17 file: null,18 progress: 0,19 uploading: false,20 });21 const [showDummy, setShowDummy] = useState(true);22 const fileInputRef = useRef<HTMLInputElement>(null);2324 const validFileTypes = [25 'text/csv',26 'application/vnd.ms-excel',27 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',28 ];2930 const handleFile = (file: File | undefined) => {31 if (!file) return;3233 if (validFileTypes.includes(file.type)) {34 setUploadState({ file, progress: 0, uploading: true });3536 const interval = setInterval(() => {37 setUploadState((prev) => {38 const newProgress = prev.progress + 5;39 if (newProgress >= 100) {40 clearInterval(interval);41 return { ...prev, progress: 100, uploading: false };42 }43 return { ...prev, progress: newProgress };44 });45 }, 200);46 } else {47 toast.error('Please upload a CSV, XLSX, or XLS file.', {48 position: 'bottom-right',49 duration: 3000,50 });51 }52 };5354 const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {55 handleFile(event.target.files?.[0]);56 };5758 const handleDrop = (event: DragEvent<HTMLDivElement>) => {59 event.preventDefault();60 handleFile(event.dataTransfer.files?.[0]);61 };6263 const resetFile = () => {64 setUploadState({ file: null, progress: 0, uploading: false });65 if (fileInputRef.current) {66 fileInputRef.current.value = '';67 }68 };6970 const getFileIcon = () => {71 if (!uploadState.file) return <File />;7273 const fileExt = uploadState.file.name.split('.').pop()?.toLowerCase() || '';74 return ['csv', 'xlsx', 'xls'].includes(fileExt) ? (75 <FileSpreadsheet className="h-5 w-5 text-foreground" />76 ) : (77 <File className="h-5 w-5 text-foreground" />78 );79 };8081 const formatFileSize = (bytes: number) => {82 if (bytes === 0) return '0 Bytes';83 const k = 1024;84 const sizes = ['Bytes', 'KB', 'MB', 'GB'];85// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from blocks
All 76 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| AI Chat with Voice Inputai-01 | blocks | Blocks | Free | 1 dep | |
| AI Chat with Model Selectionai-02 | blocks | Blocks | Free | 1 dep | |
| AI Chat Compact Interfaceai-03 | blocks | Blocks | Free | 1 dep | |
| AI Chat with File Attachmentsai-04 | blocks | Blocks | Free | 1 dep | |
| AI Elements Chatai-05 | blocks | Blocks | Free | 2 deps | |
| Command Menu with Groupscommand-menu-01 | blocks | Blocks | Free | 1 dep | |
| Command Menu with Keyboard Shortcutscommand-menu-02 | blocks | Blocks | Free | 1 dep | |
| Command Menu with Documentation Searchcommand-menu-03 | blocks | Blocks | Free | 1 dep |
