/* ============================================================================= * B05_Profile_UI_Drainage_Revet_Choice.ts * 관 보호공 상자 안 [연동] · [경사] 한 줄(54-30) — 반 폭 단추 둘 · 쓸 수 있는 쪽만 누를 수 있음. * 값 = 횡단 연동 제어 옛 자리(`revet_link_detached` · `revet_follow_grade` · `design_structure_pipe_calc`) · * 고르면 횡단 그림이 바로 따라감. 경사를 끄면(수평) 연동은 풀 수 없음(옛 규칙 그대로). * ========================================================================== */ import { toggleButton } from "./B05_Profile_UI_Panel_Fields"; import { pipeRevetChoice, setPipeRevetChoice, } from "../A00_Common/design/design_structure_pipe_calc"; const LINK_TITLE = "옆 측점 흙막이와 횡단 자리를 함께 씀 — 끄면 측점마다 따로 잡음"; const LINK_LOCKED = "경사를 끈(수평) 동안은 연동을 풀 수 없음"; const GRADE_TITLE = "종단경사 반영 — 끄면 연장 구간 내내 같은 높이(수평)"; /** 한 줄 — `paint` 가 지금 값 · 쓸 수 있는지를 다시 칠하고 줄을 돌려줌(폼 다시 그림마다). */ export function revetChoiceRow( chainageOf: () => number | null, /** 쓴 뒤 — 폼을 다시 그려 유입 · 유출 두 줄을 함께 칠함. */ written: () => void, ): { paint: (hidden: boolean) => HTMLElement; } { const row = document.createElement("div"); // label 이 아님 — 이름표를 눌러 첫 단추가 눌리지 않게 row.className = "b05-route__field"; const caption = document.createElement("span"); caption.textContent = "옵션"; const pair = document.createElement("div"); pair.className = "b05-structure__half-pair"; const write = (kind: "link" | "grade", on: boolean): void => void setPipeRevetChoice(chainageOf(), kind, on).then(written); const link = toggleButton("연동", true, (on) => write("link", on)); const grade = toggleButton("경사", true, (on) => write("grade", on)); grade.title = GRADE_TITLE; pair.append(link, grade); row.append(caption, pair); const set = (button: HTMLButtonElement, value: boolean | null, locked: boolean): void => { button.disabled = value === null || locked; button.classList.toggle("is-active", value === true); button.setAttribute("aria-pressed", String(value === true)); }; function paint(hidden: boolean): HTMLElement { const now = pipeRevetChoice(chainageOf()); const locked = now?.grade === false; set(link, now?.linked ?? null, locked); link.title = locked ? LINK_LOCKED : LINK_TITLE; set(grade, now?.grade ?? null, false); row.hidden = hidden; return row; } return { paint }; } /** 세월교 · 박스 흙막이 상자 줄(65-2 · 배관과 같은 줄) — 흙막이를 고른 유입 · 유출 · 추가 흙막이 상자마다 한 줄. * 명세 폼 `fields` 자리에 그대로 씀. */ export function guardChoiceFields( chainageOf: () => number | null, written: () => void, ): (c: { id: string }, values: Record) => HTMLElement[] { const sides = { inlet: revetChoiceRow(chainageOf, written), outlet: revetChoiceRow(chainageOf, written), }; return (c, values) => c.id === "soil_add" ? [revetChoiceRow(chainageOf, written).paint(false)] : c.id === "inlet" || c.id === "outlet" ? [sides[c.id].paint(values.structure !== "흙막이")] : []; }