Saltar al contenido principal

Validación de archivos

Dropup proporciona validación comprehensiva de archivos para asegurar que solo se acepten archivos válidos.

Opciones de validación

Accept (Tipos de archivo)

Especifica qué tipos de archivo aceptar:

// Aceptar solo imágenes
useDropup({ accept: 'image/*' });

// Aceptar tipos específicos
useDropup({ accept: 'image/png, image/jpeg' });

// Aceptar por extensión
useDropup({ accept: '.pdf, .doc, .docx' });

// Múltiples categorías
useDropup({ accept: ['image/*', 'application/pdf', '.txt'] });

Patrones de accept comunes

PatrónDescripción
image/*Todas las imágenes
image/png, image/jpegSolo PNG y JPEG
video/*Todos los videos
audio/*Todos los archivos de audio
application/pdfSolo archivos PDF
.doc, .docxDocumentos de Word
*/*Todos los archivos (por defecto)

Límites de tamaño de archivo

useDropup({
maxSize: 10 * 1024 * 1024, // 10MB máximo
minSize: 1024, // 1KB mínimo
});

Límite de cantidad de archivos

useDropup({
maxFiles: 5, // Máximo 5 archivos
});

Límites de dimensiones de imagen

useDropup({
accept: 'image/*',
maxWidth: 4096, // Ancho máximo en píxeles
maxHeight: 4096, // Alto máximo en píxeles
minWidth: 100, // Ancho mínimo en píxeles
minHeight: 100, // Alto mínimo en píxeles
});

Reglas de validación personalizadas

Crea lógica de validación personalizada:

useDropup({
customRules: [
// Regla 1: Verificar longitud del nombre de archivo
(file) => {
if (file.name.length > 100) {
return 'El nombre del archivo debe tener menos de 100 caracteres';
}
return true;
},

// Regla 2: Verificar contenido específico
(file) => {
if (file.name.includes('draft')) {
return 'No se permiten archivos de borrador';
}
return true;
},

// Regla 3: Validación asíncrona
async (file) => {
const hash = await calculateHash(file);
const exists = await checkDuplicate(hash);
if (exists) {
return 'Este archivo ya ha sido cargado';
}
return true;
},
],
});

Valores de retorno de reglas

Valor de retornoSignificado
trueValidación pasó
falseValidación falló (error genérico)
stringValidación falló con mensaje personalizado

Manejando errores de validación

Usa el callback onValidationError:

useDropup({
accept: 'image/*',
maxSize: 5 * 1024 * 1024,
onValidationError: (errors) => {
errors.forEach(({ file, errors: fileErrors }) => {
console.log(`${file.name} falló la validación:`);
fileErrors.forEach(error => console.log(` - ${error}`));
});

// Mostrar mensaje amigable al usuario
toast.error(`${errors.length} archivo(s) fallaron la validación`);
},
});

Estructura del error de validación

interface ValidationError {
file: File; // El archivo que falló
errors: string[]; // Array de mensajes de error
}

Reglas de validación pre-construidas

Dropup incluye reglas de validación comunes:

import { commonRules } from '@samithahansaka/dropup';

useDropup({
customRules: [
commonRules.noExecutables, // Bloquear .exe, .bat, etc.
commonRules.noHiddenFiles, // Bloquear archivos que empiecen con .
commonRules.maxFilenameLength(50),
commonRules.allowedExtensions(['.jpg', '.png', '.pdf']),
],
});

Retroalimentación de validación durante arrastre

Proporciona retroalimentación visual durante el arrastre:

function DropZone() {
const { getDropProps, state } = useDropup({
accept: 'image/*',
});

// state.isDragAccept - archivos coinciden con criterio de accept
// state.isDragReject - archivos no coinciden

return (
<div
{...getDropProps()}
style={{
borderColor: state.isDragAccept
? 'green'
: state.isDragReject
? 'red'
: 'gray',
}}
>
{state.isDragReject && <p>¡Tipo de archivo no aceptado!</p>}
</div>
);
}

Ejemplo completo de validación

import { useDropup, commonRules } from '@samithahansaka/dropup';

function SecureUploader() {
const { files, state, getDropProps, getInputProps } = useDropup({
// Tipo de archivo
accept: ['image/jpeg', 'image/png', 'application/pdf'],

// Límites de tamaño
maxSize: 10 * 1024 * 1024, // 10MB
minSize: 100, // 100 bytes (prevenir archivos vacíos)

// Límite de cantidad
maxFiles: 10,

// Dimensiones de imagen (solo para imágenes)
maxWidth: 8000,
maxHeight: 8000,

// Reglas personalizadas
customRules: [
commonRules.noExecutables,
commonRules.maxFilenameLength(100),

// Personalizada: sin archivos con espacios
(file) => {
if (file.name.includes(' ')) {
return 'Los nombres de archivo no pueden contener espacios';
}
return true;
},
],

// Manejo de errores
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>❌ Algunos archivos serán rechazados</p>
) : (
<p>📁 Suelta archivos aquí (solo JPEG, PNG, PDF, máximo 10MB)</p>
)}
</div>
);
}