Обработка файлов
Dropup обеспечивает беспрепятственную работу с файлами с момента их выбора до загрузки.
Методы выбора файлов
Перетаскивание
Используйте getDropProps() для включения функции drag-and-drop на любом элементе:
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>Перетащите файлы сюда</p>
</div>
);
}
Клик для выбора
Зона перетаскивания по умолчанию также кликабельна:
<div {...getDropProps()}>
<input {...getInputProps()} />
<p>Кликните или перетащите файлы сюда</p>
</div>
Программный выбор
Откройте диалог выбора файлов программно:
const { openFileDialog } = useDropup();
<button onClick={openFileDialog}>
Выбрать файлы
</button>
Программное добавление файлов
Добавляйте файлы напрямую (полезно для событий вставки или интеграций):
const { actions } = useDropup();
// Из буфера обмена
document.addEventListener('paste', (e) => {
const files = e.clipboardData?.files;
if (files?.length) {
actions.addFiles(files);
}
});
Структура объекта файла
Каждый файл в массиве files имеет следующую структуру:
interface DropupFile {
// Идентификация
id: string; // Уникальный идентификатор (генерируется автоматически)
file: File; // Оригинальный браузерный объект File
// Метаданные
name: string; // Имя файла
size: number; // Размер в байтах
type: string; // MIME тип (например, "image/png")
// Превью (для изображений)
preview?: string; // Object URL для превью
// Состояние загрузки
status: FileStatus; // 'idle' | 'uploading' | 'complete' | 'error' | 'paused'
progress: number; // 0-100
// Результаты
uploadedUrl?: string; // URL после успешной загрузки
response?: unknown; // Ответ сервера
error?: DropupError; // Детали ошибки при неудаче
// Пользовательские данные
meta?: Record<string, unknown>;
}
Жизненный цикл статуса файла
idle → uploading → complete
↘ error → (retry) → uploading
↘ paused → (resume) → uploading
Значения статусов
| Статус | Описание |
|---|---|
idle | Файл добавлен, но загрузка ещё не началась |
uploading | Идёт загрузка |
complete | Загрузка успешна |
error | Загрузка не удалась |
paused | Загрузка приостановлена (для возобновляемых загрузок) |
Работа с файлами
Доступ к файлам
const { files } = useDropup();
// Все файлы
console.log(files);
// Фильтрация по статусу
const uploading = files.filter(f => f.status === 'uploading');
const completed = files.filter(f => f.status === 'complete');
const failed = files.filter(f => f.status === 'error');
Удаление файлов
const { files, actions } = useDropup();
// Удалить один файл
actions.remove(files[0].id);
// Удалить все файлы
actions.reset();
Обновление метаданных файла
const { actions } = useDropup();
// Добавить пользовательские метаданные
actions.updateFileMeta(fileId, {
customField: 'value',
category: 'documents',
});
Превью файлов
Для изображений Dropup может генерировать URL превью:
const { files } = useDropup({
generatePreviews: true, // по умолчанию: true
});
// Используйте превью в вашем UI
{files.map(file => (
file.preview && (
<img
src={file.preview}
alt={file.name}
style={{ maxWidth: 100, maxHeight: 100 }}
/>
)
))}
Управление памятью
URL превью - это Object URL, которые потребляют память. Dropup автоматически отзывает их при удалении файлов или размонтировании компонента.
Форматирование размера файла
Вспомогательная функция для отображения размеров файлов:
function formatFileSize(bytes: number): string {
if (bytes === 0) return '0 Байт';
const k = 1024;
const sizes = ['Байт', 'КБ', 'МБ', 'ГБ'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
// Использование
{files.map(file => (
<span>{formatFileSize(file.size)}</span>
))}
Обработка больших файлов
Для больших файлов рассмотрите чанковые загрузки:
import { useDropup, createChunkedUploader } from '@samithahansaka/dropup';
const { files } = useDropup({
upload: createChunkedUploader({
url: '/api/upload',
chunkSize: 5 * 1024 * 1024, // Чанки по 5МБ
}),
});
См. Чанковые загрузки для подробностей.