Tooltip

Tooltip

요소가 키보드 포커스를 받거나 마우스를 올리면 해당 요소에 대한 정보를 표시하는 팝업이에요.

출처: 문서

본문

요소에 마우스를 올리거나 포커스할 때 짧은 설명 말풍선을 띄우는 툴팁 컴포넌트예요. 표시 지연을 전역으로 제어하는 Provider를 제공하고, 트리거가 활성화되거나 escape를 누르면 닫혀요. 커스텀 타이밍을 지원해요.

Features

  • 표시 지연을 전역으로 제어하는 Provider.
  • 트리거가 포커스되거나 호버되면 열려요.
  • 트리거가 활성화되거나 escape를 누르면 닫혀요.
  • 커스텀 타이밍 지원.

Anatomy

모든 파트를 임포트해 조립해요.

import { Tooltip } from "radix-ui";

export default () => (
  <Tooltip.Provider>
    <Tooltip.Root>
      <Tooltip.Trigger />

      <Tooltip.Portal>
        <Tooltip.Content>
          <Tooltip.Arrow />
        </Tooltip.Content>
      </Tooltip.Portal>
    </Tooltip.Root>
  </Tooltip.Provider>
);

API Reference

Provider

앱을 감싸 툴팁에 전역 기능을 제공해요.

Prop Type Default
delayDuration number 700
skipDelayDuration number 300
disableHoverableContent boolean No default value

Root

툴팁의 모든 파트를 담아요.

Prop Type Default
defaultOpen boolean No default value
open boolean No default value
onOpenChange function No default value
delayDuration number 700
disableHoverableContent boolean No default value

Trigger

툴팁을 토글하는 버튼이에요. 기본적으로 Tooltip.Content는 트리거에 맞춰 위치하게 돼요.

Prop Type Default
asChild boolean false
Data attribute Values
[data-state] "closed" | "delayed-open" | "instant-open"

Portal

사용하면 content 파트를 body로 포털해요.

Prop Type Default
forceMount boolean No default value
container HTMLElement document.body

Content

툴팁이 열렸을 때 튀어나오는 컴포넌트예요.

Prop Type Default
asChild boolean false
aria-label string No default value
onEscapeKeyDown function No default value
onPointerDownOutside function No default value
forceMount boolean No default value
side enum "top"
sideOffset number 0
align enum "center"
alignOffset number 0
avoidCollisions boolean true
collisionBoundary Boundary []
collisionPadding number | Padding 0
arrowPadding number 0
sticky enum "partial"
hideWhenDetached boolean false
Data attribute Values
[data-state] "closed" | "delayed-open" | "instant-open"
[data-side] "left" | "right" | "bottom" | "top"
[data-align] "start" | "end" | "center"
CSS Variable Description
--radix-tooltip-content-transform-origin The transform-origin computed from the content and arrow positions/offsets
--radix-tooltip-content-available-width The remaining width between the trigger and the boundary edge
--radix-tooltip-content-available-height The remaining height between the trigger and the boundary edge
--radix-tooltip-trigger-width The width of the trigger
--radix-tooltip-trigger-height The height of the trigger

Arrow

툴팁 옆에 렌더링할 수 있는 선택적 화살표 요소예요. 트리거와 Tooltip.Content를 시각적으로 연결해 주는 데 도움을 줘요. Tooltip.Content 안에 렌더링해야 해요.

Prop Type Default
asChild boolean false
width number 10
height number 5

Examples

전역으로 설정

Provider로 delayDuration과 skipDelayDuration을 전역으로 제어해요.

import { Tooltip } from "radix-ui";

export default () => (
  <Tooltip.Provider delayDuration={800} skipDelayDuration={500}>
    <Tooltip.Root>
      <Tooltip.Trigger>…</Tooltip.Trigger>

      <Tooltip.Content>…</Tooltip.Content>
    </Tooltip.Root>

    <Tooltip.Root>
      <Tooltip.Trigger>…</Tooltip.Trigger>

      <Tooltip.Content>…</Tooltip.Content>
    </Tooltip.Root>
  </Tooltip.Provider>
);

즉시 표시

delayDuration prop으로 툴팁이 열리는 데 걸리는 시간을 제어해요.

import { Tooltip } from "radix-ui";

export default () => (
  <Tooltip.Root delayDuration={0}>
    <Tooltip.Trigger>…</Tooltip.Trigger>

    <Tooltip.Content>…</Tooltip.Content>
  </Tooltip.Root>
);

