kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Material-UI の GridList コンポーネントを実装する

前回の記事から少し時間がたってしまったけど,Material-UI を使ったプロトタイプ開発を続けている.今回は GridList コンポーネントをサンプルコードを参考に実装しながら理解を深めていく.グリッドリストはフォトリストのようにコンテンツを並べる UI のことを言う.過去には List コンポーネントと Snackbars コンポーネントの記事を書いていて,コンポーネントの調査シリーズも定期的に書いていく.

material-ui.com

なお,実装したサンプルコードは GitHub に公開してある.TypeScript で create-react-app を実行してから実装を進めた.記事に載せるコードはポイントを限定し抜粋するため,実際にコード全体を見る場合は GitHub を参照して頂ければと!

$ create-react-app sandbox-material-ui-grid-list --template typescript
$ cd sandbox-material-ui-grid-list

$ npm install @material-ui/core
$ npm install @material-ui/icons

$ yarn start

github.com

今までは create-react-app --typescript を使っていたけど,最新版の v3.3.0 から以下の警告が出るようになっていた.--typescript オプションは廃止になり,今後は create-react-app --template typescript を使う必要がある.覚えておこう.

The --typescript option has been deprecated and will be removed in a future release.
In future, please use --template typescript.

GridList コンポーネント

GridList コンポーネントはグリッドリストの「全体枠」を定義する.

主要なパラメータは2個ある.まず,cellHeight プロパティを使うと,グリッドリストの「高さ」を設定できる.ピクセル固定もできるし,自動なら auto も設定できる.次に,cols プロパティを使うと,グリッドリストの「タイル数(横)」を設定できる.GridList コンポーネントで使えるプロパティ一覧は以下のドキュメントに載っている.

material-ui.com

サンプルコードの一部を載せておく.

const App: React.FC = () => {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <GridList cellHeight={200} className={classes.gridList} cols={3}>
      </GridList>
    </div>
  );
}

GridListTile コンポーネント

GridListTile コンポーネントはグリッドリストの「タイル」を定義する.

GridList コンポーネントと GridListTile コンポーネントを組み合わせることにより,「全体枠」の中に「タイル」を配置できる.GridList 側で設定した cols に対して,GridListTile 側でさらに cols を設定できる.cols="1" にすれば「等間隔にタイルを敷き詰める」ことができるし,cols="1"cols="2" を組み合わせれば「特定のタイルのサイズを変える」こともできる.GridListTile コンポーネントで使えるプロパティ一覧は以下のドキュメントに載っている.

material-ui.com

サンプルコードの一部を載せておく.

const App: React.FC = () => {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <GridList cellHeight={200} className={classes.gridList} cols={3}>
        <GridListTile key="cat" cols="2">
          <img src={cat} alt="cat" />
        </GridListTile>
        <GridListTile key="deer" cols="1">
          <img src={deer} alt="deer" />
        </GridListTile>
        <GridListTile key="kingfisher" cols="1">
          <img src={kingfisher} alt="kingfisher" />
        </GridListTile>
        <GridListTile key="koala" cols="1">
          <img src={koala} alt="koala" />
        </GridListTile>
        <GridListTile key="pelikan" cols="1">
          <img src={pelikan} alt="pelikan" />
        </GridListTile>
        <GridListTile key="rabbit" cols="1">
          <img src={rabbit} alt="rabbit" />
        </GridListTile>
        <GridListTile key="tiger" cols="2">
          <img src={tiger} alt="tiger" />
        </GridListTile>
      </GridList>
    </div>
  );
}

実際に動作確認をすると,cols="2" に設定したネコとトラは2タイルを結合したサイズになっている.なお,動物の素材は Pixabay から取得している.

f:id:kakku22:20200112123227p:plain

GridListTileBar コンポーネント

GridListTileBar コンポーネントはタイルの上に表示する「追加情報」を定義する.

主要なパラメータは3個ある.まず,titlesubtitle を使うと追加情報をタイルの上に表示できる.さらに,actionIcon を使うと「ボタンを押したら○○」というトリガーの実装と連携することもできる.GridListTileBar コンポーネントで使えるプロパティ一覧は以下のドキュメントに載っている.

material-ui.com

サンプルコードの一部を載せておく.titletitle + subtitletitle + subtitle + actionIcon の計3パターンを実装した.

const App: React.FC = () => {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <GridList cellHeight={200} className={classes.gridList} cols={3}>
        <GridListTile key="cat" cols="2">
          <img src={cat} alt="cat" />
          <GridListTileBar
            title="Cat"
          />
        </GridListTile>

        {/* 中略 */}

        <GridListTile key="koala" cols="1">
          <img src={koala} alt="koala" />
          <GridListTileBar
            title="Koala"
            subtitle="So Cute !"
          />
        </GridListTile>

        {/* 中略 */}

        <GridListTile key="tiger" cols="2">
          <img src={tiger} alt="tiger" />
          <GridListTileBar
            title="Tiger"
            subtitle="So Cool !"
            actionIcon={
              <IconButton className={classes.icon}>
                <InfoIcon />
              </IconButton>
            }
          />
        </GridListTile>
      </GridList>
    </div>
  );
}

実際に動作確認をすると,ネコとコアラとトラに追加情報が表示されている.

f:id:kakku22:20200112123308p:plain

ListSubheader コンポーネント

ListSubheader コンポーネントはグリッドリストの中に「区切り」を定義する.

GridListTile コンポーネントの中に ListSubheader コンポーネントを含めるため,サイズなどは GridListTile コンポーネントの cols プロパティを使う.ListSubheader コンポーネントで使えるプロパティ一覧は以下のドキュメントに載っている.

material-ui.com

サンプルコードの一部を載せておく.写真を撮影した年を区切りとして追加した.

const App: React.FC = () => {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <GridList cellHeight={200} className={classes.gridList} cols={3}>
        <GridListTile key="Subheader" cols={3} style={{ height: 'auto' }}>
          <ListSubheader component="div">2018</ListSubheader>
        </GridListTile>
        <GridListTile key="cat" cols="2">
          <img src={cat} alt="cat" />
          <GridListTileBar
            title="Cat"
          />
        </GridListTile>
        <GridListTile key="deer" cols="1">
          <img src={deer} alt="deer" />
        </GridListTile>

        {/* 中略 */}

        <GridListTile key="Subheader" cols={3} style={{ height: 'auto' }}>
          <ListSubheader component="div">2019</ListSubheader>
        </GridListTile>
        <GridListTile key="rabbit" cols="1">
          <img src={rabbit} alt="rabbit" />
        </GridListTile>
        <GridListTile key="tiger" cols="2">
          <img src={tiger} alt="tiger" />
          <GridListTileBar
            title="Tiger"
            subtitle="So Cool !"
            actionIcon={
              <IconButton className={classes.icon}>
                <InfoIcon />
              </IconButton>
            }
          />
        </GridListTile>
      </GridList>
    </div>
  );
}

実際に動作確認をすると,2018年の区切り(ヘッダー)と2019年の区切り(ヘッダー)が表示されている.

f:id:kakku22:20200112123336p:plain

まとめ

Material-UIGridList コンポーネントを実装しながら理解を深めた.コード量を少なくグリッドリストの実装ができて便利だった.引き続きコンポーネント調査を続けていくぞ!

Material-UI 関連記事

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com