/* ============================================================================= * B08_Quantity_UI_SidePanel_Sections.ts * 좌측 산출조건 패널을 **B03~B07 공통 상자**로 묶는 자리. * * 페이지 본문(`B08_Quantity_UI_Page.ts`)이 이미 700줄을 크게 넘어 새 코드를 그리로 * 보내지 않고 이 파일로 뀜다(CLAUDE.md 4장 700줄 제한). * ========================================================================== */ /** * 다 쌓인 조건 칸을 「제목 + 그 뒤 칸들」 덩어리로 잘라 **B03~B07 공통 상자**에 담는다. * * 왜 다 쌓은 뒤에 한 번 묶나 * 칸을 쌓는 코드가 400줄에 흩어져 있어 append 를 하나하나 고치면 손댈 자리가 너무 많다. * 제목은 `field(이름, "")` 이 낸 **값이 빈 줄**이고, 그것이 나올 때마다 새 상자가 열린다. * 상자 겉모습·접기는 공용 클래스가 전담한다 — B04·B06 과 같은 틀이다. * * ⚠ 개발용 줄과 맨 아래 액션 줄은 **상자 밖에 남긴다.** 액션 줄은 공용 코드가 패널 바닥에 * 고정하는 줄이라 상자 안으로 들어가면 바닥에 안 붙는다. * ⚠ 첫 제목보다 앞에 오는 것(산출법 한 줄 · 토량환산계수 구획)은 **제목 없는 상자**에 담는다 — * 토량환산계수는 제 제목을 제 안에 이미 들고 있어 따로 붙이면 제목이 둘이 된다. */ export function groupPanelSections(panel: HTMLElement): void { const isHeading = (node: Element): boolean => { if (node.tagName !== "DIV" || !node.classList.contains("b08-quantity__field")) return false; const value = node.querySelector(".b08-quantity__field-value"); return !value || !value.textContent; }; const newSection = (title: string | null): HTMLElement => { const section = document.createElement("section"); section.className = title ? "b08-quantity__section ui-collapsible ui-sidebar-section" : "b08-quantity__section ui-sidebar-section"; if (title) { const heading = document.createElement("p"); heading.className = "b08-quantity__section-title ui-collapsible__title"; heading.textContent = title; section.append(heading); } return section; }; let box: HTMLElement | null = null; for (const node of [...panel.children]) { // 개발용 줄·바닥 액션 줄은 건너뛰고 상자도 끊는다. if ( node.classList.contains("b08-quantity__dev") || node.classList.contains("ui-sidebar-actions") ) { box = null; continue; } if (isHeading(node)) { box = newSection(node.firstElementChild?.textContent ?? ""); panel.insertBefore(box, node); node.remove(); continue; } if (!box) { box = newSection(null); panel.insertBefore(box, node); } box.append(node); } }