前言

雖然 MUI 已經用了一段時間了

我自己認為還是對他不是很熟悉

所以想寫一篇來多了解他

MUI with emotion

npm install @mui/material @emotion/react @emotion/styled

若要使用 MUI,他的官方會直接叫你下這個指令

WHY?

emotion 是一個 css in js 的套件,和 styled component 相似

而 MUI 就使使用 emotion 的一些方法去客製化他的 component 樣式

MUI 本是提供「功能面」的 Component,自身已經有一個預設的樣式,要客製化還是依賴 emotion

createTheme

createTheme 提供以下 default 的 key 可以去設定

當然也可以自定義 key 名稱,但注意不能使用’var’作為 key 名稱

這是是 MUI theme 的 default 值

palette

設定顏色的 object

something like this…

  palette: {
    background: {
      default: '#EEEEEE',
    },
  }

typography

可以 customize 字的樣式

  typography: {
    subtitle1: {
      fontSize: 12,
    },
    body1: {
      fontWeight: 500,
    },
    button: {
      fontStyle: 'italic',
    },
  },

spacing

使用方法

theme.spacing(2);
// 就等於 2 X 8px = 16px

default 單位是 px

也可以自定義單位成 rem

{
  spacing: (factor) => `${0.25 * factor}rem`;
}

breakpoints

自定義方式如下

  breakpoints: {
    values: {
      xs: 0,
      sm: 600,
      md: 900,
      lg: 1200,
      xl: 1536,
    },
  },

components

可以更改 default props

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

或是 override styles

    MuiButton: {
      styleOverrides: {
        // Name of the slot
        root: {
          // Some CSS
          fontSize: '1rem',
        },
      },
    },

又或者 customize variants + default styles

  components: {
   MuiButton: {
     styleOverrides: {
       root: ({ ownerState }) => ({
         ...(ownerState.variant === 'contained' &&
           ownerState.color === 'primary' && {
             backgroundColor: '#202020',
             color: '#fff',
           }),
       }),
     },
   },
 },

apply themes

在 createTheme 定義好樣式之後,有些會直接使用到預設的樣式

但大部分會需要手動去使用

假設這是我定義好的 theme

const theme = createTheme({
  palette: {
    primary: {
      main: "#ff4400",
    },
  },
});

function MyApp() {
  return (
    <ThemeProvider theme={theme}>
      <MyComponent />
    </ThemeProvider>
  );
}

useTheme

function MyComponent() {
  // 使用主題
  const theme = useTheme();

  return <div style={{ color: theme.palette.primary.main }}>Hello, world!</div>;
}

以下有幾種方法

styled

const StyledDiv = styled("div")(({ theme }) => ({
  color: theme.palette.primary.main,
}));

sx

sx 有兩種方法

function MyComponent() {
  return (
    <Box
      sx={(theme) => ({
        color: theme.palette.primary.main,
        backgroundColor: theme.palette.background.default,
      })}
    >
      Hello, world!
    </Box>
  );
}
function MyComponent() {
  return (
    <Box
      sx={{
        width: 300,
        color: "success.main",
      }}
    >
      Hello, world!
    </Box>
  );
}