Skip to content

πŸ’„ Styled-Theming을 μ΄μš©ν•˜μ—¬ λ§Œλ“  DarkMode 예제 λ¬Έμ„œμž…λ‹ˆλ‹€.

Notifications You must be signed in to change notification settings

light9639/Styled-Components-Dark-Mode

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ’„ Styled-Theming을 μ΄μš©ν•˜μ—¬ λ§Œλ“  DarkMode 예제 λ¬Έμ„œμž…λ‹ˆλ‹€.

:octocat: λ°”λ‘œ κ°€κΈ° : https://light9639.github.io/Styled-Components-Dark-Mode/

Light Dark

✨ πŸ’„ Styled-Theming을 μ΄μš©ν•˜μ—¬ λ§Œλ“  DarkMode 예제 λ¬Έμ„œμž…λ‹ˆλ‹€. ✨

πŸŽ‰ React ν”„λ‘œμ νŠΈ 생성

  • React 생성
npm create-react-app my-app
# or
yarn create react-app my-app
  • viteλ₯Ό μ΄μš©ν•˜μ—¬ ν”„λ‘œμ νŠΈλ₯Ό μƒμ„±ν•˜λ €λ©΄
npm create vite@latest
# or
yarn create vite
  • ν„°λ―Έλ„μ—μ„œ μ‹€ν–‰ ν›„ ν”„λ‘œμ νŠΈ 이름 λ§Œλ“  ν›„ React 선택, Typescirpt-SWC μ„ νƒν•˜λ©΄ 생성 μ™„λ£Œ.

πŸš› styled-components, styled-theming μ„€μΉ˜

  • styled-components, styled-theming μ„€μΉ˜ν•˜κΈ°
$ npm install styled-components styled-theming
# or
$ yarn add styled-components styled-theming

βœ’οΈ main.tsx, App.tsx μˆ˜μ • 및 μž‘μ„±

⚑ main.tsx

  • components νŒŒμΌμ— μžˆλŠ” ThemeContext, GlobalStyle μ»΄ν¬λ„ŒνŠΈλ₯Ό κ°€μ Έμ˜¨λ‹€.
  • MyThemeProviderλŠ” App을 감싸쀀닀.
  • GlobalStyleλ₯Ό λ„£μœΌλ©΄ μ „μ—­λ³€μˆ˜λ‘œ ν™œμš©μ΄ κ°€λŠ₯ν•˜λ‹€.
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import { MyThemeProvider } from "@components/ThemeContext";
import GlobalStyle from '@components/GlobalStyle'

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <GlobalStyle />
    <MyThemeProvider>
      <App />
    </MyThemeProvider>
  </React.StrictMode>,
)

⚑ App.tsx

  • λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄ ν…Œλ§ˆκ°€ λ°”λ€Œλ„λ‘ 섀정함.
import * as React from "react";
import { useTheme } from "@components/ThemeContext";
import styled, { withTheme } from "styled-components";
import { buttonBackgroundColor, buttonTextColor } from "@components/theme";
import reactLogo from "./assets/react.svg";

interface PropsType {
  theme: {
    mode: string;
  }
}

function App(props: PropsType) {
  const themeToggle: any = useTheme();

  const Button = styled.button`
    background: ${buttonBackgroundColor};
    border: none;
    border-radius: 0.35rem;
    box-shadow: none;
    color: ${buttonTextColor};
    cursor: pointer;
    font-size: 1.25rem;
    padding: 1rem 2rem;
  `;

  return (
    <header className="App-header">
      <img
        src={reactLogo}
        className="App-logo"
        alt="logo"
      />
      <p>
        Edit <code>src/App.js</code> and save to reload.
      </p>
      <p>
        <Button onClick={() => themeToggle.toggle()}>
          {props.theme.mode === "dark"
            ? "Switch to Light Mode"
            : "Switch to Dark Mode"}
        </Button>
      </p>
    </header>
  );
}

export default withTheme(App);

πŸ“ components 파일 속 GlobalStyle.tsx, ThemeContext.tsx, theme.ts μˆ˜μ • 및 μž‘μ„±

⚑ GlobalStyle.tsx

  • createGlobalStyle을 importν•œ ν›„ GlobalStyle λ³€μˆ˜μ— μ €μž₯ν•œλ‹€.
import { createGlobalStyle } from "styled-components";

const GlobalStyle = createGlobalStyle`
    .App {
        font-family: sans-serif;
        text-align: center;
    }

    body {
        margin: 0;
        padding: 0;
    }

    .App-logo {
        animation: App-logo-spin infinite 20s linear;
        height: 25vmin;
        pointer-events: none;
    }

    .App-header {
        min-height: 100vh;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        font-size: calc(10px + 2vmin);
    }

    .App-link {
        color: #61dafb;
    }

    img {
        width: 250px;
        height: 250px;
    }
`;

export default GlobalStyle;

⚑ ThemeContext.tsx

  • ThemeProvider μ•ˆμ— children을 λ§Œλ“€μ–΄μ„œ props ν˜•μ‹μœΌλ‘œ ν…μŠ€νŠΈλ₯Ό μž…λ ₯ν•  수 μžˆκ²Œλ” ν•œλ‹€.
  • toggle ν•¨μˆ˜λ₯Ό λ§Œλ“€μ–΄ App.tsx에 μžˆλŠ” λ²„νŠΌμ„ 클릭할 μ‹œ ν…Œλ§ˆκ°€ λ°”κΎΈλŠ” 것을 κ°€λŠ₯ν•˜κ²Œ λ§Œλ“ λ‹€.
import * as React from "react";
import styled, { ThemeProvider } from "styled-components";
import { backgroundColor, textColor } from "./theme";

const ThemeToggleContext: any = React.createContext(null);

export const useTheme = () => React.useContext(ThemeToggleContext);

interface Type {
    children: JSX.Element
}

export const MyThemeProvider = ({ children }: Type) => {
    const [themeState, setThemeState] = React.useState({
        mode: "light"
    });

    const Wrapper = styled.div`
        background-color: ${backgroundColor};
        color: ${textColor};
    `;

    const toggle = () => {
        const mode = themeState.mode === "light" ? `dark` : `light`;
        setThemeState({ mode: mode });
    };

    return (
        <ThemeToggleContext.Provider value={{ toggle: toggle }}>
            <ThemeProvider theme={{ mode: themeState.mode }}>
                <Wrapper>{children}</Wrapper>
            </ThemeProvider>
        </ThemeToggleContext.Provider>
    );
};

export default ThemeProvider;

⚑ theme.ts

  • ν…Œλ§ˆκ°€ 변경될 λ•Œ backgroundColor와 textColor, buttonBackgroundColor, buttonTextColor의 μžλ£Œλ“€μ„ μž…λ ₯ν•œλ‹€.
import theme from "styled-theming";

export const backgroundColor = theme("mode", {
    light: "#fafafa",
    dark: "#222"
});

export const textColor = theme("mode", {
    light: "#000",
    dark: "#fff"
});

export const buttonBackgroundColor = theme("mode", {
    light: "#222",
    dark: "#eee"
});

export const buttonTextColor = theme("mode", {
    light: "#eee",
    dark: "#222"
});

About

πŸ’„ Styled-Theming을 μ΄μš©ν•˜μ—¬ λ§Œλ“  DarkMode 예제 λ¬Έμ„œμž…λ‹ˆλ‹€.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published