본문 바로가기

Styled Components로 Tag 만들기

Styled Components로 Tag 만들기

 

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

 

Tag Component

 

완성 예시

 

 

Tag UI 컴포넌트는 레이블 지정을 통해 구성이나 분류에 도움이 되는 키워드 집합을 만들 때 사용된다. 

 

필요한 컴포넌트

TagInput (div) : Tag 최상위 박스

  • ul id "tags"  
    • li className "tag" : 각각의 tag 박스 (나열)
      • span className "tag-title" 
      • span className "tag-close-icon" 
  • input className "tag-input" : tag를 입력하여 추가하는 구역

 

state

  • Tag 컴포넌트는 아래와 같은 state가 존재한다.
    • tags state : 배열의 형태로 초깃값으로 initialTags를 가지고 있다. (예: ["Doyu", "React", "Layout"])
  • (1) 태그를 추가하기 위한 핸들러 함수 addTags는 새로운 태그값을 입력하는 칸에 넣어준다.
    • addTags 함수 :
      • input 창에 Enter 키를 누를 때 발생되는 change 이벤트 핸들러 
      • Enter를 입력할 때마다 입력한 값이 state에 추가 
  • (2) 태그를 삭제하기 위한 핸들러 함수 removeTags는 개별 태그 박스 안의 (X) 버튼에 달아준다.
    • removeTags 함수 :
      • 태그 박스 안의 (X) 버튼을 누를 때 발생되는 click 이벤트 핸들러
      • 클릭을 할 때 마다 해당 태그와 관련된 값이 state에서 삭제

 

구현 코드 

 

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

export const TagsInput = styled.div`
  margin: 8rem auto;
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  min-height: 48px;
  width: 480px;
  padding: 0 8px;
  border: 1px solid rgb(214, 216, 218);
  border-radius: 6px;

  > ul {
    display: flex;
    flex-wrap: wrap;
    padding: 0;
    margin: 8px 0 0 0;

    > .tag {
      width: auto;
      height: 32px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      padding: 0 8px;
      font-size: 14px;
      list-style: none;
      border-radius: 6px;
      margin: 0 8px 8px 0;
      background: #0000f1;
      > .tag-close-icon {
        display: block;
        width: 16px;
        height: 16px;
        line-height: 16px;
        text-align: center;
        font-size: 14px;
        margin-left: 8px;
        color: var(--coz-purple-600);
        border-radius: 50%;
        background: #fff;
        cursor: pointer;
      }
    }
  }

  > input {
    flex: 1;
    height: 46px;
    font-size: 14px;
    padding: 4px 0 0 0;
    :focus {
      outline: transparent;
    }
  }

  &:focus-within {           // "&"는 TagsInput 나타내는 선택자 (자기자신)
    border: 1px solid purple;
  }
`;

export const Tag = () => {
  const initialTags = ['Doyu', 'kimcoding'];

  const [tags, setTags] = useState(initialTags);

  const removeTags = (indexToRemove) => {
    setTags( tags.filter( (_,idx) => idx !== indexToRemove ));        // 첫 번째 인자를 안 쓰는 경우 '_' 기호 사용
  };

  const addTags = (event) => {
    if (event.target.value && !tags.includes(event.target.value)) {   // - 이미 입력되어 있는 태그인지 검사하여 이미 있는 태그라면 추가하지 말기
      // console.log(typeof event.target.value)                       // - 아무것도 입력하지 않은 채 Enter 키 입력시 메소드 실행하지 말기
      setTags([...tags, event.target.value])
      event.target.value = '';                                        // - 태그가 추가되면 input 창 비우기
    }
  };

  // typeof event.target.value 는 'string'이다. ('0' 등의 숫자를 입력해도)
 return (
    <>
      <TagsInput>
      
        <ul id="tags">
          {tags.map((tag, index) => (
            <li key={index} className="tag">
              <span className="tag-title">{tag}</span>
              <!--'HTML Entities' 중 하나인 &Times;는 X 곱하기 부호를 나타낸다. -->
              <span className="tag-close-icon" onClick={() => removeTags(index)}>&times;</span>
            </li>
          ))}
        </ul>
        
        <input
          className="tag-input"
          type="text"
          onKeyUp={ e => {if(e.key === 'Enter') addTags(e)}} 
  <!-- 또는 onKeyUp={(e) => (e.key === 'Enter' ? addTags(e) : null)} -->
          placeholder="Press enter to add tags"
        />
        
      </TagsInput>
    </>
  );
};

 

포인트

 

🟣 onKeyup

 

 

onkeyup (KeyCode 값) : 사용자가 키보드의 키를 눌렀을 때

  • value(텍스트)가 입력된 후 이벤트가 실행된다.
  • 예: 'Hi!' 에서 'H'를 누르고 난 후 value : 'H' 

onkeydown (KeyCode 값) : 사용자가 키보드의 키를 눌렀다가 땔 때

  • value(텍스트)가 입력되기 전에 이벤트가 실행된다.
  • 예: 'Hi!' 에서 'H'를 누르고 난 후 value : '' 

onkeypress (ASCII 값) : 사용자가 키보드의 키를 눌렀을 때

  • value(텍스트)가 입력되기 전에 이벤트가 실행된다.
  • 예: 'Hi!' 에서 'H'를 누르고 난 후 value : '' 
  • shift, ctrl 등의 key 인식 못 함

 

🟣 event.key 와 event.code

event.key : 사용자가 실제 키보드 키를 나타내는 문자열 값 반환

  • 예: 'A', 'Enter', 'Backspace', '1' .... 
  • 한국어 키보드를 사용하면 'ㅁ' 과 같이 한글 문자열을 반환할 수 있다.

event.code : 사용자가 누른 키보드 키의 물리적 위치를 나타내는 문자열 값 반환

  • 예: 'KeyA', 'Enter', 'Backspace', 'Digit1'
  • 사용자가 어떤 키보드 레이아웃을 사용하든 동일한 값을 반환한다.

* event.keyCode는 더이상 지원되지 않는 기술이므로 사용하지 않는다.

 

 

콘솔로 직접 찍어보면 더 이해가 잘 간다.
console.log(`e.key : ${e.key} , e.code : ${e.code}`);

728x90

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

[React] 전역 상태의 필요성  (0) 2023.04.21
Styled Components로 ClickToEdit 만들기  (0) 2023.04.20
Styled Components로 Tab 만들기  (0) 2023.04.20
Styled Components로 Toggle 만들기  (0) 2023.04.20
Styled Components로 Modal 만들기  (0) 2023.04.20
⬆︎