팀프로젝트: Wingle(2.1) 공통UI 제작 - 드롭다운 컴포넌트

윤뿔소·2023년 5월 12일
0

팀프로젝트: Wingle

목록 보기
14/16

이제 드롭다운을 만들어 보겠다.

디자인/기능 기획

드롭다운 내장 태그인 select는 당연히 못쓴다. 디자인 커스텀이 제한적이기 때문에!

그래서 위 사진 같이 드롭다운을 눌렀을 때 div가 나와야한다. 또 선택 전, 선택 중, 선택 후 border, Text color가 달라져야하고, disable가 있다.

그리고 Hover되거나, Selected가 된 요소들은 다른 배경색을 가져야한다. 구현해야할 게 많다 너무

기능구현

이제 만들어보자!

Props 제작

저렇게 텍스트로 받아야하니 string으로 된 배열을 하나 받고, 선택된 항목을 관리하는 상태, 선택을 관리해주는 핸들러, Input에서 했던 것처럼 disabled, 제목 받는 label, description, placeholder를 받아줄 것이다.

코드는 다음과 같다.

interface DropDownProps {
  label?: string; // 제목
  list: string[]; // 드롭다운 리스트
  selected: string; // 선택된 항목(selected state)
  dropDownPlaceHolder?: string; // 드롭다운 플레이스홀더
  handleSelectedChange: (selected: string) => void; // 선택된 항목 변경 함수(selected setState 변경 함수)
  description?: string; // 드롭다운 설명
  disabled?: boolean; // 드롭다운 비활성화
}
export default function DropDownCommon({
  label,
  list,
  selected,
  dropDownPlaceHolder,
  handleSelectedChange,
  description,
  disabled = false,
}: DropDownProps)

이렇게 받아줄 것이다!

드롭다운 기본형태 만들기

드롭다운 기본 형태를 만들어야한다.

  1. isActive 상태를 만듦. boolean 데이터 사용하여 드롭다운 클릭하면 수정되게
    • toggleDropdownonClick 이벤트 관리
  2. isActive에 따라 DropdownMenuContainer같은 div 조정
  3. handleSelect같은 핸들러를 만들어 펼쳐진 드롭다운 onClick 이벤트 추가. 클릭하면 isActivefalse.

만들어보자!

  const [isActive, setIsActive] = useState(false);

  const toggleDropdown = () => {
    setIsActive(!isActive);
  };

  const handleSelect = () => {
    setIsActive(false);
  };

  return (
    <S.Container>
      <S.DropdownContainer>
        <S.DropdownBody
          onClick={toggleDropdown}
          isActive={isActive}
        >
        </S.DropdownBody>

        <S.DropdownMenuContainer isActive={isActive}>
          {list.map((item) => (
            <S.DropdownItemContainer
              key={item}
              onClick={() => {
                handleSelect();
              }}
            >
              {item}
            </S.DropdownItemContainer>
          ))}
        </S.DropdownMenuContainer>
      </S.DropdownContainer>
    </S.Container>
  );

이렇게 하면 클릭하면 DropdownMenuContainer가 나올 것이고, item들이 map으로 들어간다.
그 들어간 DropdownItemContainer를 클릭하면 handleSelect가 실행되고, isActivefalse가 되고 드롭다운 확장 div가 없어질 것이다.
나중에 CSS 작성할 때 isActive를 조건으로 block, none 바뀌게 할 것이다.

결과

오늘은 디자인만 만들었기 때문에 일단 지금까지 짰던 디자인을 보자.

Test한 코드는 아래와 같다.

import { useState } from "react";
import { Margin } from "../components/ui";
import DropDown from "../components/ui/dropDownUI";
import styled from "styled-components";

export default function Test() {
  const [selected, setSelected] = useState<string>("");
  const handleSelectedChange = (selected: string) => {
    setSelected(selected);
  };

  const countryList = [
    {
      code: "KR",
      nation: "대한민국",
      add_code_nation: "KR 대한민국",
      country: "REPUBLIC OF KOREA",
    },
    {
      code: "CN",
      nation: "중화인민공화국",
      add_code_nation: "CN 중화인민공화국",
      country: "CHINA",
    },
    {
      code: "VN",
      nation: "베트남",
      add_code_nation: "VN 베트남",
      country: "VIET NAM",
    },
  ];

  return (
    <S.Wrapper>
      <Margin size={50} direction="column" />
      <div>
        <Margin size={8} direction="row" />
        <DropDown
          label="안녕"
          list={countryList.map((item) => item.country)}
          selected={selected}
          handleSelectedChange={handleSelectedChange}
        />
      </div>
    </S.Wrapper>
  );
}

const S = {
  Wrapper: styled.div`
    padding-left: 24px;
    padding-right: 24px;
  `,
};

listscountryList 객체를 string으로 이루어진 리스트로 바꿧다.
selected상태와 setter 함수가 담긴 handleSelectedChange도 일단 임시적으로 넣어줬다.

짠! 이제 잘 나온다! 사실 좀 디자인 했는데 그거는 styled된 코드 할 때 설명하겠다.

다음 편에서는 기능까지 잇고, style하는 시간을 갖겠다.

profile
코뿔소처럼 저돌적으로

4개의 댓글

comment-user-thumbnail
2023년 5월 14일

오늘도 잘 보고 갑니닷 !!

답글 달기
comment-user-thumbnail
2023년 5월 14일

고생하셨습니다

답글 달기
comment-user-thumbnail
2023년 5월 14일

디자인까지 완성한 것도 빨리 보고싶네요 :D

답글 달기
comment-user-thumbnail
2023년 5월 14일

디자인 엄청 깔끔하네요 진짜!!!

답글 달기