Перейти к основному содержимому

Как работает Dropup

Dropup построен на концепции headless UI - он обрабатывает всю сложную логику загрузки файлов, предоставляя вам полный контроль над визуальным представлением.

Архитектура

┌─────────────────────────────────────────────────────────────┐
│ Your React Component │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Drop Zone │ │ File List │ │ Upload Button │ │
│ │ (your UI) │ │ (your UI) │ │ (your UI) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ useDropup Hook ││
│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌─────────┐ ││
│ │ │Validation │ │ State │ │ Upload │ │ Platform│ ││
│ │ │ Engine │ │ Manager │ │ Engine │ │ Adapter │ ││
│ │ └───────────┘ └───────────┘ └───────────┘ └─────────┘ ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘

Ключевые компоненты

1. Менеджер состояния

Dropup использует useReducer из React для предсказуемого управления состоянием:

  • Отслеживает все файлы и их статусы
  • Управляет состоянием перетаскивания
  • Обрабатывает прогресс загрузки
  • Предоставляет вычисляемые значения

2. Движок валидации

Перед добавлением файлы проходят валидацию:

const { files } = useDropup({
accept: 'image/*', // Валидация типа файла
maxSize: 5 * 1024 * 1024, // Максимальный размер файла
minSize: 1024, // Минимальный размер файла
maxFiles: 10, // Максимальное количество файлов
maxWidth: 4096, // Максимальная ширина изображения
maxHeight: 4096, // Максимальная высота изображения
customRules: [ // Пользовательская валидация
(file) => file.name.length < 100 || 'Имя файла слишком длинное'
],
});

3. Движок загрузки

Движок загрузки обрабатывает:

  • Простые загрузки (один запрос на файл)
  • Чанковые загрузки (разделение больших файлов)
  • Логику повторных попыток с экспоненциальной задержкой
  • Управление параллельными загрузками
  • Отслеживание прогресса

4. Адаптер платформы

Dropup работает на разных платформах:

  • Web - Использует нативные браузерные API
  • React Native - Использует нативную обработку файлов
  • SSR - Безопасен для серверного рендеринга

Поток данных

User Action → Validation → State Update → Upload → Callbacks
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
Select/ Accept/Reject files[] XHR/Fetch onComplete
Drop files Updated Progress onError

Принципы проектирования

1. Headless First

Без встроенных UI-компонентов - вы создаёте именно то, что вам нужно:

// Вы контролируете весь UI
<div {...getDropProps()}>
<YourCustomDropZone />
<input {...getInputProps()} />
</div>

2. Типобезопасность

Полная поддержка TypeScript с исчерпывающими типами:

import type { DropupFile, UseDropupOptions } from '@samithahansaka/dropup';

const options: UseDropupOptions = {
accept: 'image/*',
onUploadComplete: (file: DropupFile) => {
console.log(file.uploadedUrl);
},
};

3. Tree Shakeable

Импортируйте только то, что вам нужно:

// Только ядро (~10KB)
import { useDropup } from '@samithahansaka/dropup';

// Добавьте поддержку облака при необходимости
import { createS3Uploader } from '@samithahansaka/dropup/cloud/s3';

// Добавьте обработку изображений при необходимости
import { compressImage } from '@samithahansaka/dropup/image';

4. Прогрессивное улучшение

Начните с простого, добавляйте функции по мере необходимости:

// Базовое использование
const { files } = useDropup();

// Добавьте валидацию
const { files } = useDropup({ maxSize: 10_000_000 });

// Добавьте автозагрузку
const { files } = useDropup({
maxSize: 10_000_000,
upload: { url: '/api/upload' },
autoUpload: true,
});

// Добавьте облачное хранилище
const { files } = useDropup({
upload: createS3Uploader({ getPresignedUrl }),
});