cloud-drop
v0.1.1
Published
The last file uploader you'll ever need. Universal, lightweight, framework-agnostic with drag & drop, progress tracking, and React support.
Maintainers
Readme
☁️ CloudDrop
The last file uploader you'll ever need. Universal, lightweight, framework-agnostic with drag & drop, progress tracking, and React support.
🚀 Release Status
Current Version: v0.1.0 (MVP)
Status: 🚧 In Development - Month 1 MVP Phase
Next Release: v1.0.0 (Stable MVP)
✅ MVP Features Completed
- [x] Vanilla JS uploader with drag & drop
- [x] React wrapper component and hook
- [x] Progress tracking and cancel functionality
- [x] File validation (type, size)
- [x] Beautiful default UI with dark mode
- [x] TypeScript support
- [x] Optimal bundle size (< 25kb)
- [x] Example projects and documentation
🚧 Currently Working On
- [ ] npm package publication
- [ ] GitHub repository setup
- [ ] Demo site deployment
📋 Roadmap (v2.0+)
- [ ] Chunked uploads with pause/resume
- [ ] Multi-provider support (S3, GCS, R2, Firebase)
- [ ] Vue/Svelte/Angular wrappers
- [ ] Offline-first with queue & retry
- [ ] Advanced UI customization
✨ Features
- 🎯 Framework Agnostic - Works with vanilla JS and React
- 🖱️ Drag & Drop - Intuitive file selection with visual feedback
- 📊 Progress Tracking - Real-time upload progress with cancel support
- ✅ File Validation - Type and size validation out of the box
- 🎨 Customizable UI - Beautiful default UI with full customization options
- 📱 Responsive - Works great on desktop and mobile
- 🌙 Dark Mode - Automatic dark mode support
- 🚀 Lightweight - Under 25kb gzipped
- 🔧 TypeScript - Full TypeScript support
📦 Installation
npm install cloud-dropyarn add cloud-droppnpm add cloud-drop🚀 Quick Start
Vanilla JavaScript
import { createCloudDrop } from 'cloud-drop'
const uploader = createCloudDrop({
endpoint: '/api/upload',
multiple: true,
accept: ['image/*', 'application/pdf'],
maxSize: 5 * 1024 * 1024, // 5MB
}, {
onStart: (file) => console.log('Upload started:', file.name),
onProgress: (file, progress) => console.log('Progress:', progress + '%'),
onComplete: (file, url) => console.log('Upload completed:', url),
onError: (file, error) => console.error('Upload failed:', error)
})
document.getElementById('upload-zone').appendChild(uploader.element)React
import { CloudDrop } from 'cloud-drop/react'
function App() {
return (
<CloudDrop
endpoint="/api/upload"
multiple
accept={['image/*']}
maxSize={2 * 1024 * 1024}
onComplete={(file, url) => console.log('Done:', url)}
/>
)
}📚 API Reference
Core API
createCloudDrop(config, events)
Creates a new CloudDrop uploader instance.
Parameters:
config(CloudDropConfig): Configuration optionsevents(CloudDropEvents, optional): Event handlers
Returns: CloudDropInstance
CloudDropConfig
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| endpoint | string | required | Upload endpoint URL or presigned URL |
| multiple | boolean | false | Allow multiple file selection |
| accept | string[] | [] | Accepted file types (MIME types or extensions) |
| maxSize | number | undefined | Maximum file size in bytes |
| headers | Record<string, string> | {} | Custom headers for upload request |
| formData | Record<string, string \| Blob> | {} | Additional form data to send |
| showUI | boolean | true | Whether to show default UI |
| className | string | '' | Custom CSS class for the uploader element |
CloudDropEvents
| Event | Type | Description |
|-------|------|-------------|
| onStart | (file: CloudDropFile) => void | Called when upload starts |
| onProgress | (file: CloudDropFile, progress: number) => void | Called during upload progress |
| onComplete | (file: CloudDropFile, url?: string) => void | Called when upload completes |
| onError | (file: CloudDropFile, error: string) => void | Called when upload fails |
| onCancel | (file: CloudDropFile) => void | Called when upload is cancelled |
| onFilesAdded | (files: CloudDropFile[]) => void | Called when files are added |
| onFilesRemoved | (files: CloudDropFile[]) => void | Called when files are removed |
CloudDropInstance
| Method | Type | Description |
|--------|------|-------------|
| element | HTMLElement | The DOM element containing the uploader |
| files | CloudDropFile[] | Array of current files |
| addFiles(files) | (files: FileList \| File[]) => void | Manually add files |
| removeFile(fileId) | (fileId: string) => void | Remove a file |
| uploadFile(fileId) | (fileId: string) => Promise<void> | Upload a specific file |
| uploadAll() | () => Promise<void> | Upload all pending files |
| cancelUpload(fileId) | (fileId: string) => void | Cancel a specific upload |
| cancelAll() | () => void | Cancel all uploads |
| destroy() | () => void | Clean up the uploader |
React API
<CloudDrop /> Component
<CloudDrop
endpoint="/api/upload"
multiple={true}
accept={['image/*']}
maxSize={5 * 1024 * 1024}
onComplete={(file, url) => console.log('Done:', url)}
children={({ files, uploadFile, uploadAll, isUploading }) => (
<div>
{/* Custom UI */}
</div>
)}
/>useCloudDrop Hook
import { useCloudDrop } from 'cloud-drop/react'
function MyComponent() {
const {
files,
uploadFile,
uploadAll,
removeFile,
isUploading,
hasFiles
} = useCloudDrop({
endpoint: '/api/upload',
multiple: true,
onComplete: (file, url) => console.log('Done:', url)
})
return (
<div>
{/* Your custom UI */}
</div>
)
}🎨 Customization
Custom Styling
CloudDrop comes with beautiful default styles, but you can easily customize them:
/* Override default styles */
.clouddrop-uploader {
border: 3px dashed #10b981 !important;
background: #ecfdf5 !important;
}
.clouddrop-uploader.clouddrop-dragover {
border-color: #059669 !important;
background: #d1fae5 !important;
}Custom UI with Render Props
<CloudDrop endpoint="/api/upload" showUI={false}>
{({ files, uploadFile, isUploading }) => (
<div className="my-custom-uploader">
<input
type="file"
onChange={(e) => {/* handle file selection */}}
/>
{files.map(file => (
<div key={file.id}>
<span>{file.name}</span>
<button onClick={() => uploadFile(file.id)}>
Upload
</button>
</div>
))}
</div>
)}
</CloudDrop>🔧 Advanced Usage
Presigned URLs
const uploader = createCloudDrop({
endpoint: 'https://s3.amazonaws.com/bucket/presigned-url',
multiple: true,
headers: {
'Content-Type': 'multipart/form-data'
}
})Custom Form Data
const uploader = createCloudDrop({
endpoint: '/api/upload',
formData: {
userId: '123',
category: 'documents'
}
})File Type Validation
const uploader = createCloudDrop({
endpoint: '/api/upload',
accept: [
'image/*', // All images
'application/pdf', // PDF files
'.doc', // Word documents
'.docx'
]
})📱 Browser Support
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Inspired by modern file upload libraries
- Built with TypeScript for better developer experience
- Uses modern web APIs for optimal performance
📊 Bundle Size
- Minified: ~15kb
- Minified + Gzipped: ~5kb
- With React support: ~20kb minified + gzipped
🔗 Links
Made with ❤️ by mdjannatulhasan
