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.