対象読者
- JavaScriptとWeb開発の基礎に理解がある方
- Reactを用いたJavaScriptアプリケーション開発の経験者
前提環境
筆者の検証環境は以下の通りです。
- macOS Big Sur 11.4
- Node.js 16.2.0/npm 7.13.0
- React 17.0.2
- react-scripts 4.0.3
- Material-UI 4.11.4
まだまだ広大なMaterial-UIの世界
前回も確認した通り、Material-UIの公式ドキュメントを見ると、7つのジャンルのコンポーネントがあります。
- Layout:レイアウトのためのコンポーネント
- Inputs:入力のためのコンポーネント
- Navigation:ナビゲーションに関するコンポーネント
- Surfaces:任意のコンポーネントを載せるためのコンポーネント
- Feedback:フィードバックのためのコンポーネント
- Data Display:データ表示のためのコンポーネント
- Utils:各種の便利なコンポーネント
前回は初めの3つ、Layout、Inputs、Navigationについて解説しました。今回は、後半のSurface、Feedback、Data Display、Utilsを確認していきましょう。
任意のコンポーネントを載せるためのコンポーネント
まずは、地味ながら利用シーンが多い、任意のコンポーネントを載せるためのコンポーネントです(表1)。
| コンポーネント | 概要 |
|---|---|
| App Bar | ヘッダーを表示する。 |
| Paper | 浮かび具合を調整できる「紙」を表示する。 |
| Card | カスタマイズ可能なカードを表示する。 |
| Accordion | 開閉するUIを表示する。 |
Material Designは、「紙とインク」といった私たちもよく知る物体(マテリアル)の振る舞いを模倣して作られたデザイン仕様です。前回解説したボタンなども「インクで染められた紙」というモチーフで作られています。Paperコンポーネントはこのデザイン仕様の中で最小の構成要素です。自作のコンポーネントでも、Paperの中に画像などを表示すれば、おのずと「Material Designらしさ」が出ることでしょう。App Bar、Card、Accordionは、ただのPaperよりも少しだけ情報を見やすくカスタマイズしたものになります。
Material-UIのもっとも基本的なコンポーネントということで、Paperの挙動を確認してみましょう。Paperは「ちょっと浮いている紙」なので、浮かび具合(elevation)を属性として指定できます(リスト1)。
<Paper elevation={0}>elevation: 0</Paper>
<Paper>elevation: default</Paper>
<Paper elevation={3}>elevation: 3</Paper>
リスト1のJSXを実際に表示すると、図1のようになります。
elevationが大きいほど浮かび上がって影が大きくなり、elevationがゼロだと背景とくっついて影がない状態になります。elevationを指定しない場合のデフォルト値はelevation={1}です。
Paperにできることはほとんどこれだけで、このままではあまり役に立たないようにも見えますね。しかし、Material-UIのコンポーネントの多くは、このPaperをカスタマイズしたり、内部のコンテンツ(children)を充実させたりする形で作られています。もしMaterial-UIに用意されていないコンポーネントを自作したくなった場合には、Paperを使ってみるといいかもしれません。
フィードバックのためのコンポーネント
続いて、フィードバックのためのコンポーネントです(表2)。
| コンポーネント | 概要 |
|---|---|
| Progress | 回転やゲージの形で読み込み中のUIを表示する。 |
| Dialog | ダイアログを表示する。 |
| Snackbar | 下からポップアップするメッセージを表示する。 |
| Backdrop | 画面全体を暗くした領域を提供する。 |
ユーザーが操作(送信ボタンのクリックなど)を行ったときに、その処理の結果をすぐに返せないことがあります。それは「処理しているからちょっと待ってて」というケースかもしれませんし、処理を実行する前に「注意点があるけど本当にやる?」という問いかけが必要なケースかもしれません。何にせよ、ユーザーの操作に対して、アプリケーションはなんらかの反応を返す必要があります。そんなときに役立つのが、このフィードバックのためのコンポーネントです。
Material-UIのProgressは何種類かありますが、よく使うのは、円形で回転するCircularProgressと、横棒がアニメーションするLinearProgressでしょうか(リスト2)。
{/* 回転する */}
<CircularProgress />
{/* 横棒がアニメーションする */}
<LinearProgress />
{/* 進捗を指定できる */}
<LinearProgress variant="determinate" value={60} />{/* (1) */}
基本的には設置するだけで使えますが、LinearProgressは(1)のようにvariant="determinate"属性を指定することで、進捗を直接指定できます。value属性に0から100までの数値を入力すると、その割合まで色が付きます。実際にリスト2のコードを動かしてみると、図2のようになります。
一番下の横棒にはvalue={60}を指定してあるので、60%の進捗率を表示していますね。もし進捗率がわかる場合にはユーザーにも見せてあげたほうが親切なので、useStateなどで管理している進捗率の値を value属性に当てはめるとよいでしょう。
もう一つ、 使い方を覚えると便利なものとして、Snackbarについても解説しておきましょう。Snackbarは、送信処理の完了時などにしたからポップアップしてくるUIです。リスト3のように利用します。
const SnackbarSample = () => {
const [ show, setShow ] = useState(false);
const handleButtonClick = () => {
setShow(true);
};
const handleClose = () => {
setShow(false); // (5)
};
return (
<div>
<Button onClick={handleButtonClick} variant="contained">
Snackbarを表示する
</Button>
<Snackbar
open={show}{/* (1) */}
autoHideDuration={6000}{/* (3) */}
onClose={handleClose}{/* (4) */}
message="処理が完了しました!"{/* (2) */}
/>
</div>
)
};
Snackbarは(1)のopen属性がtrueの間だけ(2)のmessage属性に設定したテキストを表示します。ですが、ポップアップというからには、わざわざ消さなくても一定時間が経ったら消えてほしいですよね。そのために用意されている属性が、(3)のautoHideDuration属性です。ミリ秒で時間を設定すると、表示してからその時間の経過後に、(4)のonCloseに登録されたコールバックを呼び出します。コールバックの中で(5)のように、open属性へfalseを渡せるような状態変更を行うことで、Snackbarを自動で閉じる挙動が実現できるのです。リスト3を実際に動かしてみると、図3のようになります。
ボタンを押すと、画面下からメッセージがポップアップしてきます。ユーザーに一時的なメッセージを伝えたいときに便利なので、ぜひ活用しましょう。
