ファイルアップロードUIライブラリ比較

3つのアプローチでドラッグ&ドロップ対応のファイルアップロードUIを実装し、機能とスタイルを比較

共通の動作仕様

各デモではドラッグ&ドロップまたはクリックでファイルを選択できます。アップロードはシミュレーション(擬似処理)で、プログレスバーが進行します。

{
  "対応ファイル": ["画像 (PNG/JPG/GIF/WebP)", "PDF", "テキスト", "CSV"],
  "最大サイズ": "10MB",
  "複数ファイル": true,
  "アップロード": "シミュレーション(デモ用擬似プログレス)"
}

1. react-dropzone

軽量なドラッグ&ドロップフック — UIは自由にカスタマイズ可能なヘッドレス設計

特徴

  • • React Hooksベースでシンプルに統合
  • • ファイル種別・サイズのバリデーション内蔵
  • • ドロップゾーンのUI/スタイルは完全にカスタム
  • • バンドルサイズが非常に小さい(~8KB gzipped)

インストール

npm install react-dropzone
tsx
'use client';
import { useDropzone } from 'react-dropzone';
import { useState, useCallback } from 'react';

export function ReactDropzoneDemo() {
  const [files, setFiles] = useState<File[]>([]);

  const onDrop = useCallback((accepted: File[]) => {
    setFiles(prev => [...prev, ...accepted]);
  }, []);

  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });

  return (
    <div>
      <div
        {...getRootProps()}
        className={`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${
          isDragActive ? 'border-blue-500 bg-blue-50' : 'border-gray-300 hover:border-gray-400'
        }`}
      >
        <input {...getInputProps()} />
        <p className="text-gray-500 text-sm">
          {isDragActive ? 'ここにドロップ' : 'クリックまたはドラッグ&ドロップでファイルを選択'}
        </p>
      </div>
      {files.length > 0 && (
        <ul className="mt-4 space-y-2">
          {files.map((f, i) => (
            <li key={i} className="flex items-center gap-2 text-sm text-gray-700">
              <span>📎</span>
              <span>{f.name}</span>
              <span className="text-gray-400">({(f.size / 1024).toFixed(1)} KB)</span>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

🤖 AIプロンプトテンプレート

React + Tailwind CSSで、react-dropzoneを使ったドラッグ&ドロップファイルアップロードUIを実装してください。
- 使用ライブラリ: react-dropzone(useDropzone フック)
- useDropzone の onDrop、accept、maxSize プロパティでファイル受け取りとバリデーションを設定すること
- getRootProps/getInputProps をドロップゾーンのdivとinputに適用すること
- isDragActive でドラッグ中のスタイルを切り替えること
- 各ファイルのアップロード状態(pending/uploading/complete)とプログレスをstateで管理すること
- ドラッグ&ドロップとクリックによるファイル選択の両方に対応すること
- ファイル削除ボタンとアップロード済みファイルのリスト表示を実装すること

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

2. FilePond (react-filepond)

美しいUI内蔵のファイルアップロード — プログレス・プレビュー・アニメーション付き

最大5ファイルまで。画像、PDF、テキストファイルに対応

特徴

  • • 洗練されたUIとアニメーションが標準搭載
  • • 画像プレビュー・ファイル検証プラグインが豊富
  • • アップロード中のプログレス表示が美しい
  • • ドラッグ&ドロップ・ペースト・ブラウズに対応

インストール

npm install filepond react-filepond filepond-plugin-file-validate-type filepond-plugin-image-preview
tsx
'use client';
import { FilePond, registerPlugin } from 'react-filepond';
import 'filepond/dist/filepond.min.css';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css';
import { useState } from 'react';

registerPlugin(FilePondPluginImagePreview);

export function FilePondDemo() {
  const [files, setFiles] = useState<File[]>([]);

  return (
    <FilePond
      files={files}
      onupdatefiles={items => setFiles(items.map(i => i.file as File))}
      allowMultiple={true}
      labelIdle='ファイルをドラッグ&ドロップ、または <span class="filepond--label-action">ブラウズ</span>'
    />
  );
}

🤖 AIプロンプトテンプレート

React + Tailwind CSSで、FilePond(react-filepond)を使ったファイルアップロードUIを実装してください。
- 使用ライブラリ: filepond、react-filepond、filepond-plugin-file-validate-type、filepond-plugin-image-preview
- FilePond コンポーネントと registerPlugin でプラグインを登録すること
- allowMultiple={true}、maxFiles={5}、acceptedFileTypes でファイル制限を設定すること
- server プロパティの process 関数でアップロードのシミュレーション(擬似プログレス)を実装すること
- labelIdle、labelFileProcessing など日本語ラベルを設定すること
- credits={false} でFilePondクレジット表示を非表示にすること

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

3. カスタム実装(React + Tailwind CSS)

ライブラリ不要の完全カスタム実装 — 全体プログレスバー・リトライ・ファイル一覧を自作

ドラッグ&ドロップでアップロード

またはクリックしてファイルを選択

画像PDFテキストCSV

特徴

  • • 外部ライブラリ不要で依存関係が最小限
  • • 全体のプログレス表示・個別のプログレス表示
  • • ドラッグオーバー時のオーバーレイ演出
  • • リトライ機能・ファイル一覧の管理

インストール

追加パッケージ不要(React + Tailwind CSS のみ)
tsx
'use client';
import { useState, useCallback } from 'react';

export function CustomUploadDemo() {
  const [files, setFiles] = useState<{ name: string; size: number }[]>([]);
  const [isDragging, setIsDragging] = useState(false);

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
    const dropped = Array.from(e.dataTransfer.files);
    setFiles(prev => [...prev, ...dropped.map(f => ({ name: f.name, size: f.size }))]);
  }, []);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const selected = Array.from(e.target.files ?? []);
    setFiles(prev => [...prev, ...selected.map(f => ({ name: f.name, size: f.size }))]);
  };

  return (
    <div>
      <label
        onDragOver={e => { e.preventDefault(); setIsDragging(true); }}
        onDragLeave={() => setIsDragging(false)}
        onDrop={handleDrop}
        className={`block border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${
          isDragging ? 'border-emerald-500 bg-emerald-50' : 'border-gray-300 hover:border-gray-400'
        }`}
      >
        <input type="file" multiple className="hidden" onChange={handleChange} />
        <p className="text-gray-500 text-sm">クリックまたはドラッグ&ドロップ</p>
      </label>
      {files.length > 0 && (
        <ul className="mt-4 space-y-2">
          {files.map((f, i) => (
            <li key={i} className="flex items-center justify-between text-sm p-2 bg-gray-50 rounded">
              <span>{f.name}</span>
              <span className="text-gray-400">{(f.size / 1024).toFixed(1)} KB</span>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

🤖 AIプロンプトテンプレート

React + Tailwind CSSで、ライブラリ不要のカスタムファイルアップロードUIを実装してください。
- 使用ライブラリ: React + Tailwind CSS のみ(外部アップロードライブラリなし)
- onDragEnter/onDragLeave/onDrop イベントハンドラーを自作してドロップゾーンを実装すること
- dragCountRef(useRef)で dragEnter/dragLeave のカウントを管理し、子要素への移動で非表示にならないよう制御すること
- ファイルごとのプログレスバーと全ファイルの全体プログレスバーの2段階表示を実装すること
- ドラッグオーバー時にオーバーレイを表示すること
- ファイル削除ボタンとリトライ機能を実装すること
- ファイル種別に応じた絵文字アイコンとファイルサイズの書式化表示を実装すること

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

ライブラリ比較表

項目react-dropzoneFilePondカスタム実装
ドラッグ&ドロップ内蔵内蔵自作
プログレス表示自作内蔵(美麗)自作
画像プレビュー自作プラグイン提供自作
ファイル検証内蔵プラグイン提供自作
UIデザインヘッドレス(自作)内蔵(美麗)完全カスタム
バンドルサイズ小さい(~8KB)中程度(~40KB)最小
学習コスト低〜中中〜高(要件次第)
おすすめ用途独自UIのアップロード美しいUIが必要な場合シンプルな要件

まとめ

react-dropzone — ドラッグ&ドロップのロジックだけを提供するヘッドレス設計。独自のデザインシステムに合わせたアップロードUIを構築したい場合に最適。

FilePond — 洗練されたUIとアニメーションが標準搭載。画像プレビューやプログレス表示など、美しいアップロード体験を素早く実装したい場合におすすめ。

カスタム実装 — 外部ライブラリに依存せず、全体プログレスやリトライ機能など細かいUX制御をしたい場合に最適。