Saltar al contenido principal

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

EstadoDescripción
idleArchivo agregado pero aún no cargando
uploadingActualmente cargando
completeCarga exitosa
errorCarga falló
pausedCarga 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 }}
/>
)
))}
Gestión de memoria

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.