KAEDE Hack blog

JavaScript 中心に ライブラリなどの使い方を解説する技術ブログ。

React Material-UIを使ってみた

why

職場のサイトを作ることになって,headerを作るのに採択した

medium.com

mediumを参考にする

npm install @material-ui/core --save

npm i contentful --save

import React from 'react'
import AppBar from '@material-ui/core/AppBar'
import Toolbar from '@material-ui/core/Toolbar'
import Typography from '@material-ui/core/Typography'
const NavBar = () => {
    return(
        <div>
        <AppBar position="static">
            <Toolbar>
                <Typography variant="title" color="inherit">
                React & Material-UI Sample Application
                </Typography>
            </Toolbar>
        </AppBar>
        </div>
    )
}
export default NavBar;

NavBarのコードをコピペ

dependenciesのpackage.jsonも含めてpushするとできた

だが公式ドキュメントを読んでも複雑で,自分で組み合わせられそうにない

github.com

これはこのまま使えるらしい?

mebee.info

github.com

これならそのままcopyして使えるらしいが,Starbarがresolveできなかった..消したら動いた.

Androidの情報が多い

ここからパーツのまとまりをみていく

material-ui/Pricing.js at master · mui-org/material-ui · GitHub

Appbarを見ると

      <AppBar position="static" color="default" elevation={0} className={classes.appBar}>
        <Toolbar className={classes.toolbar}>
          <Typography variant="h6" color="inherit" noWrap className={classes.toolbarTitle}>
            Company name
          </Typography>
          <nav>
            <Link variant="button" color="textPrimary" href="#" className={classes.link}>
              Features
            </Link>
            <Link variant="button" color="textPrimary" href="#" className={classes.link}>
              Enterprise
            </Link>
            <Link variant="button" color="textPrimary" href="#" className={classes.link}>
              Support
            </Link>
          </nav>
          <Button href="#" color="primary" variant="outlined" className={classes.link}>
            Login
          </Button>
        </Toolbar>
      </AppBar>

になっていて

AppBar, Toolbar, Typography, Link, Button,

が使われている,全てimportする

classNameが必要,useStylesでかなり定義されているからその

import { makeStyles } from '@material-ui/core/styles';

も入れて先に変数で宣言しておく必要がある

