ファイルハンドリング
Dropupは、ファイルが選択された瞬間からアップロードされるまで、シームレスな体験を提供します。
ファイル選択方法
ドラッグ&ドロップ
getDropProps()を使用して、任意の要素でドラッグ&ドロップを有効にします:
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 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
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, // 5MBチャンク
}),
});
詳細はチャンクアップロードを参照してください。