はじめに
「ファイルアップロードのUIだけ、なぜか毎回時間を溶かしてしまう」——そんな経験はないでしょうか。素の <input type="file"> はそっけない見た目ですし、ドラッグ&ドロップ対応、画像プレビュー、複数ファイル選択、進捗表示、バリデーションと機能を積み上げていくと、あっという間に自前実装が肥大化してしまいます。
FilePondは、こうした「地味だけど面倒」なファイルアップロードUIを、宣言的な設定とプラグインの組み合わせだけで解決してくれるJavaScriptライブラリです。今回はFilePondの特徴から、ブラウザ上で実際に動かせるサンプルを交えた実践的な使い方までを紹介します。
FilePondとは
FilePondは、PQINAが開発しているファイルアップロード用のJavaScriptライブラリです。フレームワークに依存しないコアライブラリに加えて、React・Vue・Angular・Svelte向けの公式アダプターも用意されており、既存のプロジェクトに組み込みやすいのが特徴です。
主な特徴
- ドラッグ&ドロップとクリック選択の両対応 - 特別な実装なしにモダンなアップロードUIが手に入ります
- 豊富なプラグイン群 - 画像プレビュー、画像編集、ファイルタイプ・サイズのバリデーションなど、必要な機能だけを組み合わせられます
- なめらかなアニメーション - ファイルの追加・削除・並び替えがアニメーション付きで表示され、ユーザー体験を損ないません
- 柔軟なサーバー連携 -
process/revert/loadなどのフックを自分で実装でき、アップロード先のAPI仕様に合わせて自由にカスタマイズできます - アクセシビリティ対応 - キーボード操作やスクリーンリーダーにも配慮された実装になっています
インストール
npmから core パッケージをインストールします。
npm install filepond
画像プレビューやバリデーションなど、必要に応じてプラグインを追加します。
npm install filepond-plugin-image-preview filepond-plugin-file-validate-type
Reactで使う場合は公式アダプターも利用できます。
npm install react-filepond
FilePondの基本的な使い方
FilePondは対象の <input type="file"> 要素を FilePond.create() に渡すだけで、ドラッグ&ドロップ対応のアップロードUIに変換してくれます。まずは最小構成で動かしてみましょう。要点は次のとおりで、FilePond.create() の第2引数に渡すオプションオブジェクトの labelIdle で、初期表示のテキストをHTML付きで指定できます。
import * as FilePond from 'filepond'
// <input type="file" id="pond" /> をFilePondのUIに変換する
FilePond.create(document.getElementById('pond'), {
labelIdle:
'ファイルをドラッグ&ドロップ、または<span class="filepond--label-action">選択</span>',
})
実際にブラウザ上で動かせるサンプルが以下です。ファイルをドラッグ&ドロップしたり、クリックして選択したりして挙動を確認してみてください。
たったこれだけで、ドラッグ&ドロップ・クリック選択・ファイルの削除アニメーションまで一通り揃ったUIが完成します。labelIdle の文字列を書き換えると、待受表示のテキストや装飾を自由に変更できます。試しに絵文字を混ぜたり、<span class="filepond--label-action"> の部分を別の言葉に変えたりすると、UIの見た目がその場で変わることが確認できます。
実践的なユースケース
FilePondの画像プレビュー付きアップロード
画像ファイルを扱う場面では、選択直後にサムネイルを表示できると利便性が大きく上がります。FilePondの filepond-plugin-image-preview と filepond-plugin-file-validate-type というプラグインを FilePond.registerPlugin() で登録すれば、画像プレビューとファイル形式のバリデーションを同時に実現できます。要点だけを抜き出すと次のようになります。
import * as FilePond from 'filepond'
import FilePondPluginImagePreview from 'filepond-plugin-image-preview'
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type'
// 画像プレビューとファイル形式バリデーションのプラグインを登録する
FilePond.registerPlugin(FilePondPluginImagePreview, FilePondPluginFileValidateType)
FilePond.create(document.getElementById('pond'), {
acceptedFileTypes: ['image/png', 'image/jpeg'],
labelFileTypeNotAllowed: 'PNGまたはJPEG画像のみ選択できます',
})
実際に画像を選択してプレビューが表示される様子を確認できるサンプルが以下です。
画像を選択すると、その場でサムネイルが表示されるのが分かります。対応していない形式のファイルを選ぶと、バリデーションメッセージが表示されます。acceptedFileTypes の配列に 'image/gif' などを追加すると許可するファイル形式を増やせますし、labelFileTypeNotAllowed の文言を書き換えれば、エラーメッセージの表示内容も変わります。
FilePondのアップロード進捗表示
実際のアップロードでは、サーバーへ送信中の進捗をユーザーに示したいものです。FilePondは server.process フックに関数を渡すことで、進捗の通知やアップロードの中断処理を自由に実装できます。ここではサーバー通信の代わりに、擬似的な進捗を発生させています。要点は次のとおりです。
import * as FilePond from 'filepond'
FilePond.create(document.getElementById('pond'), {
server: {
// fieldName, file, metadata, load, error, progress, abort の順で受け取る
process: (fieldName, file, metadata, load, error, progress, abort) => {
let sent = 0
const timer = setInterval(() => {
sent += 20
progress(true, sent, 100) // アップロード進捗を通知する
if (sent >= 100) {
clearInterval(timer)
load(String(Date.now())) // 完了を通知する
}
}, 200)
return { abort: () => clearInterval(timer) }
},
},
})
実際にブラウザで進捗バーの動きを確認できるサンプルが以下です。
ファイルを追加すると、擬似的なアップロードバーが進んでいく様子が確認できます。実際のプロジェクトでは、この process 関数の中で fetch などを使ってサーバーにファイルを送信し、レスポンスに応じて load・error を呼び出す形になります。setInterval の間隔(200)を短くしたり、sent += 20 の増分を大きくしたりすると、プログレスバーが進む速さが変わります。
FilePondの複数ファイル選択と並び替え
複数の画像をまとめてアップロードするフォームでは、選択後に順序を入れ替えたい、上限数を設けたいといった要望がよくあります。FilePondの allowMultiple・maxFiles・allowReorder というオプションを組み合わせるだけで対応できます。要点は次のとおりです。
import * as FilePond from 'filepond'
FilePond.create(document.getElementById('pond'), {
allowMultiple: true, // 複数ファイルの選択を許可する
allowReorder: true, // ドラッグでの並び替えを許可する
maxFiles: 3, // 選択できる上限数
labelMaxFileSizeExceeded: 'ファイルサイズが大きすぎます',
})
実際に複数ファイルを選択して並び替えられる様子を確認できるサンプルが以下です。
3ファイルまで選択でき、追加したファイルはドラッグで並び替えられます。上限を超えて選択しようとすると自動的に制限されます。maxFiles の値を増減させると選択できる上限数が変わり、allowMultiple を false にすると単一ファイルのみの選択に制限できます。
まとめ
FilePondを使うと、ドラッグ&ドロップ・画像プレビュー・進捗表示・複数ファイル管理といったファイルアップロードUIに必要な要素を、プラグインの組み合わせだけで手早く実装できます。素の <input type="file"> から自前で作り込んでいた処理をFilePondに任せることで、UIの実装コストを大きく減らし、本質的なサーバー連携部分に集中できるようになります。
まずは今回のサンプルを手元で編集しながら、プロジェクトに必要なプラグインを探してみてください。
