[React] Toggle Component 구현하기

fejigu·2022년 8월 29일
5

Toy Project

목록 보기
4/6


👉🏻 toggle UI 컴포넌트는 두 가지 상태만을 가지고 있는 스위치이다. 모달창을 구현하고 나서인지 Toggle 컴포넌트 구현은 비교적 쉽게 할 수 있었다. 다시 정리하며 복습하고자 한다.


💻 Toggle 구현 결과

✔️ Toggle Switch가 ON 일 때 css, 텍스트 변경
✔️ Toggle Switch가 OFF 일 때 css, 텍스트 변경
✔️ transition 효과 넣어 자연스럽게 움직이게 만들기


⭐️⭐️⭐️ 다시 확인할 부분

🔎 조건부 스타일링 : 기본 CSS에서는 템플릿 리터럴삼항 연산자를 활용해 조건부 스타일링을 적용할 수 있다.

<div className={`toggle-container ${isOn ? "toggle--checked" : ""}`} />

🔎 transition : 부드럽게 옮겨지는 애니메이션 효과를 주기 위해서는 CSS의 transition 속성을 활용할 수 있다. ex) transition : 0.5s


💻 Toggle 코드

import { useState } from 'react';
import styled from 'styled-components';

const ToggleContainer = styled.div`
  position: relative;
  margin-top: 8rem;
  left: 47%;
  cursor: pointer;

  > .toggle-container {
    width: 50px;
    height: 24px;
    border-radius: 30px;
    background-color: rgb(233,233,234);}
    //.toggle--checked 클래스가 활성화 되었을 경우의 CSS를 구현
  > .toggle--checked {
    background-color: rgb(0,200,102);
    transition : 0.5s
  }

  > .toggle-circle {
    position: absolute;
    top: 1px;
    left: 1px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background-color: rgb(255,254,255);
    transition : 0.5s
    //.toggle--checked 클래스가 활성화 되었을 경우의 CSS를 구현
  } >.toggle--checked {
    left: 27px;
    transition : 0.5s
  }
`;

const Desc = styled.div`
  //설명 부분의 CSS를 구현
  text-align: center;
  margin: 20px;
`;

export const Toggle = () => {
  const [isOn, setisOn] = useState(false);

  const toggleHandler = () => {
    // isOn의 상태를 변경하는 메소드를 구현
    setisOn(!isOn)
  };

  return (
    <>
      <ToggleContainer
        // 클릭하면 토글이 켜진 상태(isOn)를 boolean 타입으로 변경하는 메소드가 실행
        onClick={toggleHandler}
      >
        {/* 아래에 div 엘리먼트 2개가 있다. 각각의 클래스를 'toggle-container', 'toggle-circle' 로 지정 */}
        {/* Toggle Switch가 ON인 상태일 경우에만 toggle--checked 클래스를 div 엘리먼트 2개에 모두 추가. 조건부 스타일링을 활용*/}
        <div className={`toggle-container ${isOn ? "toggle--checked" : null}`}/>
        <div className={`toggle-circle ${isOn ? "toggle--checked" : null}`}/>
      </ToggleContainer>
      {/* Desc 컴포넌트를 활용*/}
      {/* Toggle Switch가 ON인 상태일 경우에 Desc 컴포넌트 내부의 텍스트를 'Toggle Switch ON'으로, 그렇지 않은 경우 'Toggle Switch OFF'. 조건부 렌더링을 활용. */}
      {isOn === false ?
      <Desc><div className='OFF'>FEJIGU Toggle Switch OFF</div></Desc> :
      <Desc><div className='ON'></div>FEJIGU Toggle Switch ON</Desc>}
    </>
  );
};

+ 추가 토글 버튼(23.11.10)

//React & styled-components
<ToggleSwitch>
	<CheckBox
	type="checkbox"
	checked={isActive}
	onChange={() => setIsActive(!isActive)}
	/>
	<ToggleSlider />
</ToggleSwitch>

...

const ToggleSwitch = styled.label`
  position: relative;
  display: inline-block;
  width: 47.7px;
  height: 23.33px;
`;

const ToggleSlider = styled.span`
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  -webkit-transition: .4s;
  transition: .4s;
  border-radius: 34px;

  &:before {
    position: absolute;
    content: "";
    height: 15px;
    width: 15px;
    left: 4px;
    bottom: 4px;
    background-color: white;
    -webkit-transition: .4s;
    transition: .4s;
    border-radius: 50%;
  }
`;

const CheckBox = styled.input`
  opacity: 0;
  width: 0;
  height: 0;

  &:checked + ${ToggleSlider} {
    background-color: #ED6A2C;
  }

  &:focus + ${ToggleSlider} {
    box-shadow: 0 0 1px #2196F3;
  }

  &:checked + ${ToggleSlider}:before {
    -webkit-transform: translateX(26px);
    -ms-transform: translateX(26px);
    transform: translateX(26px);
  }
`;

+ 추가 토글 버튼 2(23.11.13)

//React & inline
<Switch
	checked={isToggleOn} // isToggleOn 상태를 확인하여 토글 상태를 설정
	onChange={() => setIsToggleOn(!isToggleOn)} // 토글 버튼 클릭 시 상태 변경
	onColor="#ED6A2C" // 토글 활성화 배경색
	offColor="#A1A1A1"   // 토글 비활성화 배경색
	handleDiameter={22} // 핸들 지름 설정
	activeBoxShadow="0 0 2px 3px #ED6A2C" // 토글 활성화 박스 쉐도우
	boxShadow="0 0 2px 3px #A1A1A1" // 토글 비활성화 박스 쉐도우
	className="custom-switch" // 커스텀 클래스 추가
/>
profile
신규 서비스의 기획부터 개발, 운영까지 전 과정을 경험한 주니어 📱

2개의 댓글

comment-user-thumbnail
2023년 1월 11일

감사합니다! 덕분에 쉽게 토글을 만들었네용 🤩

1개의 답글