覆寫 Material-UI component CSS
Material-UI 提供了許多好用的 component 使用,但有時想要改掉它的樣式,該如何做呢?
我們只提 Overriding with classes ,因為 component 常常是自己組裝出來的
文件 Overrides 提供了很多方法使用,有興趣的人可去看看。
為了方便實驗,我們組裝一個 AgencyCard
的 component
// components/AgencyCard.js
import React from ‘react’;
import PropTypes from ‘prop-types’;
import { withStyles } from ‘@material-ui/core/styles’;
const styles = {
root: {
backgroundColor: 'red',
},
card: {
minWidth: 275,
},
};function AgencyCard(props) {
const { classes } = props;
return (
<div className={classes.root}>
<p className={classes.card}>agency name</p>
</div>
);
}AgencyCard.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(AgencyCard);
AgencyCard
提供了兩個classes
的鍵 (root, card),就是官方文件說的 CSS API ,以 Button 的CSS API 就有提供一堆鍵(root, label, text, textPrimary
…)。
錯誤寫法
現在的問題是如何覆寫它們,直覺上會直接寫
import React from 'react';
import PropTypes from 'prop-types';
import {withStyles} from '@material-ui/core/styles';import AgencyCard from './Card/AgencyCard';const styles = () => ({});
class AgencyBox extends React.Component {
render() {
const {classes} = this.props;
return (
<div>
<AgencyCard classes={{
root: {
backgroundColor: 'blue', // <---- Error
}
}} />
</div>);
}
}AgencyBox.propTypes = {
classes: PropTypes.object.isRequired,
};export default withStyles(styles)(AgencyBox);
會出現以下錯誤
正確寫法
正確要是
import React from 'react';
import PropTypes from 'prop-types';
import {withStyles} from '@material-ui/core/styles';import AgencyCard from './Card/AgencyCard';const styles = () => ({
myCard: {
backgroundColor: 'blue',
},
});
class AgencyBox extends React.Component {
render() {
const {classes} = this.props;
return (
<div>
<AgencyCard classes={{
root: classes.myCard // <---- OK
}} />
</div>);
}
}AgencyBox.propTypes = {
classes: PropTypes.object.isRequired,
};export default withStyles(styles)(AgencyBox);
這是因為 classes
在送到 component 中後就變成 key -> class name 的object,例如:
classes =
{
root:"AgencyCard-root-145",
card:"AgencyCard-card-146"
}
因此,要用CSS 注入 (CSS injection),配合 withStyles()
覆寫 AgencyCard
classes
的 root。
你可以在
AgencyCard
印出classes
,你會發現classes
只是的鍵值都是字串
回到原來的問題:覆寫 Material-UI component CSS
覆寫 Button 的 root
CSS API
import React from 'react';
import PropTypes from 'prop-types';
import {withStyles} from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';const styles = () => ({
myButtonRoot: {
backgroundColor: 'blue',
},
});
class AgencyBox extends React.Component {
render() {
const {classes} = this.props;
return (
<div>
<Button classes={{
root: classes.myButtonRoot
}} />
</div>);
}
}AgencyBox.propTypes = {
classes: PropTypes.object.isRequired,
};export default withStyles(styles)(AgencyBox);
參考資料
https://material-ui.com/customization/css-in-js/#withstyles-styles-options-higher-order-component
https://material-ui.com/customization/overrides/#overriding-with-classes