이번에 회사에서 프로젝트를 하면서 Material UI를 사용하였는데,
Material UI에서 제공하는 기본 스타일링 문법이 마음에 들지 않았다.
아예 scss도 아니고 Styled Component도 아닌 좀 애매한 문법이라는 생각이 들어서 Styled Component에서 Material UI의 기본 기능들을 사용할 수 있게 세팅해보았다.
- 원하는 컬러를 @material-ui/core/colors에서 꺼내서 palette 생성
- 다크모드시 컬러 팔레트의 속성을 반전시킬 수 있도록 설정
// colors.ts
import { createMuiTheme } from "@material-ui/core/styles";
import green from "@material-ui/core/colors/green";
import teal from "@material-ui/core/colors/teal";
const palette = {
primary: {
light: teal[400],
main: teal[600],
dark: teal[800],
contrastText: "#fff",
},
secondary: {
light: green[200],
main: green[400],
dark: green[600],
contrastText: "#fff",
},
};
export const createTheme = (prefersDarkMode: boolean) =>
createMuiTheme({
palette: {
type: prefersDarkMode ? "dark" : "light",
...palette,
},
});
- styled components의 ThemeProvider에 다크모드 처리한 theme 삽입
// ColorProvider.tsx
import React from "react";
import { DefaultTheme, ThemeProvider } from "styled-components";
type ColorProviderProps = {
children: React.ReactNode;
theme: DefaultTheme;
};
function ColorProvider({ children, theme }: ColorProviderProps) {
return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
}
export default ColorProvider;
- material ui의 ThemeProvider와 styled components의 ThemeProvider인 ColorProvider를 중첩해서 적용
- material ui의 useMediaQuery 훅으로 다크테마 감지
// App.tsx
import React, { useMemo } from "react";
import "./assets/css/index.scss";
import {
ThemeProvider,
StylesProvider,
useMediaQuery,
} from "@material-ui/core";
import { createTheme } from "./common/theme/colors";
import ColorProvider from "./common/theme/ColorProvider";
import Routes from "./Routes";
function App({}) {
const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
const theme = useMemo(() => createTheme(prefersDarkMode), [prefersDarkMode]);
return (
<>
<ThemeProvider theme={theme}>
<StylesProvider injectFirst>
<ColorProvider theme={theme}>
<Routes />
</ColorProvider>
</StylesProvider>
</ThemeProvider>
</>
);
}
export default App;
- styled components에서 자동완성을 위한 테마의 타입 생성
// types.ts
import { Theme } from "@material-ui/core/styles";
export interface IStyledTheme {
theme: Theme;
}
- styled components에서 material ui의 theme 기능 사용 가능
// 사용
import React from "react";
import styled from "styled-components";
import { IStyledTheme } from "../util/types";
// theme. 입력하면 머터리얼UI에 있는 속성들이 자동완성됨
const Content = styled.div`
width: 400;
${({ theme }: IStyledTheme) => `padding: ${theme.spacing(2, 4, 3)};`}
${({ theme }: IStyledTheme) => `box-shadow: ${theme.shadows[5]};`}
${({ theme }: IStyledTheme) =>
`background-color: ${theme.palette.background.paper};`}
`;
'Frontend > React&RN' 카테고리의 다른 글
useRef()와 createRef()의 차이 (0) | 2020.11.04 |
---|---|
[Android] zsh에서 에뮬레이터 바로 실행하기 (0) | 2020.08.28 |
[mobx] 세팅과 간단한 설명 (0) | 2020.06.10 |
setState와 불변성 (0) | 2020.06.01 |
[스토리북] 리액트 컴포넌트 UI 테스트 (0) | 2020.05.01 |