const useStyles = makeStyles((theme) => ({
  '@global': {
    ul: {
      margin: 0,
      padding: 0,
      listStyle: 'none',
    },
  },
  appBar: {
    borderBottom: `1px solid ${theme.palette.divider}`,
  },
.......

そしてfunction App()のなかに

const classes = useStyles();

これを宣言

もちろんこれも必要

npm install @material-ui/core

これでこのコードだけで

const useStyles = makeStyles((theme) => ({
  '@global': {
    ul: {
      margin: 0,
      padding: 0,
      listStyle: 'none',
    },
  },
  appBar: {
    borderBottom: `1px solid ${theme.palette.divider}`,
  },
  toolbar: {
    flexWrap: 'wrap',
  },
  toolbarTitle: {
    flexGrow: 1,
  },
  link: {
    margin: theme.spacing(1, 1.5),
  },
}));

function App() {
  const classes = useStyles();
  return (

このheaderが実装できた

f:id:kei_s_lifehack:20200504160948p:plain

ではこのUIを動かしてみよう.サンプルテンプレを見せて言われたのはheaderが小さい,文字が小さいだったからそれを変えてみる

下記では全て変化がない.

  appBar: {
    padding: '100px',
  },
    minHeight: 300,

    paddingTop: theme.spacing(5),

      <AppBar position="static" color="default" elevation={0}
        height='201%' >

ul globalのpaddingを消してもダメだ

この数値を変えたら動いた!

  link: {
    margin: theme.spacing(1, 1.5),
  },

だが,Appbarに適用しても変化がない

defaultの大きさはこれだ

f:id:kei_s_lifehack:20200504170502p:plain

そもそもAppbar, Toolbar, ToolbarTitle, linkの関係性ってなんだ?

とりあえずlink全てにmgnを渡すことによってくっつくことをpreventしている

toolbarでspacingの2nd argを増やすと左に寄る (mgn rightか?)

    margin: theme.spacing(0, 20),

f:id:kei_s_lifehack:20200504170619p:plain

この時tool titleのいちは変わらないから,この二つは独立している.

当然1st argを増やすと下に膨らむ.

margin: theme.spacing(20, 0),

[f:id:kei_s_lifehack:20200504170731p:plain]

よってこれでheader barの大きさを調整できる.

次は左側にlogoを仕込みたい.

なぜCompany nameが真ん中になっているのかは

TypograhyとLinkの違いだ

[http://yucatio.hatenablog.com/entry/2018/12/20/090547:embed:cite]

このサイトを見るとLinkにlogоを入れて

      <Link to='/'>
        <img src={logo} alt="TODODO(トドド)" height="36" width="auto"/>
      </Link>

inlineで大きさを調整している

このサイトを見ると

www.reddit.com

import AppBar from "@material-ui/core/AppBar";
import Grid from "@material-ui/core/Grid";
import { makeStyles } from "@material-ui/core/styles";
import Toolbar from "@material-ui/core/Toolbar";
import React from "react";
import { Tabs } from "@material-ui/core";
import Tab from "@material-ui/core/Tab";

const useStyles = makeStyles({
  root: {
    flexGrow: 1
  },
  logo: {
    width: 135,
    height: 43.54
  }
});

const Header = () => {
  const classes = useStyles();
  const [value, setValue] = React.useState(0);

  return (
    <nav className={classes.root}>
      <AppBar position="static" color="default">
        <Toolbar>
          <Grid justify={"space-between"} container>
            <Grid xs={1} item>
              <img
                className={classes.logo}
                src={
                  "https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg"
                }
                alt="Bosch Logo"
              />
            </Grid>
            <Grid xs={4} item>
              <Grid container justify={"center"}>
                <Tabs
                  onChange={(e, v) => setValue(v)}
                  value={value}
                  aria-label="Navigation Tabs"
                >
                  <Tab label={"page 1"} />
                  <Tab label={"page 2"} />
                </Tabs>
              </Grid>
            </Grid>
            <Grid item xs={1} />
          </Grid>
        </Toolbar>
      </AppBar>
    </nav>
  );
};

export default Header;

Grid xs 1, 4, で割合を調節してるっぽい?

をコンテナとして

にimgのlogoをuseStylesでwidth: 135,height: 43.54, で入れて

それの後に

のなかに

を入れて

でlogic指定している中に

を二つ

その後に

で空間調整している.

だからこの調節コードを消すと

f:id:kei_s_lifehack:20200506205339p:plain

右にずらされる

f:id:kei_s_lifehack:20200507030306p:plain

よし!!と思ったが

f:id:kei_s_lifehack:20200507030447p:plain

自動でresponsiveにしてくれるわけではなかった....

このままではCorp Siteには採用できない

media queryごとにgiridで書くか???

Grid

blog.logrocket.com

この記事もわかりやすい

material-ui.com

f:id:kei_s_lifehack:20200507031148p:plain

とりあえずGridはわかりやすい.

f:id:kei_s_lifehack:20200507031246p:plain

ここを見るとflex-start, center, flex-endがよくわかる

headerで左右に分ける時はこれを分ければいいわけだ.

さっきのredditのcodeはspace-between でlogoを左において

距離をとって,flex-endでTabを右ヅメにしたわけだ.

また,paddingはtheme.spacing(2)で取るのが一般的らしい.

普通に入れるカードはPaper, 文字を入れるのはTypography.

自動でmedia queryをやってくれるGridは見つからなかったが

material-ui.com

Containerで幅をsm, smallに制限して

twicall.net

きゃりーさんの新作のように

元から狭い幅で作ってしまえば一つのlayoutですむかもしれない.

いや,流石にCorp Siteでこれは狭すぎるか....

Reactでmedia queryごとにcssを分けて書くのはどうやるんだろうか?

material.io

設計としてはこの記事がわかりやすい

table

f:id:kei_s_lifehack:20200507034036p:plain

Validateがうまくいっていればスマフォでもいい感じになるはずの

moneylogのこれは, bootstrap4のtable-responsiveで作ったが

Table React component - Material-UI

MUIには相当するものはなかった.

ただSortなど,使いこなせれば相当richだと思う.