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

Обработка файлов

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МБ
}),
});

См. Чанковые загрузки для подробностей.