12
5

More than 3 years have passed since last update.

React Material-UI Snackbarのカスタマイズに挑戦した

Last updated at Posted at 2020-03-14

前提

React Material-UIのSnackbarコンポーネントアニメーションを自分好みにカスタマイズしてみまました。
React × Material-UIの記事が少ないので、内容コアですが、記事にしてみました。

Snackbar(スナックバー)とは

スナックバーは、実行プロセスをユーザーに通知するための表現です。
Image from Gyazo

こちらのスライドアニメーションのカスタマイズに挑戦します。

Snackbarコンポーネントの構造

Material-UIの構造の多くは、atom要素を構成しています。
今回のSnackbarも同様に、複数のatom要素でできています。

ReactのChrome拡張ツールなどでコンポーネント構造を見ると以下のようになっています。

<Snacbar>
  <ClickAwayListener>
    <Transition>
      <Slide> // デフォルトは<Grow>
        <SnackbarContent>

もちろん、利用時に、テキスト構造などSnackbarのコンポーネント内に渡してあげると構造は変化します。

APIについて

Snackbarコンポーネントに用意されたコンポーネントは主に以下があります。(公式サイト

  • action
    • スナックバーの最後にレンダリングされる要素
  • anchorOrigin
    • アンカー要素
  • autoHideDuration
    • スナックバーの表示時間
  • message
    • スナックバーに表示されるメッセージ
  • onClose
    • 閉じるリクエストが起こった場合のコールバック
  • open
    • 表示
  • TransitionComponent
    • トランジションに使用されるコンポーネント
  • TransitonProps
    • トランジション要素のプロパティ
  • transitonDuration
    • トランジション期間の設定

Snackbarの実装

特別な要素指定を行わずにSnackbarの組み込みをしてみました。


import React from 'react';
import Button from '@material-ui/core/Button';
import Snackbar from '@material-ui/core/Snackbar';
import Slide from '@material-ui/core/Slide';
import ClearIcon from '@material-ui/icons/Clear';

// FIXME:せっかくTransitionPropsプロパティあるのでそちらでdirection設定したい...
function Transition(props) {
  return <Slide {...props} direction="left" />;
}

export default function App() {
  const [open, setOpen] = React.useState(false);

  const handleOpen = () => {
    setOpen(true);
  };
  const handleClose = () => {
    setOpen(false)
  };

  return (
    <div className="App">
      <Button variant="contained" onClick={handleOpen}>Register</Button>
      <Snackbar
        open={open}
        message="Complete!"
        onClose={handleClose}
        TransitionComponent={Transition}
        action={<ClearIcon onClick={handleClose}/>}
      />
    </div>
  );
}

TransitionPropsがよくわからない

Slideコンポーネントの組み込み方が気持ち悪いですが、なせか、TransitionPropsがうまく効きませんでした...
(原因わかったり、対応方法見つけたらまたそのタイミングで...わかる方いましたらコメントいただけると嬉しいです。。)

コードについて

Buttonコンポーネントの押されたタイミングでスナックバーが表示されます。
Snackbaractionに閉じるアイコンを設置してonClickイベントでスナックバーを閉じれるように設定しています。

SnackbaronCloseオプションを指定して、いると、スナックバー外の要素アクションでも閉じるようです。

アニメーションカスタマイズ

スナックバーでTransitionComponentを指定しなければGrowコンポーネントが標準で用意されているようです。
上のコードではSlideコンポーネントを使って横から入ってくるようにしています。

標準のTransitionが動くと、結構モーションが速いので、少しゆっくりめにカスタマイズしてみます。

transitonDurationプロパティ

こちらのプロパティでenterexit指定で入ってくるモーションと、出ていくモーションの指定が行えます。


transitionDuration={{
  enter: 800,
  exit: 800,
}}

モーション指定を行った後のソースは以下です。


import React from 'react';
import Button from '@material-ui/core/Button';
import Snackbar from '@material-ui/core/Snackbar';
import Slide from '@material-ui/core/Slide';
import ClearIcon from '@material-ui/icons/Clear';

// FIXME:せっかくTransitionPropsプロパティあるのでそちらでdirection設定したい...
function Transition(props) {
  return <Slide {...props} direction="left" />;
}

export default function App() {
  const [open, setOpen] = React.useState(false);

  const handleOpen = () => {
    setOpen(true);
  };
  const handleClose = () => {
    setOpen(false)
  };

  return (
    <div className="App">
      <Button variant="contained" onClick={handleOpen}>Register</Button>
      <Snackbar
        open={open}
        message="Complete!"
        onClose={handleClose}
        TransitionComponent={Transition}
        transitionDuration={{
          enter: 800,
          exit: 800,
        }}
        action={<ClearIcon onClick={handleClose}/>}
      />
    </div>
  );
}

Image from Gyazo

アニメーションの変更ができました!

さいごに

Material-UIを使うと手軽に様々なモーション、インタラクションの活用ができてすごく便利ですが、そこに縛られてしまうこともあります。
この辺りの細かいオプションが用意されていればすごく利便性上がりますが、ここに苦しめられることも多くあります。

同じようなコンポーネントでも用途が違うコンポーネントとして用意されているものも多くあります。
皆さんはReact開発ではどんなコンポーネント開発行ってますか?是非聞かせて欲しい。。

2020/3/15 CodeSandbox リンク追加しました!

Edit material-ui-snackbar

12
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
5