프로젝트 이모저모/HoduMarket 프로젝트

리액트+타입스크립트) styled-components theme 설정하기

Ella Seon 2023. 3. 14. 22:27

✅ 글을 쓰게 된 이유

- 버튼 컴포넌트를 만드려고 하는데 타입스크립트에서 theme을 어떻게 설정해야할지 몰라서 정리해본다.

✅ GlobalStyle VS theme

그동안 프로젝트에서 GlobalStyle 에서 아래와 같이 :root를 이용해서 색상을 사용했었다. 

 :root {
    --main-color:#FFB6B0;
    --main-disabled-color:#c8beab;
    --main-text-color:#ffffff;
    --sub-text-color:#767676;
    --border-color:#bdbdbd;
  }

보통은 GlobalStyle에는 reset 또는 공통적으로 사용(box-sizing과 같은 base Css규칙) 하는 css 가 들어가고, 

theme 에는 공통적으로 사용되는 스타일(media query, color 등) 이 들어가고 이것들을 묶을경우 코드 일관성을 지킬 수 있다고 한다. 

그래서 나도 이번에는 theme으로 설정해보려고 한다!

 

1️⃣styled.d.ts : 타입 선언 , 테마 작성하기 (declarations file 만들기)

styles 폴더 안에 생성해준다. 

.d.ts를 타입선언 파일이라고 한다. 사용할 스타일에 type을 선언해주는 파일이다. 

이 파일은 TypeScript 코드와 함께 동작하는 JavaScript 라이브러리나 프로젝트에서 타입 정보를 제공하기 위해 사용한다.

'.d.ts' 파일 자체에는 실행 가능한 코드가 포함 되어있지 않고, 타입에 대한 정보와 구조만 포함되어있다.

(.d.ts 파일은 구현부가 아닌 선언부만을 작성하는 용도의 파일로 JS 코드로 컴파일 되지 않는다. 

선언코드(declare)만 작성이 가능하다)

'styled-components' 모듈에 DefaultTheme 라는 이름의 인터페이스를 생성해 타입을 명시해둔다.

나는 main, darkGray, lightGray 색상을 사용할거라 아래와 같이 표현했다.

 

//styled.d.ts

위 코드는 'styled-components' 라이브러리의 DefaultTheme 인터페이스를 확장하여 추가적인 속성을 제공하는 타입선언을 한다.

colors 라는 속성을 DefaultTheme에 추가하여 해당 속성의 타입은 colors 객체로 지정되어있다. 

이러한 방식으로, TypeScript에서 styled-components를 사용할 때 DefaultTheme에 colors 속성이 포함되어 있다고 인식된다. 이를 통해 사용자가 styled-components의 테마 기능을 사용하면서 동시에 타입 안전성을 유지할 수 있다.

 

2️⃣theme 만들기

- 위에서  타입을 선언한 DefaultTheme을 import 해오고, 변수 옆에 적는다.(타입 지정) 

주의할 점은 colors 안의 value 부분을 문자열로 써주어야한다는 점이다. 

그냥 #21BF48로 했다가...몇십분을 날려먹었다 ㅠㅠ

 

//theme.ts

 

3️⃣ ThemeProvider 추가

App.tsx 파일에 추가한다.

 

4️⃣Button 스타일 컴포넌트에 props.theme 형식으로 theme 컬러를 적용할 수 있다.

 

//style.ts

import styled, { css } from "styled-components";

const StyledButton = styled.button`
  /* 공통 스타일 */
  display: inline-flex;
  outline: none;
  border: 1px solid black;
  border-radius: 4px;
  color: black;
  font-weight: bold;
  cursor: pointer;
  padding-left: 1rem;
  padding-right: 1rem;

  /* 크기 */
  height: 2.25rem;
  font-size: 1rem;

  /* 색상 */
  ${(props) => {
    const selected = props.theme.colors.main;
    return css`
      background: ${selected};
      &:hover {
        background: #c4c4c4;
      }
      &:active {
        background: #ffffff;
      }
    `;
  }}

  /* 기타 */
  & + & {
    margin-left: 1rem;
  }
`;

export default StyledButton;

//Button.tsx

import StyledButton from "./style";

interface ButtonType {
  children: string;
}
function Button({ children, ...rest }: ButtonType) {
  return <StyledButton {...rest}>{children}</StyledButton>;
}

export default Button;

 

아래와 같이 색상이 적용된걸 볼 수 있다

 

 

🔶 번외) 리팩토링

 

1️⃣ theme.ts 파일에서 colors 안의 프로퍼티가 많아질때마다 일일히 styled.d.ts 에서 

main:string 으로 적을 수 없을 노릇이다. 

 

// theme.ts

타입 선언이 너무 많아지니까 type 키워드로 타입별칭을 지어주고 (type alias 검색 ㄱㄱ)

typeof 변수명 을 할당해준다.

import { DefaultTheme } from "styled-components";

const colors = {
  main: "#21BF48",
  lightGray: "#C4C4C4",
  darkGray: "#767676",
};

export type ColorsTypes = typeof colors;

export const theme: DefaultTheme = {
  colors,
};

typeof 연산자는 객체 데이터를 객체 타입으로 변환해주는 연산자다. 아래 예제를 참고.

출처 : Inpa Dev

2️⃣styled.d.ts 타입 선언 파일로 간다.

theme.ts에서 export 한 ColorsTypes를 import 해오고 타입선언부에 넣는다.

3️⃣App.tsx 파일로 가서 아래만 theme에 중괄호를 쳐준다

import { theme } from "./styles/theme";

 

출처

https://watermelonlike.tistory.com/152

 

Styled-Components With TS(theme, globalStyle)

Styled-Components With TS(theme, globalStyle) TypeScript TS에 Styled-Components를 적용해보자 설치 npm install @types/styled-components 1. 테마 공통적으로 사용되는 스타일을 테마로 묶어서 코드일관성을 지킬 수 있도록

watermelonlike.tistory.com

https://velog.io/@hayoung474/Front-End-%EB%B3%B5%EC%9E%A1%ED%95%9C-styled-components-%EA%B5%AC%EC%A1%B0-%EA%B0%9C%EC%84%A0%ED%95%B4%EB%B3%B4%EA%B8%B0

 

[Front-End] 복잡한 styled-components 구조 개선해보기

styled-components 를 주요 스타일링 기술로 사용하지만 구조를 깔끔하게 하고 효율적으로 작성할 줄 모릅니다. 그래서 페이지 하나에 절반이 스타일 관련 코드인 경

velog.io

https://velog.io/@dngur9801/styled-component-%EC%84%A4%EC%A0%95-%EB%B0%8FGlobalStyle%EA%B3%BC-ThemeProvider-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0-with-typescript

 

styled-component 설정 및GlobalStyle과 ThemeProvider 적용하기 with typescript

Next.js로 프로젝트진행중 styled-component 설정 및GlobalStyle과 ThemeProvider을 적용해 보려고 한다. GlobalStyle 적용 방법 styles 폴더안에 global-styles.js 파일 생성 _app.tsx에 적용 impo

velog.io

 

https://watermelonlike.tistory.com/152

 

Styled-Components With TS(theme, globalStyle)

Styled-Components With TS(theme, globalStyle) TypeScript TS에 Styled-Components를 적용해보자 설치 npm install @types/styled-components 1. 테마 공통적으로 사용되는 스타일을 테마로 묶어서 코드일관성을 지킬 수 있도록

watermelonlike.tistory.com

https://kimyk60.tistory.com/40#declarations%20file%20%EB%A7%8C%EB%93%A4%EA%B8%B0-1

 

[styled-components] TypeScript에서 전역 스타일(Global Style) 적용하기

declarations file 만들기 // styled.d.ts import "styled-components"; declare module "styled-components" { export interface DefaultTheme { colors: { gray_100: string; gray_200: string; }; } } 먼저, 선언 파일을 생성해준다. 그리고 DefaultThem

kimyk60.tistory.com

https://inpa.tistory.com/entry/TS-%F0%9F%93%98-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-keyof-typeof-%EC%82%AC%EC%9A%A9%EB%B2%95#typeof_%EC%97%B0%EC%82%B0%EC%9E%90

 

[TS] 📘 객체를 타입으로 변환 keyof / typeof 사용법

타입스크립트 - keyof / typeof typeof 연산자 typeof : 객체 데이터를 객체 타입으로 변환해주는 연산자 아래의 코드의 obj는 객체이기 때문에, 당연히 객체 자체를 타입으로 사용할 수 없다. 그래서 만

inpa.tistory.com