...接续前一篇
在上一篇中讲解如何覆盖 Material-UI 组件的样式,现在,让我们看看如何使这些覆盖动态化。这里有五种选择;每个都有其优点和缺点。
这个方式是透过 withStyles() 的方式更改样式,直接透过 styles 内的参数做更改。
// Like https://github.com/brunobertolini/styled-by
const styledBy = (property, mapping) => (props) => mapping[props[property]];
const styles = {
root: {
background: styledBy('color', {
default: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
blue: 'linear-gradient(45deg, #2196F3 30%, #21CBF3 90%)',
}),
borderRadius: 3,
border: 0,
color: 'white',
height: 48,
padding: '0 30px',
boxShadow: styledBy('color', {
default: '0 3px 5px 2px rgba(255, 105, 135, .3)',
blue: '0 3px 5px 2px rgba(33, 203, 243, .3)',
}),
},
};
const StyledButton = withStyles(styles)(({ classes, color, ...other }) => (
<Button className={classes.root} {...other} />
));
export default function DynamicCSS() {
const [color, setColor] = React.useState('default');
const handleChange = (event) => {
setColor(event.target.checked ? 'blue' : 'default');
};
return (
<React.Fragment>
<FormControlLabel
control={
<Switch
checked={color === 'blue'}
onChange={handleChange}
color="primary"
value="dynamic-class-name"
/>
}
label="Blue"
/>
<StyledButton color={color}>Dynamic CSS</StyledButton>
</React.Fragment>
);
}
这个方法就是常用的 makeStyles() 的做法。
const useStyles = makeStyles({
button: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
borderRadius: 3,
border: 0,
color: 'white',
height: 48,
padding: '0 30px',
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
},
buttonBlue: {
background: 'linear-gradient(45deg, #2196F3 30%, #21CBF3 90%)',
boxShadow: '0 3px 5px 2px rgba(33, 203, 243, .3)',
},
});
export default function DynamicClassName() {
const classes = useStyles();
const [color, setColor] = React.useState('default');
const handleChange = (event) => {
setColor(event.target.checked ? 'blue' : 'default');
};
return (
<React.Fragment>
<FormControlLabel
control={
<Switch
checked={color === 'blue'}
onChange={handleChange}
color="primary"
value="dynamic-class-name"
/>
}
label="Blue"
/>
<Button
className={clsx(classes.button, {
[classes.buttonBlue]: color === 'blue',
})}
>
{'Class name branch'}
</Button>
</React.Fragment>
);
}
者个方法跟上面差不多,但是是以 CSS 变数作为更改的值。
const useStyles = makeStyles({
button: {
background: 'linear-gradient(45deg, var(--background-start) 30%, var(--background-end) 90%)',
borderRadius: 3,
border: 0,
color: 'white',
height: 48,
padding: '0 30px',
boxShadow: '0 3px 5px 2px var(--box-shadow)',
},
});
const blue = {
'--background-start': '#2196F3',
'--background-end': '#21CBF3',
'--box-shadow': 'rgba(33, 203, 243, .3)',
};
const defaultColor = {
'--background-start': '#FE6B8B',
'--background-end': '#FF8E53',
'--box-shadow': 'rgba(255, 105, 135, .3)',
};
export default function DynamicCSSVariables() {
const classes = useStyles();
const [color, setColor] = React.useState(defaultColor);
// 和上面不同的是以变数更改而不是使用className
const handleChange = (event) => {
setColor(event.target.checked ? blue : defaultColor);
};
return (
<React.Fragment>
<FormControlLabel
control={
<Switch
checked={color === blue}
onChange={handleChange}
color="primary"
value="dynamic-class-name"
/>
}
label="Blue"
/>
<Button className={classes.button} style={color}>
{'CSS variables'}
</Button>
</React.Fragment>
);
}
这个方法会直接使用 inline-styles 去更改。
const styles = {
button: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
borderRadius: 3,
border: 0,
color: 'white',
height: 48,
padding: '0 30px',
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
},
buttonBlue: {
background: 'linear-gradient(45deg, #2196f3 30%, #21cbf3 90%)',
boxShadow: '0 3px 5px 2px rgba(33, 203, 243, .30)',
},
};
export default function DynamicInlineStyle() {
const [color, setColor] = React.useState('default');
const handleChange = (event) => {
setColor(event.target.checked ? 'blue' : 'default');
};
return (
<React.Fragment>
<FormControlLabel
control={
<Switch
checked={color === 'blue'}
onChange={handleChange}
color="primary"
value="dynamic-class-name"
/>
}
label="Blue"
/>
<Button
style={{
...styles.button,
...(color === 'blue' ? styles.buttonBlue : {}),
}}
>
{'dynamic inline-style'}
</Button>
</React.Fragment>
);
}
这个做法之前有讲过了,透过不同的 theme provider 来更改。
export default function DynamicThemeNesting() {
const [color, setColor] = React.useState('default');
const handleChange = (event) => {
setColor(event.target.checked ? 'blue' : 'default');
};
const theme = React.useMemo(() => {
if (color === 'blue') {
return createTheme({
palette: {
secondary: {
main: blue[500],
contrastText: '#fff',
},
},
});
}
return createTheme();
}, [color]);
return (
<React.Fragment>
<FormControlLabel
control={
<Switch
checked={color === 'blue'}
onChange={handleChange}
color="primary"
value="dynamic-class-name"
/>
}
label="Blue"
/>
<ThemeProvider theme={theme}>
<Button variant="contained" color="secondary">
{'Theme nesting'}
</Button>
</ThemeProvider>
</React.Fragment>
);
}
你可能需要创建组件的变体并在不同的 context 中使用它,例如产品页面上的彩色按钮,但你可能希望保持代码单纯。
最好的方法是遵循方法 1,然後通过导出自定义组件以在任何需要的地方使用,从而利用 React 的组合能力。
Material Design 规范记录了某些组件的不同变体,例如按钮如何具有不同的形状:text(以前的"flat")、contained的(以前的"raised")、FAB 等等。
详细支援组件。
为了促进组件之间的一致性,并从整体上管理用户界面外观,Material-UI 提供了一种应用全局更改的机制。
const GlobalCss = withStyles({
// @global is handled by jss-plugin-global.
'@global': {
// 要指向 [class*="MuiButton-root"] 而不是 nest themes.
'.MuiButton-root': {
fontSize: '1rem',
},
},
})(() => null);
export default function GlobalCssOverride() {
return (
<React.Fragment>
<GlobalCss />
<Button>font-size: 1rem</Button>
</React.Fragment>
);
}
直接立一个新的 theme 去做覆盖的动作,利用 theme 的 overrides 键来更改 Material-UI 注入到 DOM 中的每个样式。
const theme = createTheme({
overrides: {
MuiButton: {
root: {
fontSize: '1rem',
},
},
},
});
export default function GlobalThemeOverride() {
return (
<ThemeProvider theme={theme}>
<Button>font-size: 1rem</Button>
</ThemeProvider>
);
}
以上就是今天的全部内容了,有在 follow 官方网站的朋友应该有发现最近已经发布 ver. 5 的版本了,我现在介绍和使用的是 ver.4,有机会会再出一个新版本更新的内容。
<<: Day18-D3 的 Axis( ) & ticks( ) 轴线与刻度
>>: D15 - 那个圆圆的东西 - OOP 物件导向程序设计
现在IntelliJ 已经成为开发JAVA使用的主流IDE, 但我们最常遇到的就是IDE出现中文乱码...
搜寻列、登入页面、Google表单,还有...客诉表单(目死)是我们日常都会接触到的东西 这些都可以...
NumPy操作 安装 请在终端机底下输入这个,谢谢 pip install numpy 载入NumP...
本篇我们继续讨论号志的存取同步的形式。 假设如果有两个任务同步执行,此时该如何同步处理这类状况呢?遇...
一、前言 在 JavaScript 的世界里有变数,那初学者们也知道 CSS (阶层式样式表,C...