File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
08-14
08-18
08-14
08-14
08-18
08-19
08-19
// FoxTooltip — 시안: 통합관리자페이지 디자인시스템 Figma tooltip
//
// 어두운 판에 짧은 글 한 줄을 담은 말풍선이다. `fox-tooltip-rich`의 작은 형제로, 제목이 없고
// 꼬리가 언제나 가운데이며 판이 글자만큼만 넓어진다.
//
// 마크업 계약 (React 밖 소비자용):
// <div class="fox-tooltip fox-tooltip--top">
// <div class="fox-tooltip__arrow-area"> <!-- top이면 판 위, bottom이면 아래 -->
// <span class="fox-tooltip__arrow">…꼬리 svg…</span>
// </div>
// <div class="fox-tooltip__content">글자</div>
// </div>
//
// `--top`은 꼬리가 판 **위**에 붙고(트리거 아래에 뜨는 말풍선), `--bottom`은 아래에 붙는다.
// 마크업 순서가 그것을 정한다 — `order`나 `column-reverse`를 쓰지 않는다.
//
// 꼬리의 가로 위치를 고르는 수식어가 없다 — 시안이 언제나 가운데에 둔다. 그래서 이 파일은
// `_bubble.scss`의 `arrow()` 믹스인을 쓰지 않는다. 저쪽은 **테두리가 있는 판**의 이음새를
// 지우려고 회전 정사각형을 반쯤 걸치는 방식인데, 이 판은 테두리 없이 한 색이라 그럴 일이 없고
// 시안의 꼬리도 12×6에 끝이 둥근 다른 그림이다.
//
// 판은 `inline-flex`라 글자만큼만 넓어진다. 다만 꼬리 영역이 좌우 24px 여백을 달고 있어
// **가장 좁을 때가 60px**(12 + 48)이다 — 글자가 그보다 짧으면 판보다 꼬리 영역이 넓어져
// 말풍선 전체 폭을 그 값이 정한다(시안이 그렇게 준다).
//
// 토큰이 아닌 값:
// - ⚠️ 꼬리 12×6px: 시안이 준 그림의 크기이고 토큰 스케일에 없다.
// - line-height / letter-spacing: 시안 텍스트 스타일 body/sm의 값이나 Figma가 변수로
// export하지 않는다. -0.325px은 13px 기준이라 `-0.025em`으로 적는다(다른 컴포넌트와 같은
// 근거).
// - display / flex: 구조 규칙.
@use "@fox/styles/abstracts" as fox;
.fox-tooltip {
box-sizing: border-box;
display: inline-flex;
flex-direction: column;
align-items: center;
// 글자만큼 넓어진다. `inline-flex`만으로는 부족하다 — 툴팁은 대개 트리거 옆에
// `position: absolute`로 떠 있고, 그때 폭은 **기준이 되는 조상의 폭**을 한도로 계산된다.
// 트리거가 24px짜리면 툴팁도 그 안에 맞추려 글자를 쪼갠다. `max-content`는 그 한도를 벗어나
// 내용 그대로의 폭을 갖게 한다.
//
// ⚠️ 글이 길면 그만큼 한 줄로 길어진다. 줄바꿈이 필요한 자리는 호출부가 `className`으로
// `max-inline-size`를 준다 — 애초에 긴 글은 `fox-tooltip-rich`가 맡는다.
inline-size: max-content;
&__content {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
padding: fox.padding(2) fox.padding(5);
border-radius: fox.radius(2);
background: fox.color(surface-neutral-default-inverse);
color: fox.color(font-neutral-strong-inverse);
text-align: center;
font-family: fox.font-family(body);
font-size: fox.font-size(body-sm);
font-weight: fox.font-weight(regular);
line-height: 1.5;
letter-spacing: -0.025em;
}
&__arrow-area {
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
padding-inline: fox.padding(8);
}
// 꼬리 색은 판과 같은 값이다 — 꼬리는 판이 뾰족하게 튀어나온 부분이다. SVG가
// `fill="currentColor"`라 이 색을 그대로 입는다.
&__arrow {
display: block;
inline-size: 1.2rem;
block-size: 0.6rem;
color: fox.color(surface-neutral-default-inverse);
}
&__arrow > svg {
display: block;
inline-size: 100%;
block-size: 100%;
}
// 꼬리가 판 위에 붙으면 뾰족한 끝이 위를 향해야 한다. 시안 그림은 아래를 향하고 있어
// 뒤집는다 — 같은 그림 하나로 두 방향을 만든다.
&--top &__arrow > svg {
transform: rotate(180deg);
}
// 꼬리를 판 쪽으로 0.5px 겹친다.
//
// ⚠️ 시안에 없는 값이다. 딱 붙여만 두면 소수 배율 화면(윈도우 125% 등)에서 두 요소의 경계가
// 물리 픽셀 중간에 떨어져 **그 사이로 밝은 실선이 비친다.** 판과 꼬리가 같은 색이라 겹쳐도
// 보이는 모양은 그대로이고, 0.5px이면 꼬리 높이(6px)가 눈에 띄게 줄지도 않는다.
// (테두리가 있는 `fox-popover`·`fox-tooltip-rich`는 같은 문제를 다른 방식으로 푼다 —
// `_bubble.scss` 상단 참고.)
&--top &__arrow-area {
margin-block-end: -0.05rem;
}
&--bottom &__arrow-area {
margin-block-start: -0.05rem;
}
}