[UI] Tooltip component 구현 (React, TypeScript, Storybook)

예구·2024년 6월 25일
post-thumbnail

최근에 과제 전형을 진행하면서 UI 컴포넌트를 직접 구현할 기회가 있었다. 이 기회를 통해 다양한 컴포넌트를 만들어 보고, 다른 사람들과 인사이트를 공유하고 싶어 UI 컴포넌트 스터디를 운영하게 되었다.

이번 스터디에서 중요하게 생각한 점은 다음과 같다:

  • 매주 한 개의 UI 컴포넌트를 직접 구현하고 배포하기
  • 전반적인 컴포넌트 개발 능력 향상시키기
  • ReactTypeScript, Storybook 사용 경험 쌓기

첫 번째 주에 구현한 것은 tooltip이었다.
라이브러리를 사용할 때는 쉬워 보였으나, 직접 구현하려니 고려할 사항이 많았다.
tooltip 컴포넌트를 구현한 과정을 정리해 보고자 한다.



Tooltip의 주요 기능

툴팁 컴포넌트로 감싼 요소에 마우스를 오버하면 툴팁이 나타나고, 마우스를 아웃하면 툴팁이 사라져야 한다.



Tooltip 구현 코드

Tooltip 컴포넌트를 구현하는 데 사용한 코드는 세 부분으로 나눌 수 있다:

  • 컴포넌트 파일 (Tooltip.tsx)
  • 스타일 파일 (Tooltip.css)
  • Storybook 파일 (Tooltip.stories.tsx)

Tooltip.tsx

이 파일에서는 Tooltip 컴포넌트의 메인 로직을 정의한다.

// src/components/Tooltip.tsx

import React, { useState } from "react";
import "./Tooltip.css";

export type TooltipProps = {
  content: string;
  children: React.ReactNode;
};

const Tooltip = ({ content, children }: TooltipProps) => {
  const [visible, setVisible] = useState(false);

  const showTooltip = () => setVisible(true);
  const hideTooltip = () => setVisible(false);

  return (
    <div className="tooltip-container" onMouseEnter={showTooltip} onMouseLeave={hideTooltip}>
      {children}
      {visible && <div className="tooltip">{content}</div>}
    </div>
  );
};

export default Tooltip;
  • useState 훅을 사용하여 visible 상태를 정의하고, 이를 통해 툴팁의 표시 여부를 제어한다.
  • TooltipProps 타입을 정의하여 contentchildren을 props로 받는다.
    • content: 툴팁에 표시될 텍스트
    • children: 툴팁을 감쌀 요소
  • showTooltiphideTooltip 함수는 마우스 이벤트에 반응하여 visible 상태를 변경한다.
  • div 요소에 onMouseEnteronMouseLeave 이벤트 핸들러를 설정하여 툴팁의 표시와 숨김을 제어한다.
  • visible 상태에 따라 툴팁(div.tooltip)을 조건부 렌더링한다.

Tooltip.css

이 파일에서는 Tooltip 컴포넌트의 스타일을 정의한다.

/* src/components/Tooltip.css */

.tooltip-container {
  position: relative;
  display: inline-block;
}

.tooltip {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  background-color: #333;
  color: #fff;
  padding: 6px 14px;
  border-radius: 10px;
  white-space: nowrap;
  z-index: 10;
}
  • .tooltip-container 클래스는 툴팁을 감싸는 요소의 스타일을 정의한다.

    • position: relative를 사용하여 툴팁이 이 요소를 기준으로 배치될 수 있게 한다.
  • .tooltip 클래스는 툴팁 자체의 스타일을 정의한다.

    • position: absolute를 사용하여 툴팁이 .tooltip-container 요소를 기준으로 절대 위치에 배치된다.
    • bottom: 100%left: 50%를 통해 툴팁을 부모 요소의 아래쪽 중앙에 배치한다.
    • transform: translateX(-50%)로 툴팁을 가로축에서 중앙 정렬한다.
    • 배경색, 글자색, 패딩, 테두리 반경, z-index를 설정하여 툴팁의 외형을 지정한다.

Tooltip.stories.tsx

이 파일에서는 Storybook을 사용하여 Tooltip 컴포넌트를 문서화하고 시각적으로 테스트할 수 있다.

// src/components/Tooltip.stories.tsx

import { Meta, StoryObj } from "@storybook/react";
import Tooltip from "./Tooltip";

const meta: Meta<typeof Tooltip> = {
  title: "Tooltip",
  component: Tooltip,
  tags: ["autodocs"],
  parameters: {
    layout: "centered",
  },
  args: {
    content: "This is a tooltip",
  },
} satisfies Meta<typeof Tooltip>;

export default meta;
type TooltipStory = StoryObj<typeof meta>;

export const Default: TooltipStory = {
  args: {
    children: <span>Hover over me</span>,
  },
};
  • meta 객체는 Storybook에서 Tooltip 컴포넌트의 메타데이터를 정의한다.

    • title: Storybook 사이드바에서 컴포넌트를 그룹화하거나 분류하는 방법
    • component: 사용할 컴포넌트를 지정
    • tags: 컴포넌트에 대한 문서를 자동으로 생성하는 데 사용
    • parameters: Storybook의 설정을 정의
    • args: 기본적으로 사용할 props를 지정
  • Default 스토리는 기본적인 Tooltip 컴포넌트를 렌더링한다.

    • argschildren을 설정하여 툴팁을 테스트할 수 있게 합니다.

이렇게 구현한 tooltip은 Storybook을 통해 테스트할 수 있고, 시각적으로 확인할 수 있다.

storybook을 통해 구현한 tooltip 확인



추가 구현할 사항

현재 구현한 툴팁은 기본적인 기능만 제공하고 있어 추가로 구현할 사항을 정리해 보았다.


  • tooltip 방향 지원

    • tooltip 방향이 left, right, bottom, top, topLeft, topRight, bottomLeft, bottomRight, leftTop, leftBottom, rightTop, rightBottom으로 뜰 수 있도록 구현
  • 딜레이 설정

    • tooltip이 나타나거나 사라질 때 delay 시간을 custom 할 수 있도록 구현
  • 닫기 버튼

    • 툴팁 안에 '닫기' button을 눌러야만 툴팁 사라지는 것 구현
  • 포커스와 키보드 접근성 지원

    • 키보드 포커스로도 툴팁을 표시할 수 있도록 구현
    • 접근성을 위한 aria 속성 추가
  • 툴팁 크기 및 위치 자동 조절

    • 툴팁이 화면 밖으로 나가지 않도록 위치와 크기를 자동 조절
  • 툴팁 내용 동적 업데이트

    • 툴팁 내용이 동적으로 업데이트될 수 있도록 기능 추가
  • 스타일 커스터마이징

    • 사용자 정의 스타일을 적용할 수 있도록 스타일 속성 추가
  • 클릭 이벤트로 툴팁 표시

    • 마우스 오버 외에 클릭 이벤트로도 툴팁을 표시할 수 있도록 구현
  • 다양한 트리거 방식 지원

    • 호버, 클릭 외에도 포커스, 더블클릭 등의 다양한 트리거 방식 지원

이 모든 기능을 다 구현할지는 모르겠지만, 추가로 기능을 구현하여 툴팁을 고도화할 예정이다.

profile
우당탕탕 FE 성장기

0개의 댓글