diff --git a/B05_Profile/B05_Profile_UI_Structures_Groups.ts b/B05_Profile/B05_Profile_UI_Structures_Groups.ts index 63b1afc19..71bdf7beb 100644 --- a/B05_Profile/B05_Profile_UI_Structures_Groups.ts +++ b/B05_Profile/B05_Profile_UI_Structures_Groups.ts @@ -21,7 +21,8 @@ import { hiddenFormKeys } from "./B05_Profile_UI_Drainage_Facility_Merge"; import { buildSummaryRow, type SummaryRow } from "./B05_Profile_UI_Structures_Summary_Row"; import { isOptionVisible } from "./B05_Profile_UI_Structures_Summary"; import { SHAPE_FIELDS, shapeFields, shapeKey } from "./B05_Profile_UI_Structures_Define"; -import { field, numberInput } from "./B05_Profile_UI_Structures_Fields"; +import { numberInput } from "./B05_Profile_UI_Structures_Fields"; +import { grid, group as boxOf, labeled, stepper } from "./B05_Profile_UI_Drainage_Facility_Fields"; import { STRUCTURE_SPECS } from "../A00_Common/design/design_structure_pipe"; import { GROUP_JOIN, @@ -126,13 +127,11 @@ export function createGroupBoxes(): GroupBoxes { ); for (const group of groups) { const keys = hiddenFormKeys(facility, group.options); - const box = document.createElement("fieldset"); - box.className = "b05-structure__group b05-structure__optgroup"; - box.dataset.b05Group = group.id; - const legend = document.createElement("legend"); - legend.textContent = group.name; - const body = document.createElement("div"); - body.className = "b05-structure__grid"; + // 상자 꼴 = 명세 컨테이너(`design_structure_form`)와 같은 조각 — 제목 · 몸통 · 격자 · 잇기 줄(52-18) + const box = boxOf(group.name); + box.root.classList.add("b05-structure__optgroup"); + box.root.dataset.b05Group = group.id; + const body = grid(); for (const scope of scopes) { const marked = [...scope.querySelectorAll("[data-option-keys]")]; // 지금 숨은 칸(다른 시설 몫 · 안 고른 갈래)은 그 자리에 둠 — 같은 키 칸이 두 벌 옮겨 오지 않게 @@ -180,23 +179,24 @@ export function createGroupBoxes(): GroupBoxes { handlers?.change?.(); }); shapeInputs.set(key, input); - body.append(field(shape.label, input)); + body.append(labeled(shape.label, stepper(input, 0.1))); } if (!body.childElementCount) { const none = document.createElement("p"); none.className = "b05-structure__owner-note"; - none.textContent = "옵션 없음 — 집계 항목만 지정"; + none.textContent = "옵션 없음 — 구조물 조합만 지정"; body.append(none); } const row = buildSummaryRow(); + row.root.querySelector(".b05-structure__summary-label")!.textContent = "구조물 조합"; row.set(items[group.id] ?? null); row.bind({ pick: () => handlers?.pick(group.id), clear: () => handlers?.clear(group.id), }); rows.set(group.id, row); - box.append(legend, body, row.root); - boxes.push(box); + box.body.append(body, row.root); + boxes.push(box.root); bodies.push(body); } const stale = diff --git a/B05_Profile/B05_Profile_UI_Structures_Panel_Options.ts b/B05_Profile/B05_Profile_UI_Structures_Panel_Options.ts index 650aef741..320f151ef 100644 --- a/B05_Profile/B05_Profile_UI_Structures_Panel_Options.ts +++ b/B05_Profile/B05_Profile_UI_Structures_Panel_Options.ts @@ -20,6 +20,7 @@ import { staleValues, } from "./B05_Profile_UI_Structures_Define"; import { FORM_OPTION_KEYS } from "./B05_Profile_UI_Drainage_Facility_Merge"; +import { stepper } from "./B05_Profile_UI_Drainage_Facility_Fields"; import { STRUCTURE_SPECS } from "../A00_Common/design/design_structure_pipe"; import { paintStructureSpec, specOwnedKeys } from "./B05_Profile_UI_Structures_Spec"; import { solveSplit, specKeys, type SplitRole } from "../A00_Common/design/design_structure_spec"; @@ -97,7 +98,15 @@ export function renderOptionFields( const name = (c: string): string => type.spec_names?.[`${option.key}=${c}`] ?? c; const input = optionControl(option, values[option.key], name); const label = `${option.unit ? `${option.label} (${option.unit})` : option.label}${option.not_in_table ? " · 표에 안 쓰임" : ""}`; - const wrap = field(label, input, option.default_basis); + // 정의 그룹 상자로 옮겨 갈 숫자 칸 = 명세 컨테이너와 같은 [-][숫자][+](52-18) + const grouped = + option.input === "number" && !!type.groups?.some((g) => g.options.includes(option.key)); + const wrap = field( + label, + grouped ? stepper(input as HTMLInputElement, 0.1) : input, + option.default_basis, + ); + if (grouped) wrap.htmlFor = input.id; // 라벨 대상 = 숫자 칸(첫 버튼으로 새지 않게) wrap.dataset.optionKeys = option.key; // 옵션 그룹 상자가 이 표식으로 칸을 옮김(PLAN 46-3) // 배치 격자(48-3) — 정의 `배치` 의 줄 · 칸 · 너비 · 없으면 흐름대로 const place = gridPlace(type.spots?.[option.key], columns); diff --git a/B05_Profile/B05_Profile_UI_Style_Structures.css b/B05_Profile/B05_Profile_UI_Style_Structures.css index 0d374f4dc..ac4c69368 100644 --- a/B05_Profile/B05_Profile_UI_Style_Structures.css +++ b/B05_Profile/B05_Profile_UI_Style_Structures.css @@ -499,25 +499,13 @@ } .b05-structure__optgroup { - display: flex; - flex-direction: column; - gap: 6px; min-width: 0; /* 긴 집계 항목 이름이 상자를 패널 밖으로 밀지 않게(fieldset 최소 폭 · 52-9) */ } -.b05-structure__optgroup > legend { - font-weight: 600; - opacity: 1; -} - .b05-structure__optgroup .is-option-hidden { display: none; } -.b05-structure__optgroup > .b05-structure__grid.is-locked { - opacity: 0.5; -} - /* 구조물 정의 규칙(PLAN 48-4)이 가린 칸 — 그룹 상자로 옮겨 가도 같은 표식 */ .b05-structure-section .is-rule-hidden { display: none;