본문 바로가기

Styled Components로 Tab 만들기

Styled Components로 Tab 만들기

 

*  React, Styled-Component, Storybook을 활용한 UI 컴포넌트 개발 
*  Styled Components를 활용해 Tab 커스텀 컴포넌트를 구현 

 

Tab Component

 

완성 예시

 

 

Tab UI 컴포넌트는 동일한 메뉴 라인에서 뷰를 전환할 때 사용한다. 

 

필요한 컴포넌트

TabMenu (ul) : Tab 상위바에서 메뉴를 선택할 수 있는 구역

  • li ClassName "submenu focused" 또는 "submenu" (조건부 스타일링)

Desc (div) : 선택한 Tab에 따라 넣어둔 텍스트를 담는 컴포넌트

 

state

Tab 컴포넌트는 아래와 같은 state가 존재한다.

  • currentTab state : 현재 tab의 index를 확인 

토글 버튼 제어를 위한 핸들러 함수 selectMenuHandler는 탭을 클릭하기 위한 메뉴 컴포넌트에 넣어준다.

  • selectMenuHandler 함수 :
    • TabMenu 클릭 시 발생되는 change 이벤트 핸들러 
    • 클릭할 때마다 상태가 index 값으로 변경 
  • li 요소를 이용해 탭 메뉴를 생성하고, 각 메뉴를 눌렀을 때 뷰가 전환되도록 handler(selectMenuHandler) 함수가 작동한다.
  • 조건부 스타일링과 currentTab 상태를 이용하여 클릭한 Tab 메뉴만 className(submenu focused)과 CSS 가 변경된다.

 

구현 코드 

 

Tab UI Component 코드
import { useState } from 'react';
import styled from 'styled-components';

// > 를 붙여주면 한 단계 아래의 자식 요소들만, 붙여주지 않으면 모든 후손 요소들이 선택된다.
const TabMenu = styled.ul`
  background-color: #dcdcdc;
  color: rgba(73, 73, 73, 0.5);
  font-weight: bold;
  display: flex;
  flex-direction: row;
  justify-items: center;
  align-items: center;
  list-style: none;
  margin-bottom: 7rem;

  .submenu {
    ${'' /* 기본 Tabmenu 에 대한 CSS */}
    background: blue;
    width: calc(100% /3)             // 3개의 Tab을 1/3
  }

  .focused {
    ${'' /* 선택된 Tabmenu 에만 적용되는 CSS */}
    background: blue;
    color: white;
  }
`;

const Desc = styled.div`
  text-align: center;
`;

export const Tab = () => {
  // Tab Menu 중 현재 어떤 Tab이 선택되어 있는지 확인하기 위한 currentTab 상태와 currentTab을 갱신하는 함수가 존재해야 하고, 초기값은 0
  const [currentTab, setCurrentTab] = useState(0)

  // Tab Menu 
  const menuArr = [
    { name: 'Tab1', content: "Tab menu ONE : Today's wether" },
    { name: 'Tab2', content: 'Tab menu TWO : To Do List' },
    { name: 'Tab3', content: 'Tab menu THREE : Diary' },
  ];

  const selectMenuHandler = (index) => {
    setCurrentTab(index)
  };

  return (
 <>
      <div>
      
        <TabMenu>
         
          <!-- <li className="submenu">{menuArr[0].name}</li>
          <li className="submenu">{menuArr[1].name}</li>
          <li className="submenu">{menuArr[2].name}</li> -->


          {menuArr.map( (menu, index) => { 
          return(
              <li key={index}       
                  className={currentTab === index ? "submenu focused" : "submenu"}
          <!--또는 className={`'submenu${idx === currentTab ? ' focused':''}`}-->
                  onClick={() => selectMenuHandler(index)}>
                {menu.name}
              </li>)
          })}
          
        </TabMenu>
        
        <Desc>
          <p>{menuArr[currentTab].content}</p>
        </Desc>
      </div>
    </>
  );
};

 

포인트

 

TabMenu

  • TabMenu 내부에 .submenu 클래스명을 가진 li 요소들을 map을 이용한 반복을 통해 생성한다.
  • TabMenu 내부에 .submenu 클래스명을 가진 li 요소의 textContent는 각 요소의 name이다. (Tab 메뉴)

currentTab

  • 조건부 렌더링을 활용해서 Tab 메뉴가 선택된 상태일 때, 선택된 Tab 메뉴 li 요소의 클래스명만 submenu focused 가 되어야 하고, 선택되지 않은 나머지는 submenu 가 된다.
  • TabMenu를 클릭하면
    • 현재 선택된 탭의 인덱스 값을 전달받아 currentTab 상태를 변경하는 selectMenuHandler 메서드가 실행된다.
    • 현재 선택된 탭 메뉴만 li 요소에 클래스가 추가되어 .focused CSS가 적용되며,
    • Desc 컴포넌트의 content의 내용이 해당 탭의 content로 바뀐다.

 

728x90

'FE > React' 카테고리의 다른 글

Styled Components로 ClickToEdit 만들기  (0) 2023.04.20
Styled Components로 Tag 만들기  (0) 2023.04.20
Styled Components로 Toggle 만들기  (0) 2023.04.20
Styled Components로 Modal 만들기  (0) 2023.04.20
React Custom Component 개요  (0) 2023.04.19
⬆︎