File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
08-14
08-14
08-18
08-18
08-14
08-19
08-18
08-18
08-18
08-18
File name
Commit message
Commit date
import type { ReactNode, Ref } from "react";
import { cx } from "../../utils";
/** 꼬리가 판의 위에 붙는지 아래에 붙는지. 판이 트리거의 아래/위 어느 쪽에 뜨는지가 따라온다. */
export type FoxTooltipDirection = "top" | "bottom";
export interface FoxTooltipProps {
/**
* `top`이면 꼬리가 판 위에 붙는다 — 트리거 아래에 뜨는 말풍선이다.
* `bottom`이면 꼬리가 판 아래에 붙는다 — 트리거 위에 뜨는 말풍선이다.
*
* 가로 위치를 고르는 값은 없다 — 시안이 꼬리를 언제나 가운데에 둔다(`FoxTooltipRich`와
* 다른 점이다).
*/
direction?: FoxTooltipDirection;
/** 보여 줄 글자. 한 줄짜리 짧은 말이다 — 길어지면 `FoxTooltipRich`를 쓴다. */
message: ReactNode;
/** 참이면 렌더하지 않는다(DOM에 남지 않는다). */
hidden?: boolean;
id?: string;
/** 배치 조정용. 트리거 옆에 놓는 위치를 여기로 준다. */
className?: string;
ref?: Ref<HTMLDivElement>;
}
const DIRECTION_CLASS: Record<FoxTooltipDirection, string> = {
top: "fox-tooltip--top",
bottom: "fox-tooltip--bottom",
};
/**
* @fox 툴팁. 어두운 판에 짧은 글 한 줄을 담은 말풍선이다.
*
* `FoxTooltipRich`의 작은 형제다 — 제목이 없고, 꼬리가 언제나 가운데이며, 판이 글자만큼만
* 넓어진다. 여기도 **누를 것이 하나도 없다**: 잠깐 떴다 사라지는 판 안의 버튼은 누를 수 없다.
*
* **상태를 갖지 않고 스스로 자리를 잡지도 않는다.** 언제 보일지와 트리거 옆 어디에 놓을지는
* 호출부가 정하고, `direction`은 꼬리가 위아래 중 어디에 붙는지만 정한다.
*
* ⚠️ 이 조각은 보조기술에 아무 역할도 주지 않는다. 툴팁으로 읽히려면 트리거가
* `aria-describedby`로 이 요소의 `id`를 가리켜야 한다 — 그 배선은 트리거 쪽이 맡는다.
*
* ⚠️ 스타일은 이 파일이 import하지 않는다 — 호스트 앱이 `@use "@fox/styles/components"`
* (또는 개별 파티셜)로 한 번 불러와야 한다.
*/
export function FoxTooltip({
direction = "top",
message,
hidden = false,
id,
className,
ref,
}: FoxTooltipProps) {
if (hidden) {
return null;
}
const arrowSlot = (
<div className="fox-tooltip__arrow-area" aria-hidden="true">
<span className="fox-tooltip__arrow">
<ArrowMark />
</span>
</div>
);
return (
<div
ref={ref}
id={id}
className={cx("fox-tooltip", DIRECTION_CLASS[direction], className)}
>
{direction === "top" ? arrowSlot : null}
<div className="fox-tooltip__content">{message}</div>
{direction === "bottom" ? arrowSlot : null}
</div>
);
}
/**
* 시안 꼬리. 여기서는 `FoxPopover`·`FoxTooltipRich`처럼 CSS로 그리지 않고 SVG를 쓴다 —
* 저쪽은 테두리가 있어 1px 이음새를 맞춰야 했지만 이 판은 테두리 없이 한 색이라 그럴 일이
* 없고, 시안의 꼬리 **끝이 살짝 둥글어** CSS 삼각형으로는 그 모양이 나오지 않는다.
*
* 색은 리터럴 대신 `currentColor`라 스타일이 판과 같은 값을 준다. 마스크가 없어 문서에서
* id가 겹칠 일도 없다.
*/
function ArrowMark() {
return (
<svg viewBox="0 0 12 6" fill="none" aria-hidden="true">
<path
d="M12 0H0L4.93934 5.50991C5.52513 6.16336 6.47487 6.16336 7.06066 5.50991L12 0Z"
fill="currentColor"
/>
</svg>
);
}