Penanganan File
Dropup menyediakan pengalaman yang mulus untuk menangani file dari saat dipilih hingga diupload.
Metode Pemilihan File
Seret dan Lepas
Gunakan getDropProps() untuk mengaktifkan seret-dan-lepas pada elemen apa pun:
function DropZone() {
const { getDropProps, getInputProps, state } = useDropup();
return (
<div
{...getDropProps()}
style={{
border: state.isDragging ? '2px dashed blue' : '2px dashed gray',
backgroundColor: state.isDragging ? '#f0f8ff' : 'transparent',
}}
>
<input {...getInputProps()} />
<p>Lepas file di sini</p>
</div>
);
}
Klik untuk Memilih
Zona drop juga dapat diklik secara default:
<div {...getDropProps()}>
<input {...getInputProps()} />
<p>Klik atau seret file ke sini</p>
</div>
Pemilihan Programatik
Buka dialog file secara programatik:
const { openFileDialog } = useDropup();
<button onClick={openFileDialog}>
Pilih File
</button>
Penambahan File Programatik
Tambahkan file secara langsung (berguna untuk event paste atau integrasi):
const { actions } = useDropup();
// Dari clipboard
document.addEventListener('paste', (e) => {
const files = e.clipboardData?.files;
if (files?.length) {
actions.addFiles(files);
}
});
Struktur Objek File
Setiap file dalam array files memiliki struktur ini:
interface DropupFile {
// Identifikasi
id: string; // Identifier unik (auto-generated)
file: File; // Objek File browser asli
// Metadata
name: string; // Nama file
size: number; // Ukuran dalam bytes
type: string; // Tipe MIME (contoh: "image/png")
// Preview (untuk gambar)
preview?: string; // Object URL untuk preview
// State Upload
status: FileStatus; // 'idle' | 'uploading' | 'complete' | 'error' | 'paused'
progress: number; // 0-100
// Hasil
uploadedUrl?: string; // URL setelah upload berhasil
response?: unknown; // Response server
error?: DropupError; // Detail error jika gagal
// Data kustom
meta?: Record<string, unknown>;
}
Siklus Hidup Status File
idle → uploading → complete
↘ error → (retry) → uploading
↘ paused → (resume) → uploading
Nilai Status
| Status | Deskripsi |
|---|---|
idle | File ditambahkan tapi belum diupload |
uploading | Sedang diupload |
complete | Upload berhasil |
error | Upload gagal |
paused | Upload dijeda (untuk upload yang dapat dilanjutkan) |
Bekerja dengan File
Mengakses File
const { files } = useDropup();
// Semua file
console.log(files);
// Filter berdasarkan status
const uploading = files.filter(f => f.status === 'uploading');
const completed = files.filter(f => f.status === 'complete');
const failed = files.filter(f => f.status === 'error');
Menghapus File
const { files, actions } = useDropup();
// Hapus satu file
actions.remove(files[0].id);
// Hapus semua file
actions.reset();
Memperbarui Metadata File
const { actions } = useDropup();
// Tambahkan metadata kustom
actions.updateFileMeta(fileId, {
customField: 'value',
category: 'documents',
});
Preview File
Untuk file gambar, Dropup dapat menghasilkan URL preview:
const { files } = useDropup({
generatePreviews: true, // default: true
});
// Gunakan preview di UI Anda
{files.map(file => (
file.preview && (
<img
src={file.preview}
alt={file.name}
style={{ maxWidth: 100, maxHeight: 100 }}
/>
)
))}
Manajemen Memori
URL preview adalah Object URL yang mengonsumsi memori. Dropup secara otomatis mencabutnya saat file dihapus atau komponen unmount.
Format Ukuran File
Helper untuk menampilkan ukuran file:
function formatFileSize(bytes: number): string {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
// Penggunaan
{files.map(file => (
<span>{formatFileSize(file.size)}</span>
))}
Menangani File Besar
Untuk file besar, pertimbangkan upload chunked:
import { useDropup, createChunkedUploader } from '@samithahansaka/dropup';
const { files } = useDropup({
upload: createChunkedUploader({
url: '/api/upload',
chunkSize: 5 * 1024 * 1024, // chunk 5MB
}),
});
Lihat Upload Chunked untuk detail lebih lanjut.