- ํฌ์คํ ์ฃผ ๋ด์ฉ์ ์ ์ญ ์คํ์ผ(Global), ํ ๋ง(theme), ํ์ ์คํฌ๋ฆฝํธ ์ ์ฉ์ ํฌ์ปค์ค๋ฅผ ๋ง์ถ๊ฒ ์ต๋๋ค.
- react ๋ฅผ ์ฌ์ฉํด๋ณธ์ ์ด ์๊ฑฐ๋, ์คํ์ผ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํด๋ณด์ ์ ์ด ์์ผ์ ๋ถ๋ค์
- ์๋ ์ฝ๋ ์์๋ง ๋ณด๊ณ ์ถฉ๋ถํ ๊ฐ์ ์ก์ผ์ค ์ ์์ ๊ฑฐ๋ผ๊ณ ์๊ฐ ํฉ๋๋ค.
โ ํ๊ฒฝ ์ธํ
// ์คํ์ผ ์ปดํฌ๋ํธ ์ค์น
yarn add styled-components
// ํ์
์คํฌ๋ฆฝํธ ์ ์ฉ
yarn add --dev @types/styled-components
โ styled.d.ts
import 'styled-components';
declare module 'styled-components' {
export interface DefaultTheme {
TitleFont : {
fontSize : any;
fontFamily : string;
fontColor : string;
fontWeight : string;
}
LoginButton : {
bgColor : any;
}
}
}
- .d.ts๋ฅผ ํ์ ์ ์ธ ํ์ผ์ด๋ผ๊ณ ํฉ๋๋ค. TS์ฝ๋์ ํ์ ์ถ๋ก ์ ๋๋ ํ์ผ ์ ๋๋ค.
- ์ฒซ๋ฒ์งธ ๋จ๊ณ๋ styled.d.ts ๋ผ๋ ํ ๋ง์ ์ฌ์ฉ๋ ๋ณ์๋ค์ ํ์ ๋ค์ ์ ์ธํ๋ ํ์ผ์ ๋ง๋๋ ๊ฒ ์ ๋๋ค.
- ์์์ ๋ง๋ ์ ์ธํ์ผ๋ก styled-components ๋ชจ๋์ DefaultTheme ๋ผ๋ ์ด๋ฆ์ ์ธํฐํ์ด์ค๋ฅผ ์์ฑํด ํ์ ์ ๋ช ์.
- ํ ๋ง๋ฅผ ์์ฑํ ๋ importํ์ฌ ํ ๋ง์์ ์ ์ธ๋ ํ์ ์ ๋ง๊ฒ ์คํ์ผ์ ์์ฑ.
โ theme.tsx
import { DefaultTheme } from "styled-components";
export const SignTheme : DefaultTheme = {
TitleFont : {
fontSize : '32px',
fontColor : 'lightgray',
fontFamily : 'Nanum Myeongjo',
fontWeight : 'bold'
},
LoginButton : {
bgColor : 'rgb(237, 82, 85)'
}
}
โ index.tsx
- ๊ตณ์ด index.tsx ์๋์ด๋ ์๊ด ์์ต๋๋ค. ( ์ฐ์ตํ ํ์ผ๋ค ๊ธฐ์ค )
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { GlobalStyle } from './style/GlobalStyle';
import { ThemeProvider } from 'styled-components';
import { SignTheme } from './style/theme';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<GlobalStyle/>
<ThemeProvider theme={SignTheme}>
<App />
</ThemeProvider>
</React.StrictMode>
);
์์ ์ฝ๋์ ๊ฐ์ด props ๋ถ๋ฌ์์ ์ฌ์ฉ
import styled from "styled-components";
import { SignTheme } from "../style/theme";
const MainWrap = styled.div`
width : 100%;
padding : 0px 16px;
display : flex;
justify-content : center;
`
const TitleText = styled.span`
display: inline-block;
margin-top : 200px;
text-transform : uppercase;
font-family : ${(props) => props.theme.TitleFont.fontFamily};
font-size : ${(props) => props.theme.TitleFont.fontSize};
font-weight : ${(props) => props.theme.TitleFont.fontWeight};
text-shadow: 0 14px 12px #5e728c;
`
const Title = () => {
return (
<MainWrap>
<TitleText>jjcl company</TitleText>
</MainWrap>
)
}
export default Title;
โ Global Style
import { createGlobalStyle } from "styled-components";
export const GlobalStyle = createGlobalStyle`
*{
box-sizing : border-box;
}
body{
width : auto;
height : 100%;
padding : 0px;
margin : auto;
background : #DBDBDB;
@media (min-width: 701px){
max-width: 700px;
};
> div {
background: #fff
}
}
input {
outline : 0;
padding : 0px 12px;
}
input:focus {
border-bottom : 1px solid rgb(237, 82, 85);
}
button {
background-color : inherit;
border : 0;
}
`
- ์ ์ญ์ ์ผ๋ก ์ฌ์ฉํ๋ ์คํ์ผ์ ๊ด๋ฆฌ ํฉ๋๋ค.
- ์ปดํฌ๋ํธ ํ์์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
- box-sizing ๊ณผ ๊ฐ์ baseCSS ๊ท์น์ ์ง์ ํ ๋ ์ฌ์ฉ
'๐ Front-End > React.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
React-Query ์บ์ฑ์ ๋ํ์ฌ (0) | 2022.11.12 |
---|---|
react-router-dom V6 ๊ณต๋ถ (0) | 2022.11.11 |
React + TypeScript(state) (0) | 2022.10.26 |
React + TypeScript(Optional Props) (0) | 2022.10.26 |
React + TypeScript(interface) (0) | 2022.10.26 |