feat(A00): 페이지 탭 줄 채움 도우미 — 부품 탭을 줄 요소 안에 채움 (PLAN 553-3)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 21:59:50 +09:00
co-authored by Claude Sonnet 5.5
parent 9729892a3d
commit 84f9547f91
+46
View File
@@ -0,0 +1,46 @@
/* =============================================================================
* b_page_tabs.ts
* 페이지 탭 줄 — 부품 「탭」(`ui_template_tabs`)을 이미 있는 줄 요소 안에 채움(553-3 · B08 · B09 · ☰ [설정]).
*
* 쓰기 = `fillTabs(줄, { tabs, value, onChange, kind: "pill", data: "b08Tab" })` — 칸마다 `data-<data>` = 탭 열쇠
* 줄 요소는 페이지가 정함(클래스 · 자리) · 칸 모양 · 크기 · 고름 표시는 부품 몫 · 누른 칸이 지금 칸이면 안 부름
* 탭 이름이 바뀌면 다시 부르면 됨(줄을 통째로 다시 채움)
* ========================================================================== */
import type { UiSize } from "@ui/ui_template_button";
import { createTabs, type TabItem } from "@ui/ui_template_tabs";
export interface PageTabsOptions {
tabs: TabItem[];
value: string;
onChange: (key: string) => void;
/** line = 위 탭(밑줄) · pill = 보조 탭(작은 알약) */
kind?: "line" | "pill";
size?: UiSize;
/** 칸에 붙일 data 이름(camelCase · 예: b08Tab → data-b08-tab) */
data: string;
/** 칸 풍선 */
title?: (key: string) => string | undefined;
}
export function fillTabs(host: HTMLElement, opts: PageTabsOptions): HTMLElement[] {
const tabs = createTabs({
tabs: opts.tabs,
value: opts.value,
kind: opts.kind,
size: opts.size,
onChange: (key) => key !== opts.value && opts.onChange(key),
});
const buttons = [...tabs.root.querySelectorAll<HTMLElement>("[data-tab]")];
for (const button of buttons) {
const key = button.dataset.tab ?? "";
button.dataset[opts.data] = key;
const title = opts.title?.(key);
if (title) button.title = title;
}
host.classList.add(...tabs.root.classList);
host.dataset.size = tabs.root.dataset.size ?? "";
host.setAttribute("role", "tablist");
host.replaceChildren(...tabs.root.childNodes);
return buttons;
}