希曼日记

自定义主题

本页目录 4
  1. 自定义组件
  2. 更改组件全局属性
  3. 全局HTML标签样式
  4. 参考

主题定制 theme

自定义组件

  1. 引入@mui/system/styled 自定义Button组件,继承自Button的自定义组件
const MyButton = syleted(Button)({
	border:'1px solid red'
})

通过sx更改单个组件的默认主题样式

  1. 开发者控制台得到MUI类名, 例如.MuiSlider-thumb-a123, 只需要.MuiSlider-thumb即可
  2. 更改MUI组件的样式覆盖默认的组件主题
<Slider
  sx={{
    '& .MuiSlider-thumb': {
      borderRadius: '1px',
    },
  }}
/>

更改组件全局属性

Components

  1. 使用createTheme创建自定义的主题
  2. 使用ThemeProvider覆盖默认的主题
  3. ThemeProvider下的子组件使用theme下继承createTheme所定义的属性

示例:

import * as React from 'react';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import Button from '@mui/material/Button';

const theme = createTheme({
  components: {
    // Name of the component ⚛️
    MuiButtonBase: {
      defaultProps: {
        // The default props to change
        disableRipple: true, // No more ripple, on the whole application 💣!
      },
    },
  },
});

export default function DefaultProps() {
  return (
    <ThemeProvider theme={theme}>
      <Button>This button has disabled ripples.</Button>
    </ThemeProvider>
  );
}

通过类名全局覆盖该组件的主题的样式

  1. 通过开发者控制台获取组件的类, 例如:.MenuItem ,或者控制其组件的状态,例如.Mui-selected
  2. 全局样式文件修改
/* 覆盖属性 */
.MenuItem.Mui-selected {
  color: blue;
}
  1. 使用
<MenuItem selected className="MenuItem">

常见状态 Pasted image 20221119144012

⚠️ 永远不要直接对状态类名应用样式。这将影响所有组件,副作用不清楚。总是将状态类和组件一起作为目标。

/* ❌ NOT OK */
.Mui-error {
  color: red;
}

/* ✅ OK */
.MuiOutlinedInput-root.Mui-error {
  color: red;
}

基于原有组件基础进行重写样式

import { Typography, TypographyProps } from '@mui/material'

const Text = styled<TypographyProps>(Typography)(()=>({
	fontFamily: ['Microsoft YaHei-Bold, Microsoft YaHei, sans-serif'].join(','),
	// ...styles
})) as typeof Typography

动态覆盖

  1. 使用styled()方法的第二个参数
import * as React from 'react';
import { alpha, styled } from '@mui/material/styles';
import Slider, { SliderProps } from '@mui/material/Slider';
import FormControlLabel from '@mui/material/FormControlLabel';
import Switch from '@mui/material/Switch';

interface StyledSliderProps extends SliderProps {
  success?: boolean;
}

const StyledSlider = styled(Slider, {
  shouldForwardProp: (prop) => prop !== 'success',
})<StyledSliderProps>(({ success, theme }) => ({
  width: 300,
  ...(success && {
    color: theme.palette.success.main,
    '& .MuiSlider-thumb': {
      [`&:hover, &.Mui-focusVisible`]: {
        boxShadow: `0px 0px 0px 8px ${alpha(theme.palette.success.main, 0.16)}`,
      },
      [`&.Mui-active`]: {
        boxShadow: `0px 0px 0px 14px ${alpha(theme.palette.success.main, 0.16)}`,
      },
    },
  }),
}));

export default function DynamicCSS() {
  const [success, setSuccess] = React.useState(false);

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setSuccess(event.target.checked);
  };

  return (
    <React.Fragment>
      <FormControlLabel
        control={
          <Switch
            checked={success}
            onChange={handleChange}
            color="primary"
            value="dynamic-class-name"
          />
        }
        label="Success"
      />
      <StyledSlider success={success} defaultValue={30} sx={{ mt: 1 }} />
    </React.Fragment>
  );
}

全局HTML标签样式

  1. 使用GlobalStyles 组件的属性style定义
  2. styles对象选择要定义的html元素,例如h1,进行定义样式
  3. 使用标签

范例:

<>
	<GlobalStyles styles={{ h1: { color: #fff } }}>
	<h1>color</h1>
</>

参考

  1. 定制主题
  2. 组件不同状态
  3. 默认主题样式
  4. MUI设计
  5. Components
  6. 主题定制