Manejo de archivos
Dropup proporciona una experiencia fluida para manejar archivos desde el momento en que se seleccionan hasta que se cargan.
Métodos de selección de archivos
Arrastrar y soltar
Usa getDropProps() para habilitar arrastrar y soltar en cualquier elemento:
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>Suelta archivos aquí</p>
</div>
);
}
Clic para seleccionar
La zona de soltar también es clicable por defecto:
<div {...getDropProps()}>
<input {...getInputProps()} />
<p>Haz clic o arrastra archivos aquí</p>
</div>
Selección programática
Abre el diálogo de archivos programáticamente:
const { openFileDialog } = useDropup();
<button onClick={openFileDialog}>
Seleccionar archivos
</button>
Adición programática de archivos
Agrega archivos directamente (útil para eventos de pegar o integraciones):
const { actions } = useDropup();
// Desde el portapapeles
document.addEventListener('paste', (e) => {
const files = e.clipboardData?.files;
if (files?.length) {
actions.addFiles(files);
}
});
Estructura del objeto de archivo
Cada archivo en el array files tiene esta estructura:
interface DropupFile {
// Identificación
id: string; // Identificador único (auto-generado)
file: File; // Objeto File original del navegador
// Metadatos
name: string; // Nombre del archivo
size: number; // Tamaño en bytes
type: string; // Tipo MIME (ej., "image/png")
// Vista previa (para imágenes)
preview?: string; // URL de objeto para vista previa
// Estado de carga
status: FileStatus; // 'idle' | 'uploading' | 'complete' | 'error' | 'paused'
progress: number; // 0-100
// Resultados
uploadedUrl?: string; // URL después de carga exitosa
response?: unknown; // Respuesta del servidor
error?: DropupError; // Detalles de error si falló
// Datos personalizados
meta?: Record<string, unknown>;
}
Ciclo de vida del estado del archivo
idle → uploading → complete
↘ error → (reintentar) → uploading
↘ paused → (reanudar) → uploading
Valores de estado
| Estado | Descripción |
|---|---|
idle | Archivo agregado pero aún no cargando |
uploading | Actualmente cargando |
complete | Carga exitosa |
error | Carga falló |
paused | Carga pausada (para cargas reanudables) |
Trabajando con archivos
Accediendo a archivos
const { files } = useDropup();
// Todos los archivos
console.log(files);
// Filtrar por estado
const uploading = files.filter(f => f.status === 'uploading');
const completed = files.filter(f => f.status === 'complete');
const failed = files.filter(f => f.status === 'error');
Eliminando archivos
const { files, actions } = useDropup();
// Eliminar un archivo
actions.remove(files[0].id);
// Eliminar todos los archivos
actions.reset();
Actualizando metadatos de archivo
const { actions } = useDropup();
// Agregar metadatos personalizados
actions.updateFileMeta(fileId, {
customField: 'valor',
category: 'documentos',
});
Vistas previas de archivos
Para archivos de imagen, Dropup puede generar URLs de vista previa:
const { files } = useDropup({
generatePreviews: true, // por defecto: true
});
// Usar vista previa en tu UI
{files.map(file => (
file.preview && (
<img
src={file.preview}
alt={file.name}
style={{ maxWidth: 100, maxHeight: 100 }}
/>
)
))}
Las URLs de vista previa son URLs de objeto que consumen memoria. Dropup las revoca automáticamente cuando se eliminan archivos o el componente se desmonta.
Formateo de tamaño de archivo
Helper para mostrar tamaños de archivo:
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];
}
// Uso
{files.map(file => (
<span>{formatFileSize(file.size)}</span>
))}
Manejando archivos grandes
Para archivos grandes, considera cargas fragmentadas:
import { useDropup, createChunkedUploader } from '@samithahansaka/dropup';
const { files } = useDropup({
upload: createChunkedUploader({
url: '/api/upload',
chunkSize: 5 * 1024 * 1024, // fragmentos de 5MB
}),
});
Ve Cargas fragmentadas para más detalles.