콘텐츠 크기 제한

콘텐츠의 너비를 트리거 너비에 맞추고 싶을 수 있어요. 높이를 뷰포트에 넘지 않게 제한할 수도 있어요.

--radix-tooltip-trigger-width, --radix-tooltip-content-available-height 같은 여러 CSS 커스텀 프로퍼티가 이를 지원해요. 콘텐츠 크기를 제한하는 데 활용하세요.

// index.jsx

import { Tooltip } from "radix-ui";

import "./styles.css";

export default () => (
  <Tooltip.Root>
    <Tooltip.Trigger>…</Tooltip.Trigger>

    <Tooltip.Portal>
      <Tooltip.Content className="TooltipContent" sideOffset={5}>
        …
      </Tooltip.Content>
    </Tooltip.Portal>
  </Tooltip.Root>
);
/* styles.css */

.TooltipContent {
  width: var(--radix-tooltip-trigger-width);

  max-height: var(--radix-tooltip-content-available-height);
}

Origin 인지 애니메이션

--radix-tooltip-content-transform-origin CSS 커스텀 프로퍼티를 노출해요. side, sideOffset, align, alignOffset과 충돌을 기반으로 계산된 origin에서 콘텐츠를 애니메이션하는 데 사용하세요.

// index.jsx

import { Tooltip } from "radix-ui";

import "./styles.css";

export default () => (
  <Tooltip.Root>
    <Tooltip.Trigger>…</Tooltip.Trigger>

    <Tooltip.Content className="TooltipContent">…</Tooltip.Content>
  </Tooltip.Root>
);
/* styles.css */

.TooltipContent {
  transform-origin: var(--radix-tooltip-content-transform-origin);

  animation: scaleIn 0.5s ease-out;
}

@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

Collision 인지 애니메이션

data-side와 data-align 속성을 노출해요. 이 값들은 충돌을 반영해 런타임에 바뀌어요. 충돌과 방향에 인지된 애니메이션을 만드는 데 사용하세요.

// index.jsx

import { Tooltip } from "radix-ui";

import "./styles.css";

export default () => (
  <Tooltip.Root>
    <Tooltip.Trigger>…</Tooltip.Trigger>

    <Tooltip.Content className="TooltipContent">…</Tooltip.Content>
  </Tooltip.Root>
);
/* styles.css */

.TooltipContent {
  animation-duration: 0.6s;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}

.TooltipContent[data-side="top"] {
  animation-name: slideUp;
}

.TooltipContent[data-side="bottom"] {
  animation-name: slideDown;
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

Accessibility

키보드 상호작용

Key Description
Tab Opens/closes the tooltip without delay.
Space If open, closes the tooltip without delay.
Enter If open, closes the tooltip without delay.
Escape If open, closes the tooltip without delay.

Custom APIs

primitive 파트를 자신의 컴포넌트로 추상화해 나만의 API를 만들 수 있어요.

파트를 추상화하고 content prop 도입

이 예제는 Tooltip의 모든 파트를 추상화하고 새 content prop을 도입해요.

사용법

import { Tooltip } from "./your-tooltip";

export default () => (
  <Tooltip content="Tooltip content">
    <button>Tooltip trigger</button>
  </Tooltip>
);

구현

asChild prop으로 트리거 파트를 슬롯 가능한 영역으로 전환해요. 전달된 자식으로 트리거를 대체해요.

// your-tooltip.jsx

import * as React from "react";

import { Tooltip as TooltipPrimitive } from "radix-ui";

export function Tooltip({ children, content, open, defaultOpen, onOpenChange, ...props }) {
  return (
    <TooltipPrimitive.Root open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>
      <TooltipPrimitive.Trigger asChild>{children}</TooltipPrimitive.Trigger>

      <TooltipPrimitive.Content side="top" align="center" {...props}>
        {content}

        <TooltipPrimitive.Arrow width={11} height={5} />
      </TooltipPrimitive.Content>
    </TooltipPrimitive.Root>
  );
}

더 알아보기 (Learn more)

  • Tooltip.Provider로 앱 전체 툴팁의 지연(delayDuration/skipDelayDuration)을 한 번에 제어할 수 있어요.
  • HoverCard와 달리 Tooltip은 키보드 포커스로도 열리며, 트리거 활성화·Escape로 닫혀요.