Comments (2)
문제: 기존에 정의되어있는 color 타입에 맞춰서 덮어쓰는 것은 가능하지만, 새로운 값을 넣어서 쓰는 것이 안된다
위 예시에서 Hex값을 다른 값으로 덮어쓰는 것은 가능하지만
위 예시처럼 새로운 프로퍼티를 넣었을 때 타입지원을 받을 수 없다
해결해야 합니다. 타입스크립트 공부좀 해야겠습니다...
from react-libraries.
기존의 테마 설정 방법
- emotion.d.ts 파일을 만들어서 Theme 타입을 선언한다. 기본적으로 Theme은 빈 객체 타입이며, 우리는 여기에 MusmaTheme을 상속해준 뒤 사용합니다. Emotion - Define a theme
import '@emotion/react'
import { MusmaTheme } from './musma/theme'
declare module '@emotion/react' {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface Theme extends MusmaTheme {}
}
- 프로젝트에서 사용할 테마는 아래와 같이 이미 정의된 기본값인 DefaultTheme을 불러와서, 커스텀 하고 싶은 부분을 덮어쓰는 형태로 사용한다. 아래 예시(대동)와 같이 theme 변수를 만들어서 MusmaProvider 에 전달합니다. 전달하지 않으면 디자인시스템에 정의되어있는 기본값을 사용합니다.
const theme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
primary: {
lighter: '#1FA2FF',
light: '#006CE8',
main: '#013F6B',
dark: '#013F6B',
darker: '#003E6A',
},
blue: {
lighter: '#1FA2FF',
light: '#006CE8',
main: '#084C9C',
dark: '#013F6B',
darker: '#003E6A',
},
...생략...
}
const App = () => {
return (
<I18nextProvider i18n={i18n}>
<MusmaProvider theme={theme}> //--> props로 theme를 전달
<ApolloClientProvider>
<QueryClientProvider>
<Toaster />
<Suspense fallback={<LoadingScreen type="fallback" />}>
<RouterProvider router={AppRouter} />
</Suspense>
</QueryClientProvider>
</ApolloClientProvider>
</MusmaProvider>
</I18nextProvider>
)
}
변경 후
1. 다중 테마를 사용하지 않는 경우
위에서 처럼 emotion.d.ts 파일을 만든 뒤, createTheme 함수에 DefaultTheme를 인자로 전달해 theme 객체를 생성합니다.
또는 DefaultTheme과 함께 덮어쓰고 싶은 프로퍼티를 전달해 커스터마이징 합니다.
// 기본 테마를 사용하거나
const theme = createTheme(DefaultTheme)
// 원하는 값을 덮어쓴다
const theme2 = = createTheme({
colors: {
...DefaultTheme.colors,
black: { main: 'black', light: 'yellow', dark: 'green', darker: 'blue', lighter: 'white' },
},
})
MusmaProvider에 전달할 때는 defaultTheme 속성에 Props로 전달해야 합니다
const rootElement = document.getElementById('root')
if (rootElement) {
createRoot(rootElement).render(
<MusmaProvider defaultTheme={theme}>
<ToastContextProvider position="top-right" limit={3} newestOnTop>
<BrowserRouter>
<Routes>
<Route element={<Component />} path="" />
<Route element={<div>여기서도 토스트 팝업이 잘 뜨는지 봐주십쇼</div>} path="toast" />
</Routes>
</BrowserRouter>
</ToastContextProvider>
</MusmaProvider>,
)
}
2. 다중 테마를 사용해야하는 경우
- emotion.d.ts 파일에 위와 같이 Theme을 선언해주되, 새롭게 추가할 프로퍼티의 타입을 추가한다. 여기서는 새로운 색상 세트인 palette 프로퍼티의 타입을 선언했습니다. 기존의 colors 프로퍼티는 key의 이름을 blue, black, gray 등 특정 색상과 직접 연결되는 이름으로 정해두었기 때문에 멀티 테마 기능에 적합하지 않습니다.(예를 들어 검은색인 텍스트가 다크모드에서는 흰색으로 나와야한다면, 텍스트 색상을 black.main으로 사용할 경우 라이트 모드에서만 유의미한 이름이 됩니다. 그보다는 priamry, secondary 와 같이 간접적인 이름이 나을듯합니다)
import type { MusmaTheme } from 'src/theme'
import '@emotion/react'
declare module '@emotion/react' {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface Theme extends MusmaTheme {
palette: {
primary: {
lighter: string
light: string
main: string
dark: string
darker: string
}
secondary: {
lighter: string
light: string
main: string
dark: string
darker: string
}
warning: {
lighter: string
light: string
main: string
dark: string
darker: string
}
}
}
}
- createTheme 함수를 이용해서 필요한 만큼 테마 객체를 만든다. 이때 위에서 정의한 palette 타입의 객체를 인자로 전달해준다.
const theme1 = createTheme({
palette: {
primary: {
lighter: '#DFE7EB',
light: '#D9E1E5',
main: '#D0D5DD',
dark: '#C4D2E0',
darker: '#BAC7D5',
},
secondary: {
lighter: '#F2F8FB',
light: '#118EE5',
main: '#036DB7',
dark: '#025996',
darker: '#003E6A',
},
warning: {
lighter: '#FD9009',
light: '#FFAB43',
main: '#FD9009',
dark: '#E76F00',
darker: '#D86900',
},
},
})
const theme2 = createTheme({
palette: {
primary: {
lighter: '#FD9009',
light: '#FFAB43',
main: '#FD9009',
dark: '#E76F00',
darker: '#D86900',
},
secondary: {
lighter: '#DFE7EB',
light: '#D9E1E5',
main: '#D0D5DD',
dark: '#C4D2E0',
darker: '#BAC7D5',
},
warning: {
lighter: '#F2F8FB',
light: '#118EE5',
main: '#036DB7',
dark: '#025996',
darker: '#003E6A',
},
},
})
- MusmaProvider에 defaultTheme과 함께 themeOptions를 전달한다. themeOptions는 내부적으로 컨텍스트를 통해 하위 컴포넌트에서 접근할 수 있게되며, 앱 실행중 테마를 변경할 때 사용됩니다.
const themeOptions = [
{ label: 'first', value: theme1 },
{ label: 'second', value: theme2 },
]
const rootElement = document.getElementById('root')
if (rootElement) {
createRoot(rootElement).render(
<MusmaProvider defaultTheme={theme1} themeOptions={themeOptions}>
<ToastContextProvider position="top-right" limit={3} newestOnTop>
<BrowserRouter>
<Routes>
<Route element={<Component />} path="" />
<Route element={<div>여기서도 토스트 팝업이 잘 뜨는지 봐주십쇼</div>} path="toast" />
</Routes>
</BrowserRouter>
</ToastContextProvider>
</MusmaProvider>,
)
}
2023-11-08.1.59.29.mov
from react-libraries.
Related Issues (20)
- regExp 수정
- fix: 빌드에러 HOT 1
- RadioGroup 컴포넌트에 disabled Props 추가
- useFormSearch 기능 수정
- useFormSearch, getFileSize 수정
- useFormSearch InitPageable props 추가
- pagination 버그 수정 HOT 1
- NPM 퍼블릭 배포 HOT 2
- eslint-config-react comment HOT 1
- useFullScreen bug HOT 1
- DateRangePicker 수정사항
- Flex , Table, Typography component 기능 추가 및 수정
- Docs 정리
- [BUG] 한 페이지 안에서 두 개의 useFormSearch를 사용할 때, formState가 겹치는 문제
- [FEATURE] 화면에서 숫자를 표시할 때, 숫자 사이의 콤마를 찍는 유틸 함수 추가
- [FEATURE] NavBar에 폴딩(Folding) 기능 추가하기 HOT 2
- [BUG] 디자인 시스템 오적용 수정
- [BUG] 일부 기능 수정
- [BUG] 크롬 콘솔 내 aria-hidden 에러 메시지
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-libraries.