Files
Aislo/M01_MasterData/M01_MasterData_UI_LogicLab_Pill.ts
T

45 lines
1.6 KiB
TypeScript

/* =============================================================================
* M01_MasterData_UI_LogicLab_Pill.ts
* 줄 모달의 알약 단추 — 쓰인 자료를 알약으로만 늘어놓고, 누른 것 하나만 펼침(다시 누르면 접힘)
* ========================================================================== */
import { el } from "@ui/ui_template_elements";
export interface Pill {
/** 알약 글 — 보기 「표 QF000421」 · 「인력 석공」 */
label: string;
/** 펼칠 때 그림 — 표처럼 읽어 와야 하면 Promise */
view: () => HTMLElement | Promise<HTMLElement>;
}
export function pillBar(pills: Pill[]): HTMLElement {
const stage = el("div", { className: "m01lab__pill-stage" });
const buttons: HTMLButtonElement[] = [];
let open = -1;
let turn = 0;
const show = async (i: number): Promise<void> => {
const mine = ++turn;
open = open === i ? -1 : i;
buttons.forEach((b, k) => {
b.setAttribute("aria-expanded", String(k === open));
b.classList.toggle("is-open", k === open);
});
if (open < 0) return stage.replaceChildren();
const view = await pills[open].view();
if (mine === turn) stage.replaceChildren(view); // 빨리 눌러도 마지막 것만
};
pills.forEach((p, i) => {
const b = el("button", {
className: "m01lab__pill",
text: p.label,
attrs: { type: "button", "aria-expanded": "false", "data-pill": p.label },
});
b.addEventListener("click", () => void show(i));
buttons.push(b);
});
return el("div", {
className: "m01lab__pills",
children: [el("div", { className: "m01lab__pill-row", children: buttons }), stage],
});
}