feat(M01): 단가산출 로직 상세 차례 · 오른쪽 흐름도/원문 두 패널
- 좌측 차례 = 기본정보 › 시험 계산 › 단가산출 상세 › 텍스트 수식 - 오른쪽 패널 둘(흐름도 · 원문) — 하나만 열림 · 둘 다 접기 · 머리 토글 단추 · 열린 패널 계정 취향(m01-logic-panel) - 흐름도 패널 접힘을 부르는 쪽이 정하는 길(folded · onFold · fold) - 원문 패널 = 출처 글로 품셈 본문 절을 찾아 보임(GET /api/m01/logic/source) · 못 찾으면 「원문 연결 없음」 + 출처 - 시험 test_m01_logic_source.py · 화면 시나리오 ui_checks/44-4_로직상세_패널.js Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NPJGtfXo6GMbcpiboQC4uK
This commit is contained in:
@@ -41,6 +41,9 @@ export interface FlowPanelOpts {
|
||||
logics?(key: string): Promise<CfLogic | null>;
|
||||
/** 패널 너비가 바뀜(끌기 · 접기 · 펴기) — 부르는 쪽이 칸 너비를 맞춤 */
|
||||
onResize?(px: number): void;
|
||||
/** 접힘을 부르는 쪽이 정함(처음 값) — 주면 접기 단추는 onFold 만 부르고 기억도 부르는 쪽 몫 */
|
||||
folded?: boolean;
|
||||
onFold?(on: boolean): void;
|
||||
}
|
||||
|
||||
export interface FlowPanel {
|
||||
@@ -49,6 +52,8 @@ export interface FlowPanel {
|
||||
destroy(): void;
|
||||
/** 크게 보기 열기 */
|
||||
expand(): void;
|
||||
/** 밖에서 접기 · 펴기(onFold 를 부르지 않음) */
|
||||
fold(on: boolean): void;
|
||||
}
|
||||
|
||||
/* ── 너비(DOM 없음) ─────────────────────────────────────────────────── */
|
||||
@@ -105,8 +110,9 @@ export function mountFlowPanel(host: HTMLElement, opts: FlowPanelOpts): FlowPane
|
||||
});
|
||||
const { diagram, detail, summary, note, undo } = paper.parts;
|
||||
let width = storedWidth(readStore(WIDTH_KEY));
|
||||
let folded = readStore(FOLD_KEY) === "1";
|
||||
const tell = (): void => opts.onResize?.(folded ? STRIP_WIDTH : (width ?? host.clientWidth));
|
||||
let folded = opts.folded ?? readStore(FOLD_KEY) === "1";
|
||||
const tell = (): void =>
|
||||
opts.onResize?.(folded ? STRIP_WIDTH : (width ?? Math.max(PANEL_MIN, host.clientWidth)));
|
||||
|
||||
const sm = (label: string, onClick: () => void, variant: "ghost" | "filled" = "ghost") =>
|
||||
createButton({ label, size: "sm", variant, onClick });
|
||||
@@ -116,7 +122,7 @@ export function mountFlowPanel(host: HTMLElement, opts: FlowPanelOpts): FlowPane
|
||||
label: tf("Toggle"),
|
||||
size: "sm",
|
||||
variant: "ghost",
|
||||
onClick: () => setFolded(!folded),
|
||||
onClick: () => (opts.onFold ? opts.onFold(!folded) : setFolded(!folded)),
|
||||
});
|
||||
toggle.classList.add("m02-dfp__toggle");
|
||||
const head = el("header", {
|
||||
@@ -215,7 +221,7 @@ export function mountFlowPanel(host: HTMLElement, opts: FlowPanelOpts): FlowPane
|
||||
if (on && !folded && width === null && root.isConnected)
|
||||
width = Math.round(root.getBoundingClientRect().width);
|
||||
folded = on;
|
||||
writeStore(FOLD_KEY, on ? "1" : "0");
|
||||
if (!opts.onFold) writeStore(FOLD_KEY, on ? "1" : "0");
|
||||
root.classList.toggle("is-folded", on);
|
||||
open.hidden = on;
|
||||
strip.hidden = !on;
|
||||
@@ -290,5 +296,6 @@ export function mountFlowPanel(host: HTMLElement, opts: FlowPanelOpts): FlowPane
|
||||
root.remove();
|
||||
},
|
||||
expand,
|
||||
fold: (on) => on !== folded && setFolded(on),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user