본문 바로가기

React

[React] 가상화폐시세 사이트 2 - Theme 적용

styled-components의 DefaultTheme를 사용하여 테마를 사용할 수 있다

  • 미리 정해둔 색과 수치 사용으로 통일성 제공
  • theme를 변경하여 라이트 / 다크 모드 전환 등을 쉽게 변경 가능
1. styled.d.ts 파일 생성
// styled.d.ts
import "styled-components";

declare module "styled-components" {
  export interface DefaultTheme {
    bgColor: string;
    textColor: string;
    accentColor: string;
  }
}
2. theme.ts 파일 생성
// theme.ts
import { DefaultTheme } from "styled-components/dist/types";

export const lightTheme: DefaultTheme = {
  bgColor: "#dfe4ea",
  textColor: "#2f3542",
  accentColor: "#ff4757",
};

export const darkTheme: DefaultTheme = {
  bgColor: "black",
  textColor: "white",
  accentColor: "black",
};
3. index.tsx 에 ThemeProvider 적용
// index.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { ThemeProvider } from "styled-components";
import { lightTheme } from "./theme";

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
root.render(
  <ThemeProvider theme={lightTheme}>
    <App />
  </ThemeProvider>
);
4. theme props 적용1
// App.tsx
const GlobalStyle = createGlobalStyle`
  /* theme */
  body {
    background-color:${(props) => props.theme.bgColor};
    color: ${(props) => props.theme.textColor}
  }
5. theme props 적용2
// Coins.tsx
import styled from "styled-components";
import { Link } from "react-router-dom";

const Container = styled.div`
  padding: 0px 20px;
`;

const Header = styled.header`
  height: 10vh;
  display: flex;
  justify-content: center;
  align-items: center;
`;

const CoinsList = styled.ul``;

const Coin = styled.li`
  background-color: ${(props) => props.theme.textColor};
  color: ${(props) => props.theme.bgColor};
  border-radius: 15px;
  margin-bottom: 10px;
  a {
    padding: 20px;
    transition: color 0.15s ease-in;
    display: block;
  }
  &:hover {
    a {
      color: ${(props) => props.theme.accentColor};
    }
  }
`;

const Title = styled.h1`
  font-size: 48px;
  color: ${(props) => props.theme.accentColor};
`;

const coins = [
  {
    id: "btc-bitcoin",
    name: "Bitcoin",
    symbol: "BTC",
    rank: 1,
    is_new: false,
    is_active: true,
    type: "coin",
  },
];

function Coins() {
  return (
    <Container>
      <Header>
        <Title>Coin</Title>
      </Header>
      <CoinsList>
        {coins.map((coin) => (
          <Coin key={coin.id}>
            <Link to={`/${coin.id}`}>{coin.name} &rarr;</Link>
          </Coin>
        ))}
      </CoinsList>
    </Container>
  );
}

export default Coins;