feat(M01): 로직 개선 시험 줄 모달 — 한 줄 풀이와 알약 단추(누른 자료 하나만 펼침·접힘) (PLAN 5-3)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PAdA5ThqmtVSsbzjusk1cJ
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
/* =============================================================================
|
||||
* 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],
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user