/* ============================================================================= * ui_template_tabs.ts * 부품 「탭」(552-2 · 부품 모음 `#/b01-account?view=ui-kit`) * * 꼴 = 밑줄 탭(line · 한 꼴 · 대시보드 `tabBar` 꼴) · 보조 탭(pill · 작은 알약 · `.ui-subtabs`) · 탭 오른쪽 수 배지(0 = 숨김) * 문서 탭(`cad-tabs` · `ss-tabs`)은 꼴 그대로 · 토큰만(553) * 크기 = data-size 24 · 32 · 36(밑줄 기본 36 · 보조 기본 24) * 상태 = 마우스 `:hover` · 막힘 `disabled` · 고름 = aria-selected + `.is-active` — CSS 는 `[data-state]` 로도 받음 * 쓰기 = `const tabs = createTabs({ tabs: [{ key: "a", label: "개요" }], value: "a", onChange }); tabs.setBadge("a", 3)` * 대신 = B01 `.b01-pg-tabs` · 공용 `.ui-subtabs` · B08 `.b08-quantity__tabs` · B09 `.b09-estimation__tabs` · `app-settings__tabs` · * M02 `m02-sod__tabs` · 시트 `.ss-fmtdlg__tabs` * 클래스 = 보조 탭 = `ui-subtabs` + 칸 `ui-btn ui-btn--pill`(옛 이름 · 시험이 잡음) * ========================================================================== */ import { createButton, setUiSize, type UiSize } from "./ui_template_button"; import "./ui_template_tabs.css"; export interface TabItem { key: string; label: string; disabled?: boolean; } export interface TabsHandle { root: HTMLDivElement; /** 고름을 바꿈(onChange 는 안 부름) */ select: (key: string) => void; /** 탭 오른쪽 수 — 0 이하면 숨김 */ setBadge: (key: string, count: number) => void; } export function createTabs(opts: { tabs: TabItem[]; value: string; onChange?: (key: string) => void; kind?: "line" | "pill"; /** 24 · 32 · 36 권함 */ size?: UiSize; }): TabsHandle { const pill = opts.kind === "pill"; const root = document.createElement("div"); root.className = pill ? "ui-tabs ui-tabs--pill ui-subtabs" : "ui-tabs"; root.setAttribute("role", "tablist"); setUiSize(root, opts.size ?? (pill ? 24 : 36)); const buttons = new Map(); const badges = new Map(); const select = (key: string): void => { for (const [k, b] of buttons) { b.classList.toggle("is-active", k === key); b.setAttribute("aria-selected", String(k === key)); } }; for (const tab of opts.tabs) { const b = pill ? createButton({ label: tab.label, variant: "pill", size: opts.size ?? 24 }) : document.createElement("button"); if (!pill) { b.type = "button"; b.className = "ui-tabs__tab"; b.append(tab.label); } b.setAttribute("role", "tab"); b.dataset.tab = tab.key; b.disabled = tab.disabled ?? false; const count = document.createElement("span"); count.className = "ui-tabs__count"; count.hidden = true; b.append(count); b.addEventListener("click", () => { select(tab.key); opts.onChange?.(tab.key); }); buttons.set(tab.key, b); badges.set(tab.key, count); root.append(b); } select(opts.value); return { root, select, setBadge: (key, n) => { const c = badges.get(key); if (!c) return; c.textContent = String(n); c.hidden = n <= 0; }, }; }