Files
Aislo/A00_Common/design/design_plan_peek.ts
T
eomsangdonandClaude Opus 5.5 eac20bd93b fix(436 B06 평면 패널): 처음 높이 바닥 160 px · 높이 상한 = 패널 % 기준 칸(offsetParent) (433-8)
- 종단 판 펼친 B06 = 칸 225 px 라 32 % 가 72 px — max(32%, 160px)
- 끌기 상한이 높이 0 인 횡단 center 를 재어 늘 120 px 로 눌림 — offsetParent 높이 − 48 px
- PLAN 436-1 검증완료

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QfHKQs7J3hQELKMWQMUJEy
2026-10-18 17:20:38 +09:00

83 lines
3.5 KiB
TypeScript

/* =============================================================================
* design_plan_peek.ts
* 횡단 보기 위 **평면 겹침 패널**(요구 258 · 계획서 425) — 종단 보기의 평면(노선 편집) 노드를
* 그대로 옮겨 붙여 보여 줌(둘째 캔버스 없음 · 편집기는 페이지에 하나). 열 때 옮기고 · 닫을 때 ·
* 횡단 보기가 숨을 때 제자리(자리표 주석)로 돌림. 누름 · 휠은 캔버스에 붙어 함께 옴.
*
* 조작 · 되돌리기 · 옵션 값은 B05 평면 그대로(같은 편집기 · 436) — 단추 줄 · 안내 · 상태줄 등만 감춤
* (`design_page.css`). 높이 = 아래 끝 끌기(화면 기억) · 열 때 · 크기 바뀔 때 내용 맞춤 없음.
* ========================================================================== */
import { createWorkflowPanelHandle } from "@ui/ui_template_overlay";
import { createPanelResizer } from "@ui/ui_template_resizer";
import { stateKey } from "../b_page_state";
import type { DesignPageHost } from "./design_page";
import type { DesignPageShared } from "./design_shared";
/** 횡단 보기 가운데(`center`)에 겹침 패널 · 손잡이를 세운다. */
export function mountPlanPeek(
center: HTMLElement,
host: DesignPageHost,
shared: DesignPageShared,
): void {
const root = document.createElement("div");
root.className = "design-plan-peek";
const body = document.createElement("div");
body.className = "design-plan-peek__body";
const note = document.createElement("p");
note.className = "design-plan-peek__note";
body.append(note);
const handle = createWorkflowPanelHandle("bottom", "up", "평면");
// 아래 끝 끌어 높이 — 120 px ~ 칸 높이 − 48 px(손잡이 자리) · 두 번 누름 = 처음 높이(32 %)
// 칸 = 패널 % 높이가 재는 자리(offsetParent) — `center` 는 높이 0
const resizer = createPanelResizer({
axis: "vertical",
target: root,
cssVar: "--design-plan-peek-height",
direction: 1,
min: 120,
max: () => (root.offsetParent?.clientHeight ?? 0) - 48,
storageKey: stateKey("plan-peek-height") ?? undefined,
});
root.append(body, resizer.root, handle.root);
center.append(root);
let opened = false;
let plan: HTMLElement | null = null;
let home: Comment | null = null;
const setOpen = (open: boolean): void => {
opened = open;
root.classList.toggle("is-open", open);
handle.setOpen(open);
};
const close = (): void => {
setOpen(false);
if (plan && home) home.replaceWith(plan);
home = null;
};
const open = async (): Promise<void> => {
setOpen(true);
resizer.restore(); // 기억한 높이를 지금 칸에 맞춰 다시 씌움(세울 때는 칸 크기 0)
note.hidden = false;
note.textContent = "평면을 여는 중…";
await shared.ensureView("profile"); // B06 바로 열기 = 종단 보기를 숨긴 채 세움
if (!opened || !host.visible() || home) return;
plan =
center
.closest(".design-page__center")
?.querySelector<HTMLElement>(".b05-route__main > .b05-routeedit") ?? null;
if (!plan) return void (note.textContent = "평면을 불러오지 못했습니다.");
note.hidden = true;
home = document.createComment("design-plan-peek");
plan.replaceWith(home);
body.append(plan); // 크기 0 → 첫 크기 알림에 편집기가 다시 그림
};
handle.root.addEventListener("click", () => (opened ? close() : void open()));
host.onHide(close);
setOpen(false);
}