メインコンテンツまでスキップ

ファイル検証

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/jpegPNGとJPEGのみ
video/*すべての動画
audio/*すべての音声ファイル
application/pdfPDFファイルのみ
.doc, .docxWord文書
*/*すべてのファイル(デフォルト)

ファイルサイズ制限

useDropup({
maxSize: 10 * 1024 * 1024, // 最大10MB
minSize: 1024, // 最小1KB
});

ファイル数制限

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 - ファイルが受け入れ条件に一致
// 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, // 10MB
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のみ、最大10MB)</p>
)}
</div>
);
}