/* ============================================================================= * B06_Section_UI_Cross_Notice_Chips.ts * 횡단 알림 줄 칩 꼴(196-1) — 항목 = 짧은 이름 + 측점 수 칩 한 줄 · 긴 설명 = 공용 호버. * 줄 아래 내용 칸 하나를 같이 씀 — 누른 칩의 측점 목록만 · 같은 칩 다시 누르면 닫힘 · * 다른 칩 누르면 바뀜(한 번에 하나). 측점 단추 누름 = `onPick`(그 카드로). * ⭐ 207-1 — 내용 칸은 줄 아래 카드 위에 겹쳐 뜸(흐름 밖 · CSS) · 측점 누르면 접힘 · * 열 때 지금 고른 측점(`selected`) 단추 강조. * 무엇을 셀지는 부르는 쪽(`_FillSlope_Notice`) — 여기는 그리기만. * ========================================================================== */ import { attachHoverInfo } from "@ui/ui_template_hover_info"; export interface NoticeChipRow { stationId: string; text: string; } export interface NoticeChipItem { key: string; /** 짧은 이름 — 칩 글 = 이름 + 측점 수 */ label: string; /** 긴 설명 — 호버 */ hint: string; tone: "warn" | "info"; rows: NoticeChipRow[]; } export interface NoticeChips { root: HTMLElement; /** 측점 설계가 바뀔 때마다 — 연 칩은 그대로(측점이 0 이 되면 닫힘) */ update: (items: NoticeChipItem[]) => void; } export function createNoticeChips( onPick: (stationId: string) => void, selected: () => string | null = () => null, ): NoticeChips { const root = document.createElement("div"); root.className = "b06-section__notice-blocks"; const chips = document.createElement("div"); chips.className = "b06-section__notice-chips"; const panel = document.createElement("div"); panel.className = "b06-section__notice-list"; panel.hidden = true; root.append(chips, panel); let items: NoticeChipItem[] = []; let openKey: string | null = null; const render = (): void => { const open = items.find((item) => item.key === openKey); if (!open) openKey = null; chips.replaceChildren( ...items.map((item) => { const chip = document.createElement("button"); chip.type = "button"; chip.className = `b06-section__notice-chip b06-section__notice-chip--${item.tone}`; chip.dataset.noticeKey = item.key; chip.setAttribute("aria-expanded", String(item === open)); chip.textContent = `${item.label} ${item.rows.length}`; return chip; }), ); panel.hidden = !open; panel.classList.toggle("is-info", open?.tone === "info"); const picked = open ? selected() : null; panel.replaceChildren( ...(open?.rows ?? []).map((row) => { const button = document.createElement("button"); button.type = "button"; button.textContent = row.text; button.dataset.stationId = row.stationId; button.classList.toggle("is-selected", row.stationId === picked); return button; }), ); }; chips.addEventListener("click", (event) => { const key = (event.target as HTMLElement).closest(".b06-section__notice-chip") ?.dataset.noticeKey; if (!key) return; openKey = openKey === key ? null : key; render(); }); panel.addEventListener("click", (event) => { const id = (event.target as HTMLElement).closest("button")?.dataset.stationId; if (!id) return; openKey = null; render(); onPick(id); }); attachHoverInfo( chips, (target) => items.find((item) => item.key === target.dataset.noticeKey)?.hint, ".b06-section__notice-chip", ); return { root, update(next) { items = next.filter((item) => item.rows.length); render(); }, }; }