引き続き Material-UI を使ったプロトタイプ開発をしている.今回は Material-UI の Snackbars
コンポーネントをサンプルコードを参考に実装しながら理解を深めていく.スナックバー(Snackbars
)は Material Design に定義された UI で,画面上にメッセージを一時的に表示する場面で使う.例えば Gmail でメールを削除すると,画面左下に「スレッドをゴミ箱に移動しました。」と表示される.
なお,実装したサンプルコードは GitHub に公開してある.TypeScript で create-react-app
を実行してから実装を進めた.記事に載せるコードはポイントを限定し抜粋するため,実際にコード全体を見る場合は GitHub を参照して頂ければと!
$ create-react-app sandbox-material-ui-snackbars --typescript
Snackbars
コンポーネント
Snackbars
コンポーネントで使えるプロパティ一覧は以下のドキュメントに載っている.最初から多くのプロパティを実装すると混乱するため,Step By Step に整理していく.
anchorOrigin
/ message
/ open
プロパティ
まず,anchorOrigin
プロパティを使うと,スナックバーを表示する位置を指定できる.以下のように horizontal
3種類と vertical
2種類を組み合わせて指定する.
horizontal
left
center
right
vertical
top
bottom
message
プロパティは,スナックバーにメッセージを表示するために指定する.そして open
プロパティに true
を指定するとスナックバーが表示されるため,今回は handleClick()
を経由して React State open
を更新する.React Hooks を前提にするため useState()
を使う.プロパティを組み合わせると,以下のような実装になる.
const App: React.FC = () => { const [open, setOpen] = React.useState(false); const handleClick = () => { setOpen(true); }; return ( <div> <button onClick={handleClick}>Open Snackbar 😃</button> <Snackbar anchorOrigin={{ vertical: 'bottom', horizontal: 'left', }} open={open} message={<span id="message-id">This is Snackbar 🎃</span>} /> </div> ); }
実際に動作確認をする.画面左上に配置したボタンをクリックすると,画面左下にスナックバーを表示できる.
anchorOrigin
プロパティを以下のように指定すると,今度は画面右上にスナックバーを表示できる.
anchorOrigin={{ vertical: 'top', horizontal: 'right', }}
onClose
/ autoHideDuration
プロパティ
open
プロパティと onClose
プロパティを組み合わせることにより,表示したスナックバーを非表示にできる.onClose
プロパティには関数を指定するため,今回は handleClose()
を経由して React State open
を false
に更新する.
ただし,onClose
プロパティを発火するためには画面をクリックする必要があるため,自動的に非表示にするために autoHideDuration
プロパティを組み合わせる.autoHideDuration
プロパティは onClose
プロパティに指定した関数を実行する前の待機時間となり,単位は milliseconds となる.プロパティを組み合わせると,以下のような実装になる.今回は「5秒」で自動的に非表示になる.
const App: React.FC = () => { const [open, setOpen] = React.useState(false); const handleClick = () => { setOpen(true); }; const handleClose = (event: React.SyntheticEvent | React.MouseEvent, reason?: string) => { setOpen(false); }; return ( <div> <button onClick={handleClick}>Open Snackbar 😃</button> <Snackbar anchorOrigin={{ vertical: 'bottom', horizontal: 'left', }} open={open} autoHideDuration={5000} onClose={handleClose} message={<span id="message-id">This is Snackbar 🎃</span>} /> </div> ); }
onClose
プロパティの仕様を読むと,関数の引数に reason
があり,「発火理由」を以下の2種類から判断できるようになっている.ドキュメントを読んでも clickaway
の意味がわからず,自分なりに調べて挙動を理解できた.
timeout
:autoHideDuration
プロパティにより発火した場合clickaway
: スナックバー以外の適当な画面領域をクリックして発火した場合
よって,以下のように clickaway
の場合に React State open
を false
に更新しないように早期リターンをすると,適当な画面領域をクリックする影響を抑止できる.多くの UI で考慮するべきポイントだと思う.
const handleClose = (event: React.SyntheticEvent | React.MouseEvent, reason?: string) => { if (reason === 'clickaway') { return; } setOpen(false); };
action
プロパティ
action
プロパティを指定すると,スナックバーから発火できる追加のアクションを指定できる.以下に抜粋した実装のように Button
コンポーネントと IconButton
コンポーネントを指定すると,Gmail などでよく見るスナックバーになる.デザインは今回も makeStyles()
を定義している(GitHub 参照).
<Snackbar anchorOrigin={{ vertical: 'bottom', horizontal: 'left', }} open={open} autoHideDuration={5000} onClose={handleClose} message={<span id="message-id">This is Snackbar 🎃</span>} action={[ <Button color="secondary" size="medium" onClick={handleClose}>取り消し</Button>, <IconButton key="close" aria-label="close" color="inherit" className={classes.close} onClick={handleClose} > <CloseIcon /> </IconButton>, ]} />
まとめ
Material-UI の Snackbars
コンポーネントを実装しながら理解を深めた.ドキュメントに載っているサンプルコードは TypeScript にも対応しているし,React Hooks にも対応しているため,合わせて学べてお得感もある.まだまだコンポーネントが多くあるため,引き続き使っていこうと思う.