오늘은 글로벌 스타일 적용하고, 스타일 컴포넌트에 타입 적용하는 방법을 해보겠돠.
하루에 아조조~금씩🔨 야금야금🔨
styled-components
설치npm i styled-component
npm i -D @types/styled-components
styled-components
를 사용할때 보통 테마/전역스타일 코드를 분리하여 사용한다.
추가로 내가 생성할 styled-components
의 타입을 지정하기 위한 styled.d.ts
파일을 추가로 생성하자.
src/styles/theme.ts
src/styles/styled.d.ts
src/styles/global-style.ts
styled.d.ts
styled-components 공식문서 : typescript 적용하기
styled-components
의 타입정의를 불러와 내가 사용할 신규 타입정의 추가 & 확장함
// import original module declarations
import 'styled-components'
// and extend them!
declare module 'styled-components' {
// 우리가 아는 타입지정을 여기서 다해주고 불러서 쓰기
// 1. 인터페이스 지정
export interface 인테페이스명지정 {
속성1 : 타입지정;
}
// 2. 타입속성지정
export type // 타입~~~지정지정해~
// ThemeProvider theme에 적용할 타입으로, theme의 속성과 동일하게 작성
export interface DefaultTheme {
dark: {
mainBackground: string;
// neutral color
title: string;
primaryText: string;
secondaryText: string;
disable: string;
border: string;
divider: string;
background: string;
tableHeader: string;
};
light: {
mainBackground: string;
// neutral color
title: string;
primaryText: string;
secondaryText: string;
disable: string;
border: string;
divider: string;
background: string;
tableHeader: string;
// point-color
// point-color
};
response: {};
}
}
defaultTheme
인터페이스는node_modules/@types/styled-components/ts3.7/index.d.ts
에 정의되어있다(빈객체 상태). 해당 인터페이스를 확장하는 개념이다!
createGlobalStyle
적용하기styled-reset
이 있어 받아보았다.npm i styled-reset
으로 설치<Reset />
컴포넌트를 불러 최상위에 위치시킴createGlobalStyled
에 적용<Reset />
으로 전역스타일 설정import { Reset } from 'styled-reset';
const App = () => (
<>
<Reset /> {/* 여기에 리셋-컴포넌트 위치 */}
<div>여기는 최상위 컴포넌트</div>
</>
);
createGlobalStyled
으로 전역스타일 설정src/styles/global-style.ts
// global-style.ts
import { createGlobalStyle } from 'styled-components';
import { reset } from 'styled-reset';
// 외부에서 import 할거니까 모듈 내보내자~!
export const GlobalStyle = createGlobalStyle`
${reset}
/* 그밖에 글로벌 스타일 작성하기 */
`;
// 최상위 컴포넌트 : App.js 또는 index.js 등등 원한느 최상위에 코드 추가
import {GlobalStyle} from '파일경로/global-style.ts'
const App = () => (
<>
<GlobalStyle /> {/* 여기에 글로벌-스타일-컴포넌트 위치 */}
<div>여기는 최상위 컴포넌트</div>
</>
);
// theme.js
import styled, { css } from 'styled-components';
export const theme:defaulTheme = {
dark: {
mainBackground: `#333`,
// neutral color
title: `rgba(255,255,255,0.85)`,
primaryText: `rgba(255,255,255,0.65)`,
secondaryText: `rgba(255,255,255,0.45)`,
disable: `rgba(255,255,255,0.25)`,
border: `rgba(255,255,255,0.15)`,
divider: `rgba(255,255,255,0.06)`,
background: `rgba(255,255,255,0.04)`,
tableHeader: `rgba(255,255,255,0.02)`,
// point-color
},
light: {
mainBackground: `#fff`,
// neutral color
title: `rgba(0, 0, 0, 0.85)`,
primaryText: `rgba(0, 0, 0, 0.75)`,
secondaryText: `rgba(0, 0, 0, 0.45)`,
disable: `rgba(0, 0, 0, 0.25)`,
border: `rgba(0, 0, 0, 0.15)`,
divider: `rgba(0, 0, 0, 0.06)`,
background: `rgba(0, 0, 0, 0.04)`,
tableHeader: `rgba(0, 0, 0, 0.02)`,
// point-color
},
response: {},
};
response: {},
};
// _app.tsx or App.jsx
// 최상위컴포넌트에서 ThemeProvider 사용하기
import { ThemeProvider } from 'styled-components';
import { theme } from './../src/styles/theme';
// ... 상단 생략
return (// 기본 라이트 모드 지정
<ThemeProvider theme={theme.light}>
<Component />
</ThemeProvider>
)
// Component.tsx or Component.js : 하위 컴포넌트 전체에서
// 스타일드-컴포넌트 정의
const Container = styled.div`
background-color: ${(props) => props.theme.mainBackground};
color: ${(props) => props.theme.primaryText};
`;
// 컴포넌트 정의
const Component = () => {
return (
<Container>
<h1>테마적용하기🎨</h1>
</Container>
);
};
theme.dark 모드
theme.light 모드
예제와 같이 theme객체에 같은 이름의 key를 갖는 mode객체를 만들어 ThemeProvider 컴포넌트에 props를 넘겨 전체 컴포넌트 모드변경할때 적용색상이 변경하도록 함!
theme 객체를 작성할때 depth가 깊어지지 않도록 주의! 하위컴포넌트에서 theme속성 적용할 때 이름이 길어진다!
참고 자료 : Styled Components & TypeScript - 😍
props
를 사용하여 컴포넌트를 정의한다면 인터페이스를 사용하여 분리하여 사용할 수 있다.styled.div<인터페이스명>
와 같이 사용한다.// styled-components에 1개 props 타입지정
// const Container = styled.div< {프롭스명 : 타입지정} >`
const Container = styled.div< { age : number } >`
color: ${(props) => (props.age > 20 ? 'red' : 'gray')};
`;
// Container styled-components에 적용할 interfacer를 작성
interface Container extends 상속타입 {
isActive: boolean;
age: number;
프롭스명: 타입지정;
}
// styled-components에 interface 타입 지정하기
const Container = styled.div<Container>`
color: ${(props) => (props.age > 20 ? 'red' : 'gray')};
background-color: ${(props) => (props.isActive ? 'red' : 'gray')};
`;
// 상속컴포넌트의 타입 상속받기
interface Container {
isActive: boolean;
age: number;
프롭스명: 타입지정;
}
// 상속받은 컴포넌트에 타입 추가하기
const Container = styled(상속받을 컴포넌트명)<Container>`
color: ${(props) => (props.age > 20 ? 'red' : 'gray')};
background-color: ${(props) => (props.isActive ? 'red' : 'gray')};
`;
// 기존 방식과 동일하게 사용
const Container = styled(상속받을 컴포넌트명)< { age : number } >`
color: ${(props) => (props.age > 20 ? 'red' : 'gray')};
`;
// 위 방식에 문제가 있을경우 아래와 같이 사용.. 하나 복잡!
const Container = styled(({ age, ...parentProps }) => (
<상속받을컴포명 {...parentProps} />
))<{
age: number;
}>`
color: ${(props) => (props.active ? 'red' : 'blue')};
`;
age
과, 부모의 타입:parentProps
을 전개연산자(...parentProps
)로 지정const customMediaQuery = (maxWidth: number):string => {
// 최대폭을 입력하면. 문자열을 밷는다!
return `@media (max-width: ${maxWidth}px)`;
}
// 각 디바이스에 따라 최대폭 값을 변수화
const media = {
custom: customMediaQuery,
desktop: customMediaQuery(922),
tablet: customMediaQuery(768),
phone: customMediaQuery(576),
};
const Content = styled.div`
height: 3em;
width: 3em;
background: papayawhip;
${media.desktop} {
background: dodgerblue;
}
${media.tablet} {
background: mediumseagreen;
}
${media.phone} {
background: palevioletred;
}
`;
${media.desktop} { color: red;}
=== @media (max-width: 922px) {color:red}
감사합니다...ㅠㅠ 삽질하고 있었는데 한 번 쭉 읽어봐야겠네요