Saltar al contenido principal

Preguntas Frecuentes

Preguntas y respuestas comunes sobre Dropup.

General

¿Qué es Dropup?

Dropup es una biblioteca React ligera y sin interfaz para carga de archivos. Proporciona funcionalidad de arrastrar y soltar, validación de archivos, seguimiento del progreso de carga y soporte para almacenamiento en la nube, todo en un paquete de menos de 10KB comprimido.

¿Por qué "sin interfaz"?

Sin interfaz significa que Dropup no incluye componentes de UI. Proporciona la lógica y gestión del estado, mientras tú construyes la interfaz como quieras. Esto te da control total sobre la apariencia y sensación.

¿Cuál es el tamaño del paquete?

  • Núcleo (@samithahansaka/dropup): < 10KB comprimido
  • Con soporte de nube: +2KB por proveedor
  • Con procesamiento de imágenes: +5KB
  • Con protocolo tus: +3KB (requiere tus-js-client como dependencia de pares)

¿Soporta TypeScript?

¡Sí! Dropup está escrito en TypeScript e incluye definiciones de tipos completas. No se necesita paquete @types.

¿Qué versión de React se requiere?

React 16.8+ (requiere soporte de hooks).

Uso

¿Cómo cargo archivos?

const { files, actions } = useDropup({
upload: { url: '/api/upload' },
});

// Cargar todos los archivos
actions.upload();

// Cargar archivos específicos
actions.upload(['file-id-1', 'file-id-2']);

¿Cómo manejo errores de validación?

useDropup({
accept: 'image/*',
maxSize: 5 * 1024 * 1024,

onValidationError: (errors) => {
errors.forEach(({ file, errors }) => {
console.log(`${file.name}: ${errors.join(', ')}`);
});
},
});

¿Puedo usar lógica de carga personalizada?

¡Sí! Pasa una función en lugar de un objeto de configuración:

useDropup({
upload: async (file, options) => {
const { signal, onProgress } = options;

// Tu lógica de carga personalizada
const response = await customUpload(file.file, {
signal,
onProgress,
});

return { url: response.url };
},
});

¿Cómo agrego archivos programáticamente?

const { actions } = useDropup();

// Desde el portapapeles
document.addEventListener('paste', (e) => {
const files = e.clipboardData?.files;
if (files) {
actions.addFiles(files);
}
});

¿Puedo tener múltiples zonas de soltar?

¡Sí! Cada llamada a useDropup crea una instancia independiente:

const images = useDropup({ accept: 'image/*' });
const documents = useDropup({ accept: '.pdf' });

// Usar por separado
<div {...images.getDropProps()}>...</div>
<div {...documents.getDropProps()}>...</div>

Cargas

¿Cómo muestro el progreso de carga?

const { files } = useDropup({ upload: { url: '/api/upload' } });

{files.map(file => (
<div key={file.id}>
{file.name}: {file.progress}%
</div>
))}

¿Cómo cancelo una carga?

const { actions } = useDropup();

// Cancelar archivo específico
actions.cancel('file-id');

// Cancelar todas las cargas
actions.cancel();

¿Cómo reintento cargas fallidas?

const { actions } = useDropup();

// Reintentar archivos específicos
actions.retry(['file-id']);

// Reintentar todos los fallidos
actions.retry();

¿Soporta cargas fragmentadas?

¡Sí! Usa createChunkedUploader:

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

useDropup({
upload: createChunkedUploader({
url: '/api/upload/chunk',
chunkSize: 5 * 1024 * 1024, // 5MB
}),
});

¿Puedo cargar directamente a S3?

¡Sí! Usa el cargador de nube:

import { createS3Uploader } from '@samithahansaka/dropup/cloud/s3';

useDropup({
upload: createS3Uploader({
getPresignedUrl: async (file) => {
const res = await fetch('/api/s3/presign', {
method: 'POST',
body: JSON.stringify({ filename: file.name }),
});
return res.json();
},
}),
});

Validación

¿Cómo restrinjo tipos de archivo?

// Por tipo MIME
useDropup({ accept: 'image/*' });

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

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

¿Cómo establezco límites de tamaño?

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

¿Cómo limito el número de archivos?

useDropup({
maxFiles: 5,
});

¿Puedo agregar validación personalizada?

¡Sí! Usa customRules:

useDropup({
customRules: [
(file) => {
if (file.name.includes('draft')) {
return 'No se permiten archivos de borrador';
}
return true;
},
],
});

Vistas previas

¿Cómo muestro vistas previas de imágenes?

Las vistas previas están habilitadas por defecto:

const { files } = useDropup();

{files.map(file => (
file.preview && <img src={file.preview} alt="" />
))}

¿Necesito limpiar las URLs de vista previa?

¡No! Dropup revoca automáticamente las URLs de objeto cuando se eliminan archivos o el componente se desmonta.

¿Puedo deshabilitar las vistas previas?

useDropup({ generatePreviews: false });

Solución de problemas

Los archivos no se cargan

  1. Verifica que upload esté configurado:

    useDropup({ upload: { url: '/api/upload' } });
  2. Asegúrate de llamar a actions.upload() (a menos que autoUpload: true)

  3. Revisa la consola del navegador para errores de red

Las URLs de vista previa no funcionan

  1. Asegúrate de que el archivo sea una imagen
  2. Verifica que generatePreviews no sea false
  3. Verifica que el objeto de archivo tenga una propiedad preview válida

Arrastrar y soltar no funciona

  1. Asegúrate de expandir getDropProps() en un elemento contenedor
  2. Incluye el input oculto: <input {...getInputProps()} />
  3. Verifica que disabled no sea true

Errores de TypeScript

  1. Actualiza a la última versión de Dropup
  2. Asegúrate de que tsconfig.json tenga moduleResolution apropiado
  3. Verifica que @samithahansaka/dropup esté en dependencies, no en devDependencies

Fugas de memoria

  1. Asegúrate de que los componentes usando useDropup se desmonten correctamente
  2. Llama a actions.reset() antes de desmontar si es necesario
  3. No almacenes archivos en estado externo sin limpieza

Compatibilidad

¿Funciona con Next.js?

¡Sí! Usa la directiva 'use client':

'use client';
import { useDropup } from '@samithahansaka/dropup';

¿Funciona con React Native?

¡Sí! Usa el adaptador nativo:

import { NativeAdapter } from '@samithahansaka/dropup/native';

useDropup({ adapter: NativeAdapter });

¿Soporta SSR?

¡Sí! Dropup es seguro para SSR. Solo usa APIs del navegador cuando están disponibles.

¿Soporte de navegadores?

Todos los navegadores modernos:

  • Chrome 60+
  • Firefox 55+
  • Safari 12+
  • Edge 79+

Contribuir

¿Cómo puedo contribuir?

  1. Haz fork del repositorio
  2. Crea una rama de característica
  3. Envía un pull request

Ve CONTRIBUTING.md para más detalles.

¿Cómo reporto errores?

Abre un issue en github.com/samithahansaka/dropup/issues.

¿Hay una hoja de ruta?

Revisa los issues y discusiones de GitHub para características planificadas.