[TypeScript]다크모드 Toggle버튼 구현

seovee·2023년 6월 11일
0
post-thumbnail

✔ 왜 만들게 되었는가?

단순히 페이지에서 다크모드를 구현하는 것은 굉장히 쉽다. 하지만 프론트엔드에게는 재사용성을 고려한 Component를 만드는 것이 굉장히 중요하지 않은가?😎

Toggle Component를 TypeScript환경에서 만들어보았다.

대부분 구글링으로 정보를 찾아본 것으로 이것이 정석이 아닐 수 있다.

✔ 구현방법

Toggle버튼가상요소(::before, ::after)를 활용했고,
ThemeProvider와 useState로 Props테마가 변하도록 구현해보았다.

  1. DarkmodeBtn.tsx 파일을 만든다.

  2. input을 만들고 type="checkbox"로 만들고, styled-component로 CSS를 넣어주었다. 체크박스 자체는 뒤에 가리도록 트릭을 사용했다.

const Checkbox = styled.input`
  width: 5rem;
  height: 2rem;
  background: white;
  border-radius: 2em;
`

function DarkmodeBtn() {
  return (
    <Container>
      <CheckboxLabel>Theme</CheckboxLabel>
      <Checkbox type="checkbox" id="toggle" />
    </Container>
  );
}

export default DarkmodeBtn;
  1. 가상요소(::before, ::after), 가상선택자(:checked)를 활용하여 CSS를 만들어준다.
const Checkbox = styled.input`
  width: 5rem;
  height: 2rem;
  background: white;
  border-radius: 2em;
  &::before {
    content: "";
    text-align: center;
    line-height: 50px;
    width: 100px;
    height: 50px;
    display: block;
    position: absolute;
    border-radius: 30px;
    background-color: white;
    box-shadow: 0 0 16px 3px rgba(0 0 0 / 15%);
    transition: all 0.2s ease-in;
    cursor: pointer;
  }
  &::after {
    content: "";
    display: block;
    position: relative;
    width: 40px;
    height: 40px;
    top: 5px;
    left: 5px;
    border-radius: 50%;
    background: #2f3640;
    transition: all 0.2s ease-in;
  }
  &:checked {
    &::before {
      background-color: #585d6d;
    }
    &::after {
      background-color: white;
      left: calc(100% - 25px);
    }
  }
`

그럼 이러한 결과물이 나올 것이다. 색상이나 크기는 원하는대로 정해주면 된다.

  1. App.tsx에서 ThemeProvider를 통해 테마를 결정해주고, useState상태 정해주는 "ToggleTheme함수"를 Props로 전달해주자.
    (ThemeProvider사용방법은 구글에 검색하면 금방 나오므로 생략)
import { ThemeProvider, createGlobalStyle } from "styled-components";

function App() {
  const [theme, setTheme] = useState<boolean>(false);
	// 타입스크립트에게 useState는 boolean이라는 것을 알려준다.
  
  const ToggleTheme = () => {
    setTheme((prev) => !prev);
  };

  return (
    <>
      <ThemeProvider theme={theme ? darktheme : lighttheme}>
        <GlobalStyle />
        <DarkmodeBtn toggleTheme={ToggleTheme} />
          // 
        <Router />
      </ThemeProvider>
    </>
  );
}

export default App;
  1. 다시 DarkmodeBtn.tsx로 돌아와서
interface IToggleProps {
  toggleTheme: () => void;
}
// Props 타입은 함수라는걸 알려줌.

function DarkmodeBtn({ toggleTheme }: IToggleProps) {
  return (
    <Container>
      <CheckboxLabel></CheckboxLabel>
      <Checkbox type="checkbox" id="toggle" onClick={() => toggleTheme()} />
    </Container>
  );
}

✔ Toggle Component 완성!!

checkbox가 체크되면 lighttheme가 실행이 되고, 체크가 해제되면 darktheme가 실행된다. 거꾸로 만들었어야했는데...ㅋㅋ

아직 초보자여서, 검색하면서 만드는데 5시간 정도 걸렸다. 아마 방법이 이상할 수도 있다고 생각한다. 이상한 곳이 있으면 문의바란다.

✔ 이슈 & 배운점 🧐

  1. Props 전달할 때, 전달하는 곳 + 전달받는 곳 둘다 타입을 선언해야 한다는 것을 알게됨
  2. Styled-component를 통해서 가상요소와 가상선택자의 활용성을 경험할 수 있었다. 굉장히 편하군..후후🧐 그럼 이만!

끝~!

profile
낭만이 빠지면 섭하지

0개의 댓글