@nilovonjs/bucketkit-react
v0.1.1
Published
React components and hooks for S3 uploads - Built with shadcn/ui
Downloads
131
Maintainers
Readme
⚛️ @nilovonjs/bucketkit-react
React components and hooks for S3 uploads - Built with shadcn/ui patterns for beautiful upload interfaces.
🎯 Overview
@nilovonjs/bucketkit-react provides React components and hooks for building beautiful file upload interfaces with direct-to-S3 uploads. Built with shadcn/ui design patterns for easy customization.
✨ Features
- 🎨 Beautiful UI - Pre-built components with shadcn/ui styling
- 📤 Drag & Drop - Dropzone component for easy file selection
- 📊 Progress Tracking - Real-time upload progress with cancel support
- 🎣 Hooks API - Full control with custom UIs using hooks
- 🎨 Customizable - Easy styling with Tailwind CSS
- 📝 Type-Safe - Full TypeScript support
- ⚡ Performant - Direct-to-S3 uploads with progress tracking
🚀 Installation
npm install @nilovonjs/bucketkit-react
# or
pnpm add @nilovonjs/bucketkit-react
# or
yarn add @nilovonjs/bucketkit-reactPeer Dependencies:
react >= 18.0.0react-dom >= 18.0.0
📖 Quick Start
Basic Setup
import {
BucketKitProvider,
BucketKitDropzone,
BucketKitUploadList,
} from '@nilovonjs/bucketkit-react';
function App() {
return (
<BucketKitProvider endpoint="/api/upload">
<BucketKitDropzone />
<BucketKitUploadList />
</BucketKitProvider>
);
}With Custom Configuration
import {
BucketKitProvider,
BucketKitDropzone,
BucketKitUploadList,
} from '@nilovonjs/bucketkit-react';
function App() {
return (
<BucketKitProvider
endpoint="/api/upload"
onUploadComplete={(file) => {
console.log('Uploaded:', file.url);
}}
onUploadError={(error) => {
console.error('Upload failed:', error);
}}
>
<BucketKitDropzone
multiple
accept={['image/*', 'application/pdf']}
maxSize={10 * 1024 * 1024} // 10 MB
/>
<BucketKitUploadList />
</BucketKitProvider>
);
}🧩 Components
BucketKitProvider
Context provider that manages upload state and configuration.
Props:
endpoint: string- API endpoint for generating presigned URLsonUploadComplete?: (file: UploadItem) => void- Callback when upload completesonUploadError?: (error: Error, file: UploadItem) => void- Error callbackheaders?: Record<string, string>- Custom headers for API requestschildren: ReactNode- Child components
BucketKitDropzone
Drag & drop file upload component.
<BucketKitDropzone
multiple
accept={['image/*']}
maxSize={10 * 1024 * 1024}
className="border-2 border-dashed p-8"
/>Props:
multiple?: boolean- Allow multiple filesaccept?: string[]- Accepted MIME typesmaxSize?: number- Maximum file size in bytesclassName?: string- Custom CSS classesdisabled?: boolean- Disable the dropzone
BucketKitUploadButton
Button component for file selection.
<BucketKitUploadButton
accept={['image/*']}
multiple
>
Upload Files
</BucketKitUploadButton>Props:
multiple?: booleanaccept?: string[]maxSize?: numberclassName?: stringdisabled?: booleanchildren: ReactNode- Button content
BucketKitUploadList
List component showing upload progress.
<BucketKitUploadList
showProgress
showActions
onRemove={(item) => console.log('Removed:', item)}
/>Props:
showProgress?: boolean- Show progress barsshowActions?: boolean- Show cancel/remove buttonsonRemove?: (item: UploadItem) => void- Remove callbackclassName?: string- Custom CSS classes
🎣 Hooks
useBucketKitUpload()
Main hook for managing file uploads.
import { useBucketKitUpload } from '@nilovonjs/bucketkit-react';
function CustomUpload() {
const {
uploadFiles,
items,
isUploading,
progress,
cancelUpload,
removeItem,
retryUpload,
} = useBucketKitUpload();
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const files = Array.from(e.target.files || []);
uploadFiles(files);
};
return (
<div>
<input type="file" onChange={handleFileChange} multiple />
{isUploading && <p>Uploading: {progress}%</p>}
<ul>
{items.map((item) => (
<li key={item.id}>
{item.fileName}: {item.status} ({item.progress}%)
{item.status === 'uploading' && (
<button onClick={() => cancelUpload(item.id)}>Cancel</button>
)}
{item.status === 'error' && (
<button onClick={() => retryUpload(item.id)}>Retry</button>
)}
<button onClick={() => removeItem(item.id)}>Remove</button>
</li>
))}
</ul>
</div>
);
}Returns:
uploadFiles(files: File[])- Start uploading filesaddFiles(files: File[])- Add files to queue without uploadingitems: UploadItem[]- List of upload itemsisUploading: boolean- Whether any upload is in progressprogress: number- Overall progress (0-100)cancelUpload(id: string)- Cancel a specific uploadremoveItem(id: string)- Remove an item from the listretryUpload(id: string)- Retry a failed uploadclearCompleted()- Clear all completed/errored items
useUploadItemActions(itemId: string)
Get actions for a specific upload item.
import { useUploadItemActions } from '@nilovonjs/bucketkit-react';
function UploadItemRow({ item }: { item: UploadItem }) {
const actions = useUploadItemActions(item.id);
return (
<div>
<span>{item.fileName}</span>
{item.status === 'uploading' && (
<button onClick={actions.cancel}>Cancel</button>
)}
{item.status === 'error' && (
<button onClick={actions.retry}>Retry</button>
)}
<button onClick={actions.remove}>Remove</button>
</div>
);
}Returns:
cancel: () => void- Cancel the uploadretry: () => void- Retry the uploadremove: () => void- Remove the item
useUploadStats()
Get aggregate upload statistics.
import { useUploadStats } from '@nilovonjs/bucketkit-react';
function UploadStats() {
const { total, completed, failed, uploading, progress } = useUploadStats();
return (
<div>
<p>Total: {total}</p>
<p>Completed: {completed}</p>
<p>Failed: {failed}</p>
<p>Uploading: {uploading}</p>
<p>Progress: {progress}%</p>
</div>
);
}useCompletedUploads()
Get only completed uploads.
import { useCompletedUploads } from '@nilovonjs/bucketkit-react';
function CompletedList() {
const completed = useCompletedUploads();
return (
<ul>
{completed.map((item) => (
<li key={item.id}>
<a href={item.url}>{item.fileName}</a>
</li>
))}
</ul>
);
}🎨 Styling
Components use Tailwind CSS and can be customized with the className prop. The package follows shadcn/ui patterns for easy styling.
Custom Dropzone
<BucketKitDropzone
className="border-2 border-dashed border-gray-300 rounded-lg p-12 text-center hover:border-gray-400 transition-colors"
disabledClassName="opacity-50 cursor-not-allowed"
/>Custom Upload List
<BucketKitUploadList
className="space-y-2"
itemClassName="flex items-center justify-between p-4 bg-gray-100 rounded"
/>📚 Types
UploadItem
type UploadItem = {
id: string;
file: File;
fileName: string;
status: 'pending' | 'uploading' | 'completed' | 'error';
progress: number;
url?: string;
error?: Error;
};PresignedUrlResponse
Expected response from your API endpoint:
type PresignedUrlResponse = {
url: string;
method: 'PUT';
headers: Record<string, string>;
key: string;
publicUrl: string;
expiresIn: number;
};🔗 Backend Integration
This package works with @nilovonjs/bucketkit-core on the backend. Your API endpoint should:
- Accept a POST request with
{ fileName, contentType, size } - Validate the request using
bucketKit.validateUploadRequest() - Generate a presigned URL using
bucketKit.createPresignedUpload() - Return the presigned URL response
See @nilovonjs/bucketkit-core for backend setup.
📄 License
MIT
