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ón | Descripción |
|---|---|
image/* | Todas las imágenes |
image/png, image/jpeg | Solo PNG y JPEG |
video/* | Todos los videos |
audio/* | Todos los archivos de audio |
application/pdf | Solo archivos PDF |
.doc, .docx | Documentos 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 retorno | Significado |
|---|---|
true | Validación pasó |
false | Validación falló (error genérico) |
string | Validació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>
);
}