Validasi File
Dropup menyediakan validasi file yang komprehensif untuk memastikan hanya file yang valid yang diterima.
Opsi Validasi
Accept (Tipe File)
Tentukan tipe file mana yang diterima:
// Hanya terima gambar
useDropup({ accept: 'image/*' });
// Terima tipe tertentu
useDropup({ accept: 'image/png, image/jpeg' });
// Terima berdasarkan ekstensi
useDropup({ accept: '.pdf, .doc, .docx' });
// Multiple kategori
useDropup({ accept: ['image/*', 'application/pdf', '.txt'] });
Pola Accept Umum
| Pola | Deskripsi |
|---|---|
image/* | Semua gambar |
image/png, image/jpeg | Hanya PNG dan JPEG |
video/* | Semua video |
audio/* | Semua file audio |
application/pdf | Hanya file PDF |
.doc, .docx | Dokumen Word |
*/* | Semua file (default) |
Batas Ukuran File
useDropup({
maxSize: 10 * 1024 * 1024, // 10MB maksimum
minSize: 1024, // 1KB minimum
});
Batas Jumlah File
useDropup({
maxFiles: 5, // Maksimum 5 file
});
Batas Dimensi Gambar
useDropup({
accept: 'image/*',
maxWidth: 4096, // Lebar maks dalam pixel
maxHeight: 4096, // Tinggi maks dalam pixel
minWidth: 100, // Lebar min dalam pixel
minHeight: 100, // Tinggi min dalam pixel
});
Aturan Validasi Kustom
Buat logika validasi kustom:
useDropup({
customRules: [
// Aturan 1: Periksa panjang nama file
(file) => {
if (file.name.length > 100) {
return 'Nama file harus kurang dari 100 karakter';
}
return true;
},
// Aturan 2: Periksa konten tertentu
(file) => {
if (file.name.includes('draft')) {
return 'File draft tidak diperbolehkan';
}
return true;
},
// Aturan 3: Validasi async
async (file) => {
const hash = await calculateHash(file);
const exists = await checkDuplicate(hash);
if (exists) {
return 'File ini sudah pernah diupload';
}
return true;
},
],
});
Nilai Return Aturan
| Nilai Return | Makna |
|---|---|
true | Validasi berhasil |
false | Validasi gagal (error generik) |
string | Validasi gagal dengan pesan kustom |
Menangani Error Validasi
Gunakan callback onValidationError:
useDropup({
accept: 'image/*',
maxSize: 5 * 1024 * 1024,
onValidationError: (errors) => {
errors.forEach(({ file, errors: fileErrors }) => {
console.log(`${file.name} gagal validasi:`);
fileErrors.forEach(error => console.log(` - ${error}`));
});
// Tampilkan pesan yang ramah pengguna
toast.error(`${errors.length} file gagal validasi`);
},
});
Struktur Error Validasi
interface ValidationError {
file: File; // File yang gagal
errors: string[]; // Array pesan error
}
Aturan Validasi Bawaan
Dropup menyertakan aturan validasi umum:
import { commonRules } from '@samithahansaka/dropup';
useDropup({
customRules: [
commonRules.noExecutables, // Blokir .exe, .bat, dll.
commonRules.noHiddenFiles, // Blokir file yang dimulai dengan .
commonRules.maxFilenameLength(50),
commonRules.allowedExtensions(['.jpg', '.png', '.pdf']),
],
});
Feedback Validasi Seret
Berikan feedback visual saat menyeret:
function DropZone() {
const { getDropProps, state } = useDropup({
accept: 'image/*',
});
// state.isDragAccept - file cocok dengan kriteria accept
// state.isDragReject - file tidak cocok
return (
<div
{...getDropProps()}
style={{
borderColor: state.isDragAccept
? 'green'
: state.isDragReject
? 'red'
: 'gray',
}}
>
{state.isDragReject && <p>Tipe file tidak diterima!</p>}
</div>
);
}
Contoh Validasi Lengkap
import { useDropup, commonRules } from '@samithahansaka/dropup';
function SecureUploader() {
const { files, state, getDropProps, getInputProps } = useDropup({
// Tipe file
accept: ['image/jpeg', 'image/png', 'application/pdf'],
// Batas ukuran
maxSize: 10 * 1024 * 1024, // 10MB
minSize: 100, // 100 bytes (cegah file kosong)
// Batas jumlah
maxFiles: 10,
// Dimensi gambar (hanya untuk gambar)
maxWidth: 8000,
maxHeight: 8000,
// Aturan kustom
customRules: [
commonRules.noExecutables,
commonRules.maxFilenameLength(100),
// Kustom: tidak ada file dengan spasi
(file) => {
if (file.name.includes(' ')) {
return 'Nama file tidak boleh mengandung spasi';
}
return true;
},
],
// Penanganan error
onValidationError: (errors) => {
errors.forEach(({ file, errors }) => {
alert(`${file.name}: ${errors.join(', ')}`);
});
},
});
return (
<div
{...getDropProps()}
className={`dropzone ${
state.isDragReject ? 'reject' : state.isDragAccept ? 'accept' : ''
}`}
>
<input {...getInputProps()} />
{state.isDragReject ? (
<p>❌ Beberapa file akan ditolak</p>
) : (
<p>📁 Lepas file di sini (hanya JPEG, PNG, PDF, maks 10MB)</p>
)}
</div>
);
}