Material-UIのwithStylesでカスタマイズ
はじめに
Material-UI のコンポーネントのスタイルを変更したいなーと思った際に、公式ドキュメントだけでは"withStyles"の利用方法が分かりづらかったので。
色々と使い方はあるみたいだが、とりあえず基本の基本をピックアップ。
withStyles の基本
下記のように withStyles によってコンポーネントを作成し配置する。
const CustomComponent = withStyles({
root: {
// ここにスタイルを書いたり
},
label: {},
// etc...
})(カスタムしたいコンポーネント)
// コンポーネントの配置
<CustomComponent />
直接 className や style にスタイルを指定してもよいが、同じレイアウトのものを複数作成したり、変更点が多い場合にスッキリしたコードが書けるのでおすすめ。
root?label?ってなに?
Material-UI の公式ドキュメントの Component API の各ページ下部に CSS という欄がある。
ここの Rule name が withStyles に渡すスタイルの key 名となる。
Button の CSS の一部
実践(Button を例に)
Button にはもともと color プロパティが用意されているがテーマに沿った色しか指定できない。
もっと自由にスタイルを変更してみる。
デフォルト Button
1-1. root にカラー設定
const MyButton = withStyles({
root: {
// rootコンポーネントへ適応
background: '#26a69a', // 背景色
'&:hover': {
// hover時背景色
background: '#1a746b',
},
marginRight: 10,
// color: 'white', ここに書いてもいいが、せっかくなのでlabelに記述
},
label: {
color: 'white',
},
})(Button)
...
<MyButton>text</MyButton> // デフォルトがvariant="text"
<MyButton variant="outlined">outlined</MyButton>
<MyButton variant="contained">contained</MyButton>
root に指定した場合
色は変更できたが、variant それぞれのスタイルが崩れてしまう。
variant ごとの Rule name も用意されているので、そちらに指定することで特定の vairant に対してのみスタイルを当てることができる。
1-2. variant ごとに設定
const MyButton = withStyles({
root: {
marginRight: 10,
},
// variant="text"のみ適応
text: {
color: '#03a9f4',
},
// variant="outlined"のみ適応
outlined: {
border: '1px solid #e65100',
'&:hover': {
background: '#ffe0b2',
},
},
// variant="contained"のみ適応
contained: {
color: 'white',
background: '#43a047',
'&:hover': {
background: '#2e7031',
},
},
})(Button)
...
<MyButton>text</MyButton> // デフォルトがvariant="text"
<MyButton variant="outlined">outlined</MyButton>
<MyButton variant="contained">contained</MyButton>
各 variant に個別設定した場合
1-3. ちょっと特殊なものの紹介
1-3-1. 概要
上記とは少し異なった実装をしなければならないパターンも紹介します。
自分は最初わからず躓きました...
たとえば、Button にはこんなルールがあります。
今までのパターンでいけば disabled が設定された際に適応されるなと想像できます。
実際に指定して disabled 時の文字色を赤にしてみます。
const MyButton = withStyles({
root: {
// 見栄えのためにつけているだけです
marginRight: 10,
},
disabled: {
color: 'rgba(255, 0, 0, 0.26)',
},
})(Button)
<MyButton variant="contained">disabled</MyButton>
<MyButton variant="contained" disabled>
disabled
</MyButton>
...変化なし!
一度 Chrome の開発者ツールを覗いてみると
自動で付与される style に優先順位で負けてます。
本来であれば設定したものが上に来てほしいのですが。
1-3-2. 解決策
ドキュメントを漁ると Global class が Mui-から始まるもの、または、Description に 「Pseudo-class applied ~」と記載のあるものは root に$ruleName で指定する必要があるようです。(Pseudo-class は擬似クラスで desabled や checked, selected のようなものが該当)
const MyButton = withStyles({
root: {
// 見栄えのためにつけているだけです
marginRight: 10,
// &$ruleNameで指定
'&$disabled': {
color: 'rgba(255, 0, 0, 0.26)'
}
},
disabled: {
// 必ず空を用意
},
})(Button)
<MyButton variant="contained">disabled</MyButton>
<MyButton variant="contained" disabled>
disabled
</MyButton>
disable 時の文字色を赤に
1-4. その他
上記で紹介したもの以外でも outlinedPrimary(variant="outlined", color="primary")や textSizeLarge(variant="text", size="large")など更に細かな設定条件のルールもある。
下記を参考にしていろいろ試してみてください。
Button の CSS
おわりに
withStyles によるコンポーネントのカスタマイズ方法を紹介しました。
Component API の CSS 欄を確認し、Rule name を key に実装するという方法でした。
また、疑似クラスの disabled, selected 等は注意が必要であることは覚えておいてください。
今回は Button を例に紹介しましたが、Select, List 等のコンポーネントでも同じようにカスタマイズができます。
(例えば、ListItem が selected 時の背景色を変えたい等)
ぜひ様々なコンポーネントを使って試してみてください!
Discussion