😸
Material-UI v4でコンポーネントのデザインをカスタムする方法
グローバルのCSS設定をカスタムする
コンテキストを作ってその中でCSSのデフォルト設定をカスタムする
Iconの大きさや、Typographyのフォント設定などをグローバルにカスタムできる。
VScodeを使っていれば、control
+ space
で、設定項目を教えてもらえる。
カスタムCSSを設定
theme.ts
import { createMuiTheme, ThemeOptions } from '@material-ui/core/styles';
const DROPDOWN_BOX_SHADOW =
'0px 2px 8px rgba(0, 0, 0, 0.12), 2px 0px 8px rgba(0, 0, 0, 0.12)';
export const theme = (options: ThemeOptions = {}) => {
return createMuiTheme({
overrides: {
// SvgIconサイズをカスタム
MuiSvgIcon: {
fontSizeSmall: {
'& > *:first-child': {
fontSize: 10
}
},
fontSizeLarge: {
fontSize: ICON_SIZES.regular,
'& > *:first-child': {
fontSize: 20
}
}
},
// Iconサイズをカスタム
MuiIcon: {
fontSizeSmall: {
'& > *:first-child': {
fontSize: 10
}
},
fontSizeLarge: {
fontSize: ICON_SIZES.regular,
'& > *:first-child': {
fontSize: 20
}
}
},
// Buttonサイズをカスタム
MuiButton: {
iconSizeSmall: {
'& > *:first-child': {
fontSize: 10
}
},
iconSizeMedium: {
'& > *:first-child': {
fontSize: 20
}
},
iconSizeLarge: {
'& > *:first-child': {
fontSize: 25
}
}
}
},
// Typographyをカスタム
typography: {
fontFamily: "'Noto Sans JP', sans-serif;",
h1: {
fontSize: 24,
fontWeight: 700
},
h2: {
fontSize: 24,
fontWeight: 700
},
...
},
// パレットを設定
palette: {
primary: {
main: 'green'
},
secondary: {
main: 'blue'
},
text: {
primary: COLORS.textBlack,
secondary: COLORS.textGray
}
},
// その他
shape: {
borderRadius: 4
},
zIndex: {
appBar: 1250
},
shadows: [
'none',
DROPDOWN_BOX_SHADOW,
...Array(23).fill('none')
] as Shadows,
...options
});
};
コンテキスト内でカスタムCSSを適用
コンテキストはグローバルに設定することもできるし、ローカルに設定することもできる。
下記はNext.jsでグローバルに設定する場合。
_app.tsx
import { MuiThemeProvider } from '@material-ui/core/styles';
import { theme } from './theme';
...
return (
<MuiThemeProvider theme={theme()}>
<Your-Components-Here>
</MuiThemeProvider>
);
}
参考
スクロールバーのCSSをグローバル設定する
スクロールバーのグローバル設定は特殊だったのでメモ。MuiCssBaseline
を設定する必要がある。
customScrollbar.tsx
import CssBaseline from '@material-ui/core/CssBaseline';
import { MuiThemeProvider } from '@material-ui/core/styles';
const theme = createTheme({
overrides: {
MuiCssBaseline: {
'@global': {
'*::-webkit-scrollbar': {
width: 8
},
'*::-webkit-scrollbar-track': {
borderRadius: 4,
background: '#BDBDBD'
},
'*::-webkit-scrollbar-thumb': {
borderRadius: 4,
background: '#BDBDBD'
}
}
},
},
});
...
return (
<MuiThemeProvider theme={theme}>
<CssBaseline />
<Your-Component-Here>
</MuiThemeProvider >
);
参考
コンポーネントのCSSカスタマイズ
ClassNameを使ってカスタマイズできる。
Propsによるスタイル設定の分岐も可能。
下記はCustom Inputを使った例。
デフォルト
Focusがあたったとき
textInput.tsx
import React from 'react';
import InputBase from '@material-ui/core/InputBase';
import FormControl from '@material-ui/core/FormControl';
import FormLabel from '@material-ui/core/FormLabel';
import { makeStyles, Theme } from '@material-ui/core/styles';
export type Props = {
widthInPercent?: number;
label: string;
text: string;
placeholder?: string;
onTextChange: (text: string) => void;
};
const useTextFormStyles = makeStyles<Theme, { widthInPercent?: number }>({
formControl: {
width: ({ widthInPercent }) =>
widthInPercent ? `${widthInPercent}%` : 'auto',
maxWidth: '100%'
},
label: {
color: '#757575',
fontSize: 12,
fontWeight: 400,
'&.Mui-focused': {
color: '#BDBDBD'
}
},
text: {
backgroundColor: '#FFFFFF',
borderRadius: 4,
border: `#BDBDBD solid 1px`,
fontSize: 14,
fontWeight: 400,
'&.Mui-focused': {
border: `#1F79CC solid 1px`,
color: '#323030'
},
'& .MuiInputBase-input': {
height: 32,
padding: `0px 8px`
},
marginTop: 0
}
});
export const TextForm: React.FC<Props> = ({
widthInPercent,
label,
text,
placeholder,
onTextChange
}) => {
const classes = useTextFormStyles({ widthInPercent });
return (
<FormControl className={classes.formControl}>
<FormLabel className={classes.label}> {label}</FormLabel>
<InputBase
className={classes.text}
value={text}
onChange={(e) => onTextChange(e.target.value)}
placeholder={placeholder}
/>
</FormControl>
);
};
Focusがあたった部分のCSSをカスタマイズするには?
FocusがあたったときのCSSをカスタマイズするためには、該当するCSSクラス名を指定して記述すればよい。
'&.Mui-focused': {
border: `#1F79CC solid 1px`,
color: '#323030'
},
ではどうやってクラス名を特定するのか
Focusが当たった部分のクラス名はドキュメントに書いてある。
ドキュメントを見なくてもDev toolで分かる
また、ブラウザのDev toolのElements
タブで該当するエレメントをinspectすれば分かる。
ドキュメントに書いていない細かい部分のCSSをカスタマイズしたいとき、細かい部分のクラス名を調べるためにはDev toolでinspectする必要がある。
Classes属性をつかう場合
前述のやりかたではMUIコンポーネントのclassName
属性をつかったが、classes
属性を使ってカスタムCSSを指定することもできる。
const useTextFormStyles = makeStyles<Theme, { widthInPercent?: number }>({
...
text: {
backgroundColor: #FFFFFF,
borderRadius: BORDER_RADIUSES.regular,
border: `#BDBDBD solid 1px`,
fontSize: 14,
fontWeight: 400,
- '&.Mui-focused': {
- border: `#1F79CC solid 1px`,
- color: '#323030'
- },
'& .MuiInputBase-input': {
height: 32,
padding: `0px 4px`
},
marginTop: 4
},
+ textFocus: {
+ border: `#1F79CC solid 1px`,
+ color: #323030
+ }
});
export const TextForm: React.FC<Props> = ({
widthInPercent,
label,
text,
placeholder,
onTextChange
}) => {
const classes = useTextFormStyles({ widthInPercent });
return (
<FormControl className={classes.formControl}>
<FormLabel className={classes.label}> {label}</FormLabel>
<InputBase
className={classes.text}
+ classes={{ focused: classes.textFocus }}
value={text}
onChange={(e) => onTextChange(e.target.value)}
placeholder={placeholder}
/>
</FormControl>
);
};
classes
属性に指定できるkeyはどうやって分かるの?
control
+ shift
でVScodeが教えてくれるが、ドキュメントにも書いてある。
Discussion