Material-UIを使った開発
Material-UI
数ヶ月ほど、Material-UIを使った開発をしたので、知見などのメモです。
Material-UIは、MaterialデザインベースのReactのUIコンポーネントライブラリです。
とても有名で、便利なコンポーネントがたくさん用意されています。
パッケージ
基本的には、@material-ui/core
をインストールすれば良いです。
追加で、アイコンを利用する場合は@material-ui/icons
をインストールします。
また、coreに入ってないコンポーネントが、@material-ui/lab
というパッケージで提供されているので、もし利用したくなったらインストールします。
自分の場合は、AlertやAutocompleteが使いたかったのでインストールしました。
情報
あまりネットに情報が無い印象なので、基本的に公式ドキュメントを見るだけです。 あとは、似たようなUIのTemplatesを見るくらいです。
コンポーネント
Components
各コンポーネントについては、ドキュメントの「Components」項目を見ると、見た目やパターン、サンプルコードを確認できます。
React Button component - Material-UI
ただし、コンポーネントごとにページが用意されているわけではなく、「Button」や「Card」といったある程度のまとまりでページが用意されています。
例えば、「Card」コンポーネントの場合、ページの下部に「API」という項目があり、「Card」以外にも「CardActionArea」や「CardActions」といった関連するコンポーネントのAPIページへの導線が記されています。
React Card component - Material-UI
Component API
「Component API」という項目もあり、こちらは全コンポーネントのPropsなどの情報が書いてあります。逆に見た目やパターンなどは書いてないので、「Components」ページを見る必要があります。
よく使うコンポーネント
- Button
- 基本的にボタンはこれ
- IconButton
- アイコンだけのボタンの場合はこれ
- Card
- カード
- Grid
- レイアウトはだいたいGridでいい感じにできる
- Paper
- ある程度の区切りをPaperで作る
- Dialog
- ダイアログ
- Snackbar、Alert
- エラーや成功時のフィードバックに使う
- Table
- テーブル
- Typography
- 文字は基本的にこれ
- Checkbox、Radio、Select、TextField、FormControl
- フォーム
- App Bar
- よくあるヘッダー
- Progress
- ローディング
アイコン
以下のページで、それっぽいキーワードで検索する
その他
普段の開発では、まず「Components」ページで、見た目やサンプルコードを確認して、Props情報などが知りたくなったら「Component API」ページを見ていました。
また、全体的にどんなコンポーネントがあるのかみたい場合は、以下のFigmaを見るといいかもしれません。
Material-UI for Figma | Material-UI Store
DateTimePicker(日時)
DateTimePickerが欲しくなった際は、以下の「Material-UI Pickers」が用意されています。
このライブラリは、ユーザーがdate-fns
やdayjs
といった日時操作系のライブラリと組み合わせて使えるようになっています。自分の場合は、dayjs
と組み合わせて使いました。
以下のように、dayjs
以外に、@date-io/dayjs
パッケージをインストールします。
$ npm i -s @date-io/dayjs@1.x dayjs
あとは、Providerを設定します。
import { MuiPickersUtilsProvider } from "@material-ui/pickers"; import DayjsUtils from "@date-io/dayjs"; import Root from "./Root"; function App() { return ( <MuiPickersUtilsProvider utils={DayjsUtils}> <Root /> </MuiPickersUtilsProvider> ); }
あとは、<DatePicker>
や<DateTimePicker>
といった用意されているコンポーネントを利用するだけです。
dayjs
用の設定をしておいたので、value
にDayjsオブジェクトが使えたり、onChange
のdataがDayjsオブジェクトとして返ってきます。
type Props = { value: Dayjs; handleChange: (date: Dayjs) => void; }; export const MyDateTimePicker: React.FC<Props> = ({ value, handleChange }) => ( <KeyboardDateTimePicker variant="inline" ampm={false} value={value} onChange={(date) => { if (date) { handleChange(date); } }} format="YYYY/MM/DD HH:mm" /> );
スタイル
Material-UIには、core/styles
からmakeStyles
というAPIが提供されており、CSS-in-JS
スタイルでスタイリングをしていきます。
@material-ui/styles - Material-UI
import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; const useStyles = makeStyles({ root: { color: 'white', height: 48, padding: '0 30px', }, }); export default function MyButton() { const classes = useStyles(); return <Button className={classes.root}>Hook</Button>; }
また、CssBaseline
というnormalize.css
に似た役割を持ったコンポーネントが用意されているので、アプリケーションのトップレベルで読み込むようにしました。
SSR(Next.js)
Next.js
で開発している際、「Prop className did not match」というエラーが出ます。
SSRとクライアントサイドでclassNameが変わってしまうので、_app.tsx
に以下の記事で紹介されているような対応をしました。
Theme
Material-UIで用意されているコンポーネントは色がprimary
やdefault
、secondary
といった形で指定します。
ここで適用される色はデフォルトのThemeです。
アプリケーションのデザインに合うように、Themeをカスタマイズしました。ThemeProvider
を設定します。
Themeの例
import { createMuiTheme } from "@material-ui/core/styles"; import blue from "@material-ui/core/colors/blue"; import red from "@material-ui/core/colors/red"; const theme = createMuiTheme({ palette: { primary: { main: blue["600"], }, secondary: { main: red["600"], }, }, typography: { h1: { fontWeight: 600, }, h2: { fontWeight: 600, }, button: { fontWeight: 600, }, }, }); export default theme;
日本語だと、h要素でも細字になってしまったので、h要素のfontWeight
を高く設定することも可能です。