From 87ecf8a2e1efbef3e9066d919c7e6e804b021567 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sat, 12 Sep 2026 14:39:31 +0900 Subject: [PATCH] =?UTF-8?q?feat(B09):=20=EC=A2=8C=EC=B8=A1=20=ED=8C=A8?= =?UTF-8?q?=EB=84=90=EC=9D=84=20B03~B07=20=EA=B3=B5=ED=86=B5=20=ED=8B=80(?= =?UTF-8?q?=EC=A0=91=ED=9E=88=EB=8A=94=20=EC=83=81=EC=9E=90=C2=B7=EB=B0=94?= =?UTF-8?q?=EB=8B=A5=20=EA=B3=A0=EC=A0=95=20=EC=95=A1=EC=85=98=20=EC=A4=84?= =?UTF-8?q?)=EB=A1=9C=20=EA=B5=90=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 조건 상자 다섯을 `ui-collapsible ui-sidebar-section` 으로, 제목에 `ui-collapsible__title` 부여 - 자체 `b09-panel__actions` 를 공용 `ui-sidebar-actions` 로 바꿔 [계산]·[확정] 이 패널 바닥에 고정 - 패널 루트에 `attachCollapsible` 연결 — 제목 행 클릭으로 접힘·펼침 - 상자 꼴(패딩·모서리·배경)은 `.ui-sidebar-section` 이 붙은 것만 집어 기초자료 본문 표는 불변 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01GrXDD23Dvt2sR7q3X6oekp --- B09_Estimation/B09_Estimation_UI_Page.ts | 34 ++++++++++++++++-------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/B09_Estimation/B09_Estimation_UI_Page.ts b/B09_Estimation/B09_Estimation_UI_Page.ts index 766587b8..fa5576f8 100644 --- a/B09_Estimation/B09_Estimation_UI_Page.ts +++ b/B09_Estimation/B09_Estimation_UI_Page.ts @@ -16,6 +16,7 @@ import { ui_locales, currentLanguageIndex } from "@ui/ui_template_locale"; import { createButton, createInputField, showToast } from "@ui/ui_template_elements"; import { createWorkflowLayout } from "@ui/ui_template_workflow_layout"; +import { attachCollapsible } from "@ui/ui_template_collapsible"; import { drawBaseDataTab, drawFactorChoices, @@ -175,6 +176,14 @@ function injectStyles(): void { style.textContent = ` .b09-panel { display: flex; flex-direction: column; gap: var(--space-md, 12px); } .b09-panel__group { display: flex; flex-direction: column; gap: var(--space-xs, 4px); } +/* 좌측 패널 상자 — B04~B07 과 같은 꼴(테두리는 공용 .ui-sidebar-section 이 전담). + .ui-sidebar-section 이 붙은 것만 집어 본문 기초자료 표의 같은 클래스는 안 건드린다. */ +.b09-panel__group.ui-sidebar-section { + margin: 0; + padding: calc(var(--spacing-8) + var(--spacing-4)); + border-radius: var(--radius-cards); + background-color: var(--color-surface-raised); +} .b09-panel__legend { font-size: var(--font-size-xs, 12px); letter-spacing: .06em; color: var(--color-text-secondary); text-transform: uppercase; @@ -184,7 +193,6 @@ function injectStyles(): void { display: flex; justify-content: space-between; gap: var(--space-sm, 8px); border-bottom: 1px solid var(--color-border); padding: 2px 0; } -.b09-panel__actions { display: flex; gap: var(--space-xs, 4px); margin-top: var(--space-sm, 8px); } .b09-hint { font-size: var(--font-size-xs, 12px); color: var(--color-text-secondary); } /* 표본이 얇은 노임 — 막는 것이 아니라 눈에 띄기만 하면 된다. */ .b09-hint--warn { color: var(--color-warning-text, #8a5a00); } @@ -483,10 +491,10 @@ function buildSidePanel( legendKey: keyof typeof ui_locales, fields: Array<[keyof CostFormState, keyof typeof ui_locales]>, ): void => { - const group = document.createElement("div"); - group.className = "b09-panel__group"; + const group = document.createElement("section"); + group.className = "b09-panel__group ui-collapsible ui-sidebar-section"; const legend = document.createElement("span"); - legend.className = "b09-panel__legend"; + legend.className = "b09-panel__legend ui-collapsible__title"; legend.textContent = L(legendKey); group.append(legend); for (const [field, labelKey] of fields) { @@ -512,10 +520,10 @@ function buildSidePanel( ]); // 요율 판 — 읽기 전용. 「어느 판으로 계산했나」가 화면에 남아야 재현성이 선다. - const rateGroup = document.createElement("div"); - rateGroup.className = "b09-panel__group"; + const rateGroup = document.createElement("section"); + rateGroup.className = "b09-panel__group ui-collapsible ui-sidebar-section"; const rateLegend = document.createElement("span"); - rateLegend.className = "b09-panel__legend"; + rateLegend.className = "b09-panel__legend ui-collapsible__title"; rateLegend.textContent = L("B09_Estimation_Group_RateVersion"); const rateVersionBox = document.createElement("div"); rateGroup.append(rateLegend, rateVersionBox); @@ -532,10 +540,10 @@ function buildSidePanel( ]); // 수량 — 여러 줄이라 텍스트 영역으로. 비어 있으면 위 직접비 3칸을 그대로 쓴다. - const quantityGroup = document.createElement("div"); - quantityGroup.className = "b09-panel__group"; + const quantityGroup = document.createElement("section"); + quantityGroup.className = "b09-panel__group ui-collapsible ui-sidebar-section"; const quantityLegend = document.createElement("span"); - quantityLegend.className = "b09-panel__legend"; + quantityLegend.className = "b09-panel__legend ui-collapsible__title"; quantityLegend.textContent = L("B09_Estimation_Group_Quantity"); const quantityLabel = document.createElement("label"); quantityLabel.className = "ui-field__label"; @@ -555,7 +563,8 @@ function buildSidePanel( root.append(hintBox); const actions = document.createElement("div"); - actions.className = "b09-panel__actions"; + // 바닥 고정 액션 줄(공용) — ui_template_overlay 가 이 줄을 스크롤 밖으로 빼낸다. + actions.className = "ui-sidebar-actions"; actions.append( createButton({ label: L("B09_Estimation_Btn_Recalc"), @@ -569,6 +578,9 @@ function buildSidePanel( ); root.append(actions); + // 그룹 제목 행 클릭 시 접기/펼치기(B04~B07 공통). 액션 줄은 collapsible 이 아니다. + attachCollapsible(root); + return { root, rateVersionBox, hintBox }; }