feat(382-1): B05 우측 횡단 판 = 패널 양식(손잡이 · 머리 · 폭 끌기 · 열림 · 폭 기억 · 지도 위 덮개 그대로)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TteK8mfYZetk5P3bEZkyVZ
This commit is contained in:
2026-10-17 14:44:23 +09:00
co-authored by Claude Opus 5.5
parent 7329065c3b
commit 0800796998
3 changed files with 45 additions and 44 deletions
+29 -15
View File
@@ -1,4 +1,5 @@
import { createButton } from "@ui/ui_template_elements";
import { createSidePanels, type SidePanels } from "@ui/ui_template_side_panels";
import { bindFootprintToggle } from "./B05_Profile_UI_RouteEdit_Footprint";
/* =============================================================================
@@ -46,6 +47,12 @@ export interface RouteEditChrome {
terrainSelect: HTMLSelectElement;
}
/** 손잡이 자리(24) + 틈(8) — 접혀도 남는 폭(`.ui-side-panels` margin-left). */
const SIDE_HANDLE_PX = 32;
/** 횡단 판 몸 → 패널 묶음 — 고른 측점 횡단을 띄울 때 접힌 판을 폄(382-2 · `_Cross`). */
export const sidePanelsOf = new WeakMap<HTMLElement, SidePanels>();
// 글판 접기 기억(345-5 덧 3) — 페이지 동안만(모듈 값) · 다시 열어도 그대로.
let hintOpen = false;
let infoCollapsed = false;
@@ -118,26 +125,33 @@ export function createRouteEditChrome(
</div>
</div>
<div class="b05-routeedit__busy" hidden><span></span></div>
<aside class="b05-routeedit__side-wrap">
<button type="button" class="ui-btn ui-btn--glass b05-routeedit__side-toggle"
data-act="side-toggle" aria-expanded="true" title="오른쪽 횡단 미리보기 칸 접기 · 펴기">횡단</button>
<div class="b05-routeedit__side"></div>
</aside>`;
<aside class="b05-routeedit__side-wrap"></aside>`;
parent.append(overlay);
// 부른 쪽 단추([3D])도 같은 유리 단추로 — 지도 위에 떠 있는 도구줄.
tools.forEach((tool) => tool.classList.replace("ui-btn--ghost", "ui-btn--glass"));
overlay.querySelector('[data-slot="tools"]')!.replaceWith(...tools);
// 횡단 미리보기 = 접는 칸 — 좁은 화면은 접힌 채 시작(지도가 먼저다).
const sideWrap = overlay.querySelector<HTMLElement>(".b05-routeedit__side-wrap")!;
const sideToggle = overlay.querySelector<HTMLButtonElement>('[data-act="side-toggle"]')!;
const setSide = (open: boolean): void => {
sideWrap.classList.toggle("is-collapsed", !open);
overlay.classList.toggle("is-side-open", open); // 회전 단추 · 잰 값 창이 판을 비킴
sideToggle.setAttribute("aria-expanded", String(open));
};
setSide(window.innerWidth >= 1500);
sideToggle.addEventListener("click", () => setSide(sideWrap.classList.contains("is-collapsed")));
// 횡단 미리보기 = 패널 양식(382-1 · 손잡이 · 머리 · 폭 끌기 · 열림 · 폭 기억) · 자리는 지도 위 덮개 그대로 ·
// 기억이 없으면 좁은 화면은 접힌 채 시작(지도가 먼저다) · 잰 값 창이 판을 비킴(--b05-side-open).
const side = document.createElement("div");
side.className = "b05-routeedit__side";
const setSideOpen = (): void =>
overlay.style.setProperty(
"--b05-side-open",
`${(panels.current() ? panels.width() : 0) + SIDE_HANDLE_PX}px`,
);
const panels = createSidePanels({
prefKey: "b05-routeedit-cross",
panels: [{ id: "cross", title: "횡단", body: side }],
defaultOpen: window.innerWidth >= 1500 ? "cross" : null,
defaultWidth: 460,
follow: false,
onChange: setSideOpen,
onResize: setSideOpen,
});
sidePanelsOf.set(side, panels);
overlay.querySelector(".b05-routeedit__side-wrap")!.append(panels.root);
setSideOpen();
// 도움말 = 기본 접힘 · [?] 한 번에 펼침(345-5 덧 3).
const hint = overlay.querySelector<HTMLElement>(".b05-routeedit__hint")!;
+10 -24
View File
@@ -4,17 +4,13 @@
/* 평면 = 가운데 칸 전체(352-1) — 머리 줄 · 테두리 없음. 도구줄은 3D 와 같은 떠 있는 유리 단추
(`.b05-route__view-controls` · ☰ 비킴 `--wf-burger-pad`) · 횡단 판은 오른쪽을 덮는 판. */
.b05-routeedit {
--b05-side-open: 0px; /* 횡단 판이 펴져 지도를 덮는 폭 */
--b05-side-open: 0px; /* 횡단 판이 지도를 덮는 폭(손잡이 포함 · `_Chrome` 이 적음) */
position: relative;
display: flex;
flex: 1 1 auto;
min-height: 0;
}
.b05-routeedit.is-side-open {
--b05-side-open: 460px;
}
/* 도구줄 — 3D 도구줄 규격 그대로 · 회전 단추도 이 줄(366-2) · 넘치면 줄바꿈. */
.b05-routeedit__tools {
right: var(--spacing-12);
@@ -187,9 +183,8 @@
border-top: 2px solid var(--map-route, #f97316);
}
/* 오른쪽 덮는 판 — 위아래 반씩 나눠 **지금 횡단**과 **이전 횡단**이 앉는다(352-1). 지도 위에 얹고
아래 종단 판(z 3)이 그 위를 덮는다. 접는 칸(345-3) — 좁은 화면은 접힌 채 시작(`_Chrome`) ·
[횡단] 단추로 펴고 접는다. 빈 자리는 지도 조작을 통과. */
/* 오른쪽 덮는 판 — 패널 양식(382-1 · `ui_template_side_panels` · 손잡이 · 머리 · 폭 끌기) 을 지도 위에 얹음 ·
위아래 반씩 **지금 횡단** · **이전 횡단**(352-1) · 아래 종단 판(z 3)이 그 위를 덮음 · 빈 자리는 지도 조작을 통과. */
.b05-routeedit__side-wrap {
position: absolute;
z-index: 2;
@@ -197,24 +192,20 @@
right: var(--spacing-12);
bottom: var(--spacing-12);
display: flex;
flex-direction: column;
gap: var(--spacing-8);
min-height: 0;
pointer-events: none;
}
.b05-routeedit__side-wrap.is-collapsed {
bottom: auto;
}
.b05-routeedit__side-wrap > * {
pointer-events: auto;
}
.b05-routeedit__side-toggle {
align-self: flex-end;
min-width: 56px;
height: 34px;
.b05-routeedit__side-wrap .ui-side-panels__panel {
box-shadow: 0 12px 40px rgb(0 0 0 / 45%);
}
.b05-routeedit__side-wrap .ui-side-panels__body {
display: flex;
}
.b05-routeedit__side {
@@ -222,14 +213,10 @@
flex: 1 1 auto;
flex-direction: column;
gap: var(--spacing-12);
width: 452px;
min-width: 0;
min-height: 0;
}
.b05-routeedit__side-wrap.is-collapsed > .b05-routeedit__side {
display: none;
}
.b05-routeedit__cross {
display: flex;
flex: 1 1 0;
@@ -241,7 +228,6 @@
border: 1px solid var(--color-border);
border-radius: var(--radius-16, 12px);
background: var(--color-surface-raised);
box-shadow: 0 12px 40px rgb(0 0 0 / 45%);
}
.b05-routeedit__cross-head {
@@ -43,7 +43,9 @@ def test_겉틀은_본문_칸():
assert 'title="되돌리기 (Ctrl+Z)"' in chrome and 'title="다시하기 (Ctrl+Y)"' in chrome
# 시험 · 배선이 집는 자리는 남김
assert "b05-routeedit__measure-close" in chrome
assert 'data-act="side-toggle"' in chrome and "is-collapsed" in chrome
# 382-1 — 오른쪽 횡단 판 = 패널 양식(손잡이 · 머리 · 폭 끌기 · 열림 · 폭 기억) · 칸 높이를 채움
assert "createSidePanels({" in chrome and 'prefKey: "b05-routeedit-cross"' in chrome
assert "follow: false" in chrome and 'data-act="side-toggle"' not in chrome
def test_CSS_덮개_걷음_대기막은_전체():
@@ -55,9 +57,8 @@ def test_CSS_덮개_걷음_대기막은_전체():
assert "position: fixed;" in busy and "z-index: var(--z-modal, 1000);" in busy
label = _block(css, ".b05-routeedit__label")
assert "position: absolute;" in label and "position: fixed" not in label
assert "display: none;" in _block(
css, ".b05-routeedit__side-wrap.is-collapsed > .b05-routeedit__side"
)
# 382-1 — 자체 [횡단] 단추 · 접기 걷음(접기는 양식 손잡이)
assert "b05-routeedit__side-toggle" not in css and "is-side-open" not in css
assert "@media (width < 1500px)" not in css # 접기는 단추로(처음만 폭으로)
@@ -87,7 +88,7 @@ def test_352_1_머리줄_상자_없음_도구는_뜬_단추_횡단은_우측_덮
assert "right: var(--spacing-12);" in _block(css, ".b05-routeedit__spin") # 도구줄 줄 오른쪽
assert "34px" in side # 횡단 판은 도구줄 줄 아래에서 시작
assert "var(--b05-side-open)" in _block(css, ".b05-routeedit__measure")
assert "is-side-open" in chrome
assert '"--b05-side-open"' in chrome # 판 폭(손잡이 포함)을 적음
glass = _block(css, ".b05-routeedit__terrain")
assert "backdrop-filter: blur(6px);" in glass and "background:" in glass