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

Валидация файлов

Dropup предоставляет комплексную валидацию файлов, чтобы гарантировать принятие только валидных файлов.

Опции валидации

Accept (Типы файлов)

Укажите, какие типы файлов принимать:

// Принимать только изображения
useDropup({ accept: 'image/*' });

// Принимать определённые типы
useDropup({ accept: 'image/png, image/jpeg' });

// Принимать по расширению
useDropup({ accept: '.pdf, .doc, .docx' });

// Несколько категорий
useDropup({ accept: ['image/*', 'application/pdf', '.txt'] });

Общие паттерны Accept

ПаттернОписание
image/*Все изображения
image/png, image/jpegТолько PNG и JPEG
video/*Все видео
audio/*Все аудиофайлы
application/pdfТолько PDF файлы
.doc, .docxДокументы Word
*/*Все файлы (по умолчанию)

Ограничения размера файла

useDropup({
maxSize: 10 * 1024 * 1024, // Максимум 10МБ
minSize: 1024, // Минимум 1КБ
});

Ограничение количества файлов

useDropup({
maxFiles: 5, // Максимум 5 файлов
});

Ограничения размеров изображений

useDropup({
accept: 'image/*',
maxWidth: 4096, // Максимальная ширина в пикселях
maxHeight: 4096, // Максимальная высота в пикселях
minWidth: 100, // Минимальная ширина в пикселях
minHeight: 100, // Минимальная высота в пикселях
});

Пользовательские правила валидации

Создайте собственную логику валидации:

useDropup({
customRules: [
// Правило 1: Проверка длины имени файла
(file) => {
if (file.name.length > 100) {
return 'Имя файла должно быть короче 100 символов';
}
return true;
},

// Правило 2: Проверка на определённое содержимое
(file) => {
if (file.name.includes('draft')) {
return 'Черновики не допускаются';
}
return true;
},

// Правило 3: Асинхронная валидация
async (file) => {
const hash = await calculateHash(file);
const exists = await checkDuplicate(hash);
if (exists) {
return 'Этот файл уже был загружен';
}
return true;
},
],
});

Возвращаемые значения правил

Возвращаемое значениеЗначение
trueВалидация пройдена
falseВалидация не пройдена (общая ошибка)
stringВалидация не пройдена с пользовательским сообщением

Обработка ошибок валидации

Используйте колбэк onValidationError:

useDropup({
accept: 'image/*',
maxSize: 5 * 1024 * 1024,
onValidationError: (errors) => {
errors.forEach(({ file, errors: fileErrors }) => {
console.log(`${file.name} не прошёл валидацию:`);
fileErrors.forEach(error => console.log(` - ${error}`));
});

// Показать понятное сообщение пользователю
toast.error(`${errors.length} файл(ов) не прошли валидацию`);
},
});

Структура ошибки валидации

interface ValidationError {
file: File; // Файл, который не прошёл проверку
errors: string[]; // Массив сообщений об ошибках
}

Встроенные правила валидации

Dropup включает общие правила валидации:

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

useDropup({
customRules: [
commonRules.noExecutables, // Блокировать .exe, .bat и т.д.
commonRules.noHiddenFiles, // Блокировать файлы, начинающиеся с .
commonRules.maxFilenameLength(50),
commonRules.allowedExtensions(['.jpg', '.png', '.pdf']),
],
});

Обратная связь при перетаскивании

Предоставьте визуальную обратную связь при перетаскивании:

function DropZone() {
const { getDropProps, state } = useDropup({
accept: 'image/*',
});

// state.isDragAccept - файлы соответствуют критериям accept
// state.isDragReject - файлы не соответствуют

return (
<div
{...getDropProps()}
style={{
borderColor: state.isDragAccept
? 'green'
: state.isDragReject
? 'red'
: 'gray',
}}
>
{state.isDragReject && <p>Тип файла не поддерживается!</p>}
</div>
);
}

Полный пример валидации

import { useDropup, commonRules } from '@samithahansaka/dropup';

function SecureUploader() {
const { files, state, getDropProps, getInputProps } = useDropup({
// Тип файла
accept: ['image/jpeg', 'image/png', 'application/pdf'],

// Ограничения размера
maxSize: 10 * 1024 * 1024, // 10МБ
minSize: 100, // 100 байт (предотвратить пустые файлы)

// Ограничение количества
maxFiles: 10,

// Размеры изображений (только для изображений)
maxWidth: 8000,
maxHeight: 8000,

// Пользовательские правила
customRules: [
commonRules.noExecutables,
commonRules.maxFilenameLength(100),

// Пользовательское: без пробелов в имени
(file) => {
if (file.name.includes(' ')) {
return 'Имя файла не может содержать пробелы';
}
return true;
},
],

// Обработка ошибок
onValidationError: (errors) => {
errors.forEach(({ file, errors }) => {
alert(`${file.name}: ${errors.join(', ')}`);
});
},
});

return (
<div
{...getDropProps()}
className={`dropzone ${
state.isDragReject ? 'reject' : state.isDragAccept ? 'accept' : ''
}`}
>
<input {...getInputProps()} />
{state.isDragReject ? (
<p>❌ Некоторые файлы будут отклонены</p>
) : (
<p>📁 Перетащите файлы сюда (только JPEG, PNG, PDF, макс. 10МБ)</p>
)}
</div>
);
}