Tooltip
진행 중 (Tooltip — work in progress)
- 툴팁의 종류는 2가지다 — 한 줄(기본,
nowrap검은 알약)과 멀티라인 상세 도움말(title에 줄바꿈이 있으면 자동). 아래 placement는 어디에 뜨는가를 정하는 별개의 축이고, 어떤 종류인가는 오직 라벨에 줄바꿈이 있느냐로 갈린다. - 멀티라인은 대상 제한이 없다 — 버튼·표 셀·배지·구간 제목 등 아무 요소에나 여러 줄
title만 주면 뜬다(data-ds-tip불필요). 한 줄 툴팁만 아래 셀렉터 목록에 걸린 대상으로 제한된다. - 싱글톤 hover 툴팁.
setupTooltip()을 앱 시작 시 한 번 호출하면, body-level 단일 요소(.ds-tooltip)가 이벤트 위임으로 모든(동적 포함) 대상의 hover를 처리. - 4가지 placement: right(접힌 LNB 메뉴) · top(아이콘 버튼·잘린 라벨·멀티라인 기본값) · compact(
<select>/ms-dropdown현재 선택값) · compact-center(?도움말 배지 등 작은 트리거 — 가운데 정렬). - top·compact·compact-center는 상단 공간 부족 시 아래로 flip(collision flip) — 대상 아래에 뜨고 화살표가 위를 가리킴. compact=PR #247, top=
design/adjust-table(짧은 임베드 iframe 상단의 아이콘 버튼 등에서 잘리던 문제 해결). - 가로도 보정한다(2026-07-27) — 화면 좌·우 끝에서는 버블을 안으로 되돌리고 화살표만 대상 위에 남긴다.
- 색 톤은 2가지(2026-07-27) — 기본 어두운 알약과 밝은 버블(
data-ds-tip-tone="light"). 톤은 종류(한 줄/멀티라인)·placement와 직교하는 축이며, 세 번째 종류가 아니다. → 색 톤 - ✅ 색은 토큰화 완료(
--color-neutral-900/--ds-bw-white, 시각 변화 0). 그림자만 하드코딩 유지(매칭 토큰 없어 결정상 보류) — 검토 필요 사항 참고.
규칙 (강제) · 코딩 에이전트용 — 사람은 접힌 채로 두어도 됩니다
싱글톤 hover 툴팁의 강제 규칙. 상세·placement·토큰은 아래 본문.
- 종류는 2가지뿐이다 — 한 줄(기본) · 멀티라인 상세 도움말. 판정 기준은 라벨의 줄바꿈 하나이며
tooltip.ts가 자동으로 한다. 세 번째 종류를 만들지 말 것(새 클래스·새 버블 스타일 금지). 아래 색 톤은 종류가 아니라 직교 축이다 — 톤을 늘리는 것도 금지(값은light하나). - 색 톤은 2가지, 켜는 법은
data-ds-tip-tone="light"하나다 — 기본은 어두운 알약이고, 대상 또는 그 조상에 이 속성이 있으면 밝은 버블(.ds-tooltip--light)로 바뀐다(밝은 배경 +--color-label-alternative글자 + 1px 라인). 어떤 종류·어떤 placement와도 조합된다..ds-tooltip--light를 마크업에 직접 붙이지 말 것(싱글톤 요소는tooltip.ts가 매 표시마다 다시 판정한다). 밝은 톤이 필요하다고 툴팁을 손으로 만들지 말 것. - 멀티라인은 어디에나 쓸 수 있다 —
title에 줄바꿈(\n)만 있으면 버튼·표 셀·배지·구간 제목 등 셀렉터에 없는 요소도 자동 대상이 된다.data-ds-tip은 placement를 바꿀 때만 쓴다(기본top). 줄바꿈이 곧 opt-in이다. - 한 줄 툴팁은 반대다 — 아래 자동 셀렉터에 걸리거나
data-ds-tip으로 opt-in한 대상에서만 뜬다. 한 줄title을 아무 요소에나 달아도 DS 툴팁이 되지는 않는다(브라우저 기본 툴팁 그대로). setupTooltip()을 앱 시작 시 한 번 호출. body에 싱글톤.ds-tooltip1개가 이벤트 위임으로 모든(동적 포함) 대상의 hover를 처리 — 툴팁 요소를 직접 만들지 말 것(재호출은 no-op).- 4 placement:
right(접힌 LNB 메뉴) ·top(.icon-btn·.ds-btn--icon·표 액션·잘린 라벨·[data-ds-tip='top'], 대상 위·아래 화살표) ·compact(select/.ms-dropdown__trigger현재 선택값, 좌측정렬·화살표 없음) ·compact-center([data-ds-tip='compact-center']전용 — compact 버블을 트리거 중앙 정렬 + 아래 화살표). top·compact·compact-center 모두 상단 공간 부족 시 아래로 flip. - 자동 대상:
.icon-btn·.ds-btn--icon·select·.ms-dropdown__trigger등 위 셀렉터는 마크업 변경 없이 자동. opt-in은data-ds-tip="top|compact|compact-center"+title. - title 보존: hover 시 네이티브
title을aria-label/data-tip-title로 이관(브라우저 기본 툴팁 방지) → leave 시 복원. 별도 처리 불필요. - 잘린 라벨 대상(
.role-card__pill등)은 실제 말줄임 됐을 때만(scrollWidth > clientWidth) 표시. - 멀티라인 상세 도움말:
title에 줄바꿈(\n)이 포함되면tooltip.ts가.ds-tooltip--multiline을 자동 부여 —pre-line+max-width: min(320px, 100vw-32px)+ 좌측 정렬. 클래스를 수동으로 붙이지 말 것(자동 판정이 정본). - 가로 위치는 자동 보정된다: 중앙 정렬 버블(
top·compact-center)이 화면 밖으로 나가면 뷰포트 안으로 되돌리고 화살표만 대상 쪽에 남긴다(clampTooltipX+--ds-tip-arrow-x). 화면 가장자리 버튼이라고 멀티라인을 피할 필요 없다 — 다만--ds-tip-arrow-x를 CSS에서 임의로 덮어쓰지 말 것. - 색은
--ds-tip-bg/--ds-tip-fg두 변수로만 읽는다 — 버블 배경과 4개 placement의 화살표가 같은 변수를 본다. 톤을 손보려면 이 변수만 덮을 것이고, placement 규칙에 색을 다시 적지 말 것(화살표 3곳이 조용히 어긋난다). .ds-tooltip의width: max-content를 지우지 말 것:width:auto로 되돌리면 fixed 요소의 shrink-to-fit이 자기left기준 잔여 공간으로 계산돼, 오른쪽 끝 버블이 스스로 좁아지며 세로로 길어진다(2026-07-27 재현·수정).- 색은 토큰(
--color-neutral-900/--ds-bw-white), 그림자만 하드코딩 유지(매칭 토큰 없음 — 결정). 툴팁 룩은.ds-tooltip= DS 소유(마크업 변경 불필요). - 자매 유틸
positionFloatingMenu(trigger, menu)— ms-dropdown 등 떠 있는 메뉴를 모달 안에서 아래 공간 부족 시 위로 flip(툴팁 아님).
라이브 미리보기
아래는 실제
.ds-tooltip을 body에 띄우는 라이브 데모입니다 (tooltip.ts와 동일한 위치 계산·flip). 각 대상에 마우스를 올려 placement를 확인하고, 체크박스로 아래로-flip을 강제해 보세요.2번째·3번째 줄은 흉내가 아니라 진짜입니다 — docs 사이트가 앱과 똑같이 한 번 호출해 둔 실제
setupTooltip()이 처리하므로, 여기서 보이는.ds-tooltip--multiline전환은 프로덕션 경로 그대로입니다.
- 2번째 줄 —
data-ds-tip으로 placement를 지정한 경우(ⓘ=top,?=compact-center). 「한 줄 비교」는 같은 opt-in에 한 줄title만 준 것으로 기본nowrap버블이 뜹니다.- 3번째 줄 — opt-in이 하나도 없는 평범한 버튼·셀입니다. 여러 줄
title만으로 상세 도움말이 뜨는 확장된 범위를 그대로 보여 줍니다. 맨 오른쪽 「가장자리」는 화면 끝에 붙여 둔 것으로, 버블이 안으로 밀리고 화살표만 대상에 남는 가로 보정을 확인할 수 있습니다(창을 좁히면 더 뚜렷합니다).- 4번째 줄(흰 바닥) — 밝은 톤입니다. 줄 전체에
data-ds-tip-tone="light"를 한 번 걸어 둔 것으로, 안의 세 대상이 종류(한 줄·멀티라인)와 placement가 서로 다른데도 톤만 함께 바뀝니다.
마지막 표시: —— 각 대상에 마우스를 올려 보세요 (툴팁은 실제 .ds-tooltip). 아래 줄은 실제 setupTooltip()이 처리하므로 이 표시기가 갱신되지 않습니다
⚠️ docs 환경 차이: 툴팁은
position: fixedbody-level 요소라 위 영역 밖(뷰포트 기준)에 뜰 수 있습니다 — 실제 앱과 동일한 동작이며, 데모 카드 안에 가두려면positionoverride(강제)가 필요해 일부러 하지 않았습니다.
단일 출처
| 파트 | 파일 |
|---|---|
| 유틸 | packages/components/src/tooltip.ts (setupTooltip) |
| 자매 유틸 | packages/components/src/positionFloatingMenu.ts (ms-dropdown 메뉴 flip) |
| 스타일 | packages/static/styles/design-system.css (.ds-tooltip[data-placement]) |
토큰 소유권: 툴팁 룩(색·shadow·arrow·placement transform)은
.ds-tooltip클래스 = DS 소유. 색은 토큰화 완료(--color-neutral-900/--ds-bw-white), 그림자는 하드코딩 유지(매칭 토큰 없음). 마크업·위치 계산은 JS(tooltip.ts)가 담당(컴포넌트 마크업 변경 불필요).
동작 원리
- 싱글톤:
setupTooltip()최초 호출 시installed플래그 설정 → 재호출 no-op. body에.ds-tooltip1개만 생성. - 이벤트 위임:
document에pointerover(capture)·pointerleave·click리스너. 동적으로 추가된 노드도 자동 커버. - 위치: 대상의
getBoundingClientRect()기준position: fixed로 배치 → 어떤 overflow도 뚫고 표시(z-index 최대). - title 보존: hover 시 네이티브
title을 제거(브라우저 기본 툴팁 방지)하고data-tip-title/aria-label로 옮김 → leave 시 복원. - 대상 판정 순서: 접힌 LNB →
compact-center→compact→top→ 잘린 라벨 → 멀티라인 fallback([title]·[data-tip-title]중 줄바꿈 있는 것). 명시적으로 opt-in한 placement가 항상 먼저 이기고, 아무것도 안 걸린 요소만 마지막 규칙으로 내려온다. - fallback이
[data-tip-title]까지 보는 이유: 툴팁이 뜨는 동안 대상의title은 제거돼 있다.[title]만 보면 hover 중 재판정에서 대상이 사라져 show → hide → title 복원 → show 로 깜빡인다(구현 시 실제로 밟은 함정). - flip·화살표 초기화: 싱글톤 요소 1개를 재사용하므로
show()마다data-flip과--ds-tip-arrow-x를 먼저 지운 뒤 위치를 다시 계산 → 직전 대상에서 flip·가로보정됐던 잔재(뒤집힌 화살표·어긋난 화살표 위치)가 다음 툴팁으로 새지 않음.
Placement & 대상
| placement | 대상 셀렉터 | 위치 | 비고 |
|---|---|---|---|
| right | .ds-lnb--collapsed .ds-lnb__menu | LNB 우측, 좌측 화살표 | 접힌 사이드바 메뉴 라벨 |
| top | .icon-btn, .ds-btn--icon, .org-tree__action-btn, [data-ds-tip='top'] | 대상 위, 아래 화살표. 상단 부족 시 아래로 flip(data-flip="down", 화살표가 위 가리킴) | 표 액션 아이콘 등 |
| top (truncate) | .role-card__group-label, .role-card__pill, .cell-trunc-tip | 대상 위 | 실제로 말줄임 됐을 때만 (scrollWidth > clientWidth) |
| compact | select, .ms-dropdown__trigger, [data-ds-tip='compact'] | 대상 좌측 정렬·위, 화살표 없음 | 현재 선택된 옵션/라벨 텍스트 자동 표시. 상단 부족 시 아래 flip |
| compact-center | [data-ds-tip='compact-center'] | 대상 가운데 정렬·위, 아래 화살표 | compact와 같은 작은 버블이지만 중앙 정렬 — ? 도움말 배지처럼 좁은 트리거용(좌측 정렬이면 어긋나 보임). 상단 부족 시 아래 flip |
| top (멀티라인 자동) | [title] 중 줄바꿈이 있는 것 — 셀렉터 무관 | top과 동일 | 위 셀렉터에 하나도 안 걸린 요소(버튼·셀·제목…)의 상세 도움말. 다른 규칙이 먼저 매칭되면 그쪽 placement가 이긴다 |
가로 방향 충돌 처리 — 중앙 정렬(
top·compact-center) 버블은 뷰포트를 벗어나면 안쪽으로 밀고(양옆 8px 여백), 화살표만 대상 위에 남긴다(--ds-tip-arrow-x). 계산은 순수 함수clampTooltipX()에 분리돼 있어 단위 테스트로 고정돼 있다. 좌측 정렬compact도 같은 방식으로 되돌린다(clampTooltipLeft()).
멀티라인 상세 도움말 (자동)
title 속성에 줄바꿈(\n)이 포함된 대상은 show() 시점에 .ds-tooltip--multiline이 자동 토글된다 — white-space: pre-line + max-width: 320px + text-align: left. 설정 화면의 ⓘ 도움말 아이콘처럼 여러 줄 설명이 필요한 곳에서 data-ds-tip="top" + 여러 줄 title만 주면 된다(HTML 속성 안의 실제 줄바꿈은 보존된다). 한 줄 라벨로 돌아오면 클래스도 자동 해제되므로 수동 관리 금지.
발동 조건은 하나다 — 평가된 title 문자열에 실제 개행이 있을 것. 셀렉터도 data-ds-tip도 필요 없다(2026-07-27 범위 확장). 버튼, 표 셀, 배지, 구간 제목, <div role="button"> 무엇이든 여러 줄 title만 주면 상세 도움말 버블이 뜬다.
<!-- 이게 전부다. opt-in 속성 없음 -->
<button class="ds-btn ds-btn--line ds-btn--dark ds-btn--sm"
title="이 시트의 반영 대상 열에서 수당·공제 레코드를 만듭니다. 마지막 반영 이후 바뀐 내용이 없으면 버튼이 비활성화돼요.">
급여대장 반영
</button>- placement 기본값은
top(대상 위 가운데). 작은 원형 트리거에서 더 어울리는compact-center가 필요하면 그때만data-ds-tip="compact-center"를 준다. - Alpine 바인딩에서는
\n을 쓴다 —:title="'1줄\n2줄'". 정적 속성 안에서는 실제 줄바꿈 또는 . 주의: 정적 HTML에 을 쓰면 파서가 실제 LF로 바꾸므로, Alpine 표현식(:title="\…`") 안에 넣으면 JS 문자열이 끊겨 SyntaxError가 난다(column-kind-editor.html`의 주석 참고). - 소스에서 여러 줄에 걸친
:title="..."표현식은 개행이 아니다 — 판정은 평가 결과 문자열 기준이다.
현재 멀티라인 툴팁이 뜨는 곳:
| 화면 | 위치 | placement | 내용 |
|---|---|---|---|
| admin — 근무 유형 모달 | apps/admin/src/views/modals/shift-type-form.html (ⓘ) | top | 연차 차감 판정 (요일/듀티 기준 + 예시) |
| admin — 근무 유형 모달 | 〃 (ⓘ) | top | 공휴일에도 근무하는 유형 (보조 스위치) |
| hr-system — 시트 「열 설정」 모달 | apps/hr-system/src/views/tabs/sheets/modals/column-kind-editor.html (? 배지) | compact-center | 열 종류 안내 + 열 ID 참조 (2줄) |
hr-system — 시트 헤더 수식 힌트 ƒ | apps/hr-system/src/views/tabs/sheets/grid.html | top (기본값) | 수식 + 「헤더 더블클릭으로 편집」 — 범위 확장으로 자동 승격(마크업 무수정, 기존엔 브라우저 기본 툴팁) |
| hr-system — 시트 툴바 반영 상태 칩 | 〃 (「반영 필요」/「반영됨」 칩, 문구는 commit-compute.ts의 commitStatusTooltip) | top | 1줄=지금 상태, 2줄=다시 반영하는 경로(누를 버튼 + 막혔을 때 먼저 풀 것) |
| hr-system — 급여대장 「소스 전체 반영」 버튼 | 〃 (문구는 commit-compute.ts의 ledgerCommitTooltip) | top | 1줄=값이 소스 시트에서 온다(대장엔 반영 버튼이 없다), 2줄=미반영 소스 N개 + 이 버튼이 하는 일 |
| hr-system — 시트 사이드바 「작업 중」 점 | apps/hr-system/src/views/tabs/sheets/sidebar.html (문구는 commit-compute.ts의 sheetDotTooltip) | top | 1줄=상태 이름(작업 중), 2줄=점 색이 뜻하는 반영 상태(반영 필요 / 반영 완료), 3줄=마지막 값 수정 시각(「3시간 전 수정」). 반영 개념이 없는 시트는 2줄째를 뺀다 |
색 톤 (어두움 / 밝음)
툴팁에는 축이 셋 있고 서로 독립입니다 — 종류(한 줄 / 멀티라인, 라벨의 줄바꿈으로 자동), placement(어디에 뜨는가), 색 톤(어떤 색인가). 톤은 2026-07-27에 추가된 세 번째 축이고, 종류가 3개가 된 것이 아닙니다.
| 톤 | 켜는 법 | 배경 | 글자 | 테두리 | 쓰는 자리 |
|---|---|---|---|---|---|
| 어두움(기본) | 아무것도 안 함 | --color-neutral-900 | --ds-bw-white | 없음 | 대부분의 화면 — 강한 대비로 확실히 읽힘 |
| 밝음 | data-ds-tip-tone="light" | --color-bg-normal | --color-label-alternative | 1px --color-line-normal | 밝은 패널·카드 위에서 검은 알약이 과하게 튀는 자리 |
<!-- 트리거 하나만 밝게 -->
<button class="icon-btn" data-ds-tip-tone="light" title="삭제">…</button>
<!-- 패널 단위로 한 번에 (안쪽 트리거는 마크업 무수정) -->
<div class="ds-modal__body" data-ds-tip-tone="light">…</div>- 조상까지 봅니다 —
tooltip.ts가closest('[data-ds-tip-tone="light"]')로 판정하므로, 화면·패널 루트에 한 번만 걸면 그 안의 모든 툴팁이 밝은 톤이 됩니다. 밝은 톤은 보통 트리거 하나가 아니라 표면 단위 결정이라 이렇게 뒀습니다. - 값은
light하나뿐입니다. 기본이 어두움이므로dark같은 값을 만들 필요가 없고, 톤을 늘리는 것은 금지입니다(종류 3개 금지와 같은 이유 — 버블 스타일이 갈라지기 시작하면 되돌리기 어렵습니다). .ds-tooltip--light를 손으로 붙이지 마세요. 버블은 body에 하나뿐인 싱글톤이라, 클래스는show()가 표시할 때마다 다시 켜고 끕니다(직전 대상의 톤이 다음 툴팁으로 새지 않게).
구현 메모 — 색은 변수 2개로 뒤집습니다. .ds-tooltip이 --ds-tip-bg/--ds-tip-fg를 선언하고 버블 배경과 4개 placement의 화살표(::before)가 모두 같은 변수를 읽습니다. 그래서 톤 모디파이어는 변수 2개만 덮으면 되고, placement별로 색을 다시 적을 필요가 없습니다(예전처럼 화살표마다 색을 하드코딩하면 톤 추가 때 3곳을 빠뜨리기 쉽습니다).
밝은 톤에만 테두리가 있는 이유는 흰 버블이 흰 배경 위에서 경계를 잃기 때문입니다. 화살표도 함께 테두리를 받는데, 45° 회전한 사각형이라 바깥을 향하는 두 변이 placement마다 다릅니다(아래 방향 = bottom+right, 위 방향 = top+left, 왼쪽 방향 = left+bottom). 화살표 안쪽 절반은 버블 테두리 위에 겹쳐 그려지므로, 두 선이 정확히 이어지도록 화살표를 1px 더 바깥으로 밀어 둡니다.
compact 라벨 계산 (title 불필요)
<select>→ 현재 선택된option.text.ms-dropdown__trigger→ 다중 선택 시 체크된 항목 라벨 콤마 join, 0/1개면.ms-dropdown__label텍스트
호출 패턴
import { setupTooltip } from "@hereby/components";
// 앱 시작 시 한 번 (Alpine.start() 이후도 OK — 이벤트 위임이라 동적 노드 커버)
setupTooltip();→ 이후 마크업 변경 없이, 위 셀렉터에 맞는 요소는 자동으로 툴팁이 붙음. opt-in이 필요하면 data-ds-tip="compact"(또는 "top") + title 부여.
사용된 토큰 (현재)
| 카테고리 | 값 | 상태 |
|---|---|---|
| 배경/글자 (어두운 톤) | --ds-tip-bg = var(--color-neutral-900) / --ds-tip-fg = var(--ds-bw-white) | ✅ 토큰화 완료 (값 동일, 시각 변화 0) |
| 배경/글자 (밝은 톤) | --ds-tip-bg = var(--color-bg-normal) / --ds-tip-fg = var(--color-label-alternative) | ✅ 토큰만 사용 |
| 테두리 (밝은 톤만) | 1px solid var(--color-line-normal) | ✅ 토큰만 사용 |
| 그림자 (기본) | 0 4px 12px rgba(0,0,0,0.25) | ⬜ 하드코딩 유지 (결정 — 매칭 토큰 없음) |
| 그림자 (compact) | dual rgba(7,7,7,0.06) | ⬜ 하드코딩 유지 (결정) |
| 그림자 (밝은 톤) | var(--ds-shadow-md) | ✅ 토큰 사용 (25% 검정은 밝은 버블 아래에서 탁함) |
| font-size | top 12px · compact 11px | 🟡 11px는 토큰(b6=12px)보다 작음 |
| radius | top 6px · compact 4px | --ds-radius-* 매핑 검토 |
| transition | 120ms | 🟡 motion scale 부족 |
검토 필요 사항
- ✅ 색 토큰화 완료 — 배경/글자/화살표
#1b1b1b/#ffffff→var(--color-neutral-900)/var(--ds-bw-white)(값 동일, 시각 변화 0). 전 앱(admin·management-dashboard·team-manager) 일괄 적용. - ⬜ 그림자는 하드코딩 유지 (결정) — 기본
0 4px 12px rgba(0,0,0,0.25)는--ds-shadow-xs~xl어디와도 안 맞음. 새 토큰 가치가 생기면 그때 토큰화. - 🟡 compact 11px / dual shadow — Figma
tooltip-compact(10702:11728) 전용 값. 마이크로 토큰 정책 결정 후 매핑. - 🟡 transition 120ms —
--duration-*motion scale 부족. - ✅ collision flip — top·compact 상단 부족 시
data-flip="down"으로 아래 표시(화살표는 위를 가리킴). compact=PR #247, top=design/adjust-table에서 추가(싱글톤 flip 잔재 누수 수정 포함). - ✅ 밝은 톤 추가 완료(2026-07-27) —
data-ds-tip-tone="light". 색은 전부 토큰(--color-bg-normal/--color-label-alternative/--color-line-normal)이고 그림자도--ds-shadow-md를 씁니다. 어두운 톤의 그림자 2종은 그대로 하드코딩입니다(위 결정 유지). - 🟡 밝은 톤을 어느 화면에 적용할지는 미정 — 컴포넌트는 준비됐지만 실제 사용처는 아직 없습니다(현재 전 화면이 기본 어두운 톤). 「밝은 패널 위에서 검은 알약이 과하다」고 판단된 화면부터
data-ds-tip-tone="light"를 겁니다. - ✅ 가로 방향 충돌 처리 완료 — 멀티라인을 아무 요소에나 쓸 수 있게 되면서(2026-07-27) 화면 가장자리 트리거가 현실이 됐고,
clampTooltipX()/clampTooltipLeft()+--ds-tip-arrow-x로 버블을 안으로 되돌리고 화살표만 대상에 남기도록 넣었다. 같은 작업에서width: max-content누락으로 오른쪽 끝 버블이 스스로 좁아지던 문제도 함께 고쳤다.
사용처
- admin — 표 액션 아이콘(
.icon-btn), 조직 트리 액션, 접힌 LNB 메뉴, 모든<select>/ms-dropdown - team-manager 등 공유 앱 — 동일 (
setupTooltip()한 번 호출로 전역 적용) setupTooltip()호출 앱 — admin · team-manager · hr-system · general-affairs · management-dashboard · landing- 멀티라인(개행 title) — admin 근무 유형 모달 ⓘ 2개 · hr-system 시트 「열 설정」
?배지 · hr-system 시트 수식 힌트ƒ(멀티라인 상세 도움말 표). 범위 확장 이후로는 여러 줄title을 새로 다는 곳이 곧 사용처라 이 목록은 스냅샷이다
자매: positionFloatingMenu
positionFloatingMenu(trigger, menu) — 툴팁과 별개로, ms-dropdown 등 떠 있는 메뉴를 트리거 아래에 배치하되 모달(.ds-modal/.ds-mini-modal) 안에서 아래 공간 부족 시 위로 flip. 툴팁의 compact flip과 같은 "충돌 회피" 계열 유틸 (PR #247).
목표 & 로드맵
| 항목 | 현재 | 목표 |
|---|---|---|
| 싱글톤 + 이벤트 위임 | ✅ | 유지 |
| 종류 2가지 (한 줄 / 멀티라인) | ✅ 라벨의 줄바꿈으로 자동 판정 | 유지 — 세 번째 종류 추가 금지 |
| 색 톤 2가지 (어두움 / 밝음) | ✅ data-ds-tip-tone="light" (직교 축) | 유지 — 톤 값 추가 금지 |
| 멀티라인 적용 범위 | ✅ 대상 제한 없음 (줄바꿈 = opt-in) | 유지 |
| 4 placement (right/top/compact/compact-center) | ✅ | 유지 |
| 세로 collision flip | ✅ data-flip (top·compact·compact-center) | 유지 |
| 가로 clamp | ✅ clampTooltipX + --ds-tip-arrow-x | 유지 |
| title→aria 이관 (a11y) | ✅ | 유지 |
| 색 토큰화 | ✅ 완료 (neutral-900 / bw-white) | 유지 |
| 그림자 토큰화 | ⬜ 하드코딩 유지(결정) | 매칭 토큰 생기면 전환 |
| compact 마이크로 토큰 | 🟡 11px/dual shadow | 토큰 정책 결정 후 매핑 |
변경 이력
| 날짜 | 내용 |
|---|---|
| 2026-07-27 | 밝은 톤(light) 추가 — 색 톤이 종류·placement와 별개인 세 번째 축이 됐다. data-ds-tip-tone="light"를 대상 또는 그 조상에 걸면 밝은 배경 + --color-label-alternative 글자 + --color-line-normal 1px 라인 버블로 바뀐다(.ds-tooltip--light, tooltip.ts가 매 표시마다 판정). 구현은 .ds-tooltip에 --ds-tip-bg/--ds-tip-fg 두 변수를 두고 버블과 4개 placement의 화살표가 같은 변수를 읽게 바꾼 것이라, 톤 모디파이어가 placement별 색을 재선언하지 않는다(어두운 톤 값은 그대로 — 시각 변화 0). 밝은 버블은 흰 배경 위에서 경계를 잃으므로 테두리를 두르고, 화살표도 바깥을 향하는 두 변에만 같은 라인을 그린 뒤 1px 바깥으로 밀어 버블 테두리와 잇는다. 그림자는 25% 검정 대신 --ds-shadow-md. 미리보기에 4번째 줄(밝은 톤) 추가 |
| 2026-07-27 | 멀티라인 툴팁의 적용 범위 확장 — 툴팁 종류를 「한 줄 / 멀티라인」 2가지로 정리. 이제 title에 줄바꿈만 있으면 셀렉터·data-ds-tip 없이도 버튼·표 셀·배지·구간 제목 등 아무 요소에서 상세 도움말이 뜬다(기본 placement top). 확장에 따라 화면 가장자리 트리거가 현실이 되므로 가로 방향 보정을 함께 넣었다 — clampTooltipX()/clampTooltipLeft()(순수 함수, 단위 테스트 12개) + --ds-tip-arrow-x로 버블은 뷰포트 안으로, 화살표는 대상 위에 남긴다. 이 과정에서 오른쪽 끝 버블이 스스로 좁아지며 세로로 길어지던 버그를 재현·수정(width: max-content — fixed 요소의 shrink-to-fit이 자기 left 기준 잔여 공간으로 계산되던 문제). hr-system 시트 수식 힌트 ƒ는 마크업 수정 없이 자동 승격 |
| 2026-07-27 | 라이브 미리보기에 멀티라인 stage 추가 — Vue 재구현이 아니라 data-ds-tip + 여러 줄 title 마크업만 두고 docs가 이미 호출해 둔 실제 setupTooltip() 이 처리(top·multiline / compact-center·multiline / 한 줄 비교 3종). 데모 쪽 show()도 .ds-tooltip--multiline 자동 토글과 top의 아래로-flip을 반영해 실제 코드와 맞춤. 가로 방향 충돌 처리가 없다는 한계는 검토 필요 사항에 기록 |
| 2026-07-27 | 문서 정정 — placement는 3개가 아니라 4개(compact-center 누락분 추가: 셀렉터·중앙 정렬·아래 화살표·flip), top 자동 대상에 .ds-btn--icon 추가. 멀티라인 툴팁 사용처를 코드에서 전수 확인해 표로 기록(admin 근무 유형 모달 ⓘ 2 · hr-system 열 설정 ? 1). 발동 조건이 「개행 title」 하나가 아니라 「툴팁 대상 + 개행」 두 가지임을 명시 — hr-system 시트 수식 ƒ 힌트는 개행 title이지만 data-ds-tip이 없어 브라우저 기본 툴팁으로 뜬다(미전환 1건으로 기록). ⚠️ 이 두 가지 조건 서술은 같은 날 범위 확장으로 폐기됐다 — 지금은 개행 하나로 충분하고, ƒ 힌트도 DS 툴팁으로 승격됐다(윗줄 참고) |
| 2026-07-07 | top placement도 상단 잘림 시 아래로 flip 추가 — data-flip="down" + .ds-tooltip[data-placement="top"][data-flip="down"] CSS(화살표가 위 가리킴, 위쪽 tip 코너만 라운드). 짧은 임베드 iframe(admin 안 team-manager/hr-system) 상단의 아이콘 버튼에서 툴팁이 프레임 위로 잘리던 문제 해결. 싱글톤 재사용 요소라 show()가 매번 data-flip 선제거 → 직전 flip 잔재 누수도 수정 (design/adjust-table) |
| 2026-06-08 | .ds-tooltip 색 토큰화(배경·글자·화살표 → --color-neutral-900/--ds-bw-white, 시각 변화 0). 그림자는 하드코딩 유지(결정). 전 앱 일괄 적용 |
| 2026-06-08 | Tooltip 페이지 신규 작성 + 라이브 미리보기(<DemoTooltip>) (PR #247 기준) |
| PR #247 | setupTooltip 공유 싱글톤 + compact <select>/ms-dropdown 자동 툴팁 + 상단 잘림 시 아래로 flip |