feat(B05): 352-1 평면 전체 칸 · 머리 줄 · 테두리 삭제 · 도구 떠 있는 유리 단추 · 횡단 우측 덮는 판
- 머리 줄(제목 · 테두리)과 상자 삭제 · 도구줄 = 3D 와 같은 떠 있는 단추(☰ 비킴) - [?] 도구줄 아래 · 분석 지형 글에 유리 바탕 - 횡단 판 = 오른쪽 덮는 판(z 2 · 아래 종단 판 z 3 이 위) · 회전 단추 · 잰 값 창이 판을 비킴 - 시험 chrome_modal · initial 고쳐 씀 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VmC34fsxxbweEG3RUjs3Mn
This commit is contained in:
@@ -8,9 +8,9 @@ import { bindFootprintToggle } from "./B05_Profile_UI_RouteEdit_Footprint";
|
||||
* `B05_Profile_UI_RouteEdit.ts` 가 700줄을 넘겨 떼어낸 조각이다(2026-09-12). 생김새만 있고
|
||||
* 동작은 없다 — 배선은 본체와 각 조각(`_Apply`·`_Rotate`·`_History`…)이 한다.
|
||||
*
|
||||
* **배치**(2026-09-12 사용자 지시 ⑩~⑬·⑱) — 아래 정보행을 없애고 지도 위 오버레이로 옮겼다.
|
||||
* 단추는 제목행 오른쪽, 조작 설명은 지도 왼쪽 위 2열, 상태·범례는 왼쪽 아래, 잰 값은 오른쪽
|
||||
* 아래. 메인 창은 왼쪽으로 밀고 오른쪽 세로 칸에 횡단 두 판이 앉는다.
|
||||
* **배치**(352-1) — 지도가 칸 전체 · 머리 줄 · 테두리 없음. 도구는 3D 와 같은 떠 있는 유리 단추
|
||||
* (지도 왼쪽 위 · ☰ 비킴), [?] 조작 설명은 도구줄 아래 2열, 상태·범례는 왼쪽 아래, 잰 값은 오른쪽
|
||||
* 아래. 횡단 두 판은 지도 오른쪽을 덮는 판(아래 종단 판이 그 위).
|
||||
*
|
||||
* 자리(345-3) — 모달이 아니라 종단 보기 가운데 위 본문(옛 3D 자리)에 붙는다. 덮개 · 전체 화면 ·
|
||||
* 닫기 단추는 걷었다 · [취소] · [확인] · [노선 반영] · [저장 전으로]는 없앰(346-3 · 352-2 — 노선은 페이지
|
||||
@@ -57,12 +57,11 @@ export function createRouteEditChrome(
|
||||
const overlay = document.createElement("div");
|
||||
overlay.className = "b05-routeedit";
|
||||
overlay.innerHTML = `
|
||||
<div class="b05-routeedit__box" aria-label="계획노선 편집">
|
||||
<div class="b05-routeedit__head">
|
||||
<h3>계획노선</h3>
|
||||
<span class="b05-routeedit__actions">
|
||||
<div class="b05-routeedit__canvas-wrap" aria-label="계획노선 편집">
|
||||
<canvas class="b05-routeedit__canvas"></canvas>
|
||||
<div class="b05-route__view-controls b05-routeedit__tools">
|
||||
<span data-slot="tools"></span>
|
||||
<i class="b05-routeedit__divider" aria-hidden="true"></i>
|
||||
<i class="b05-route__view-separator" aria-hidden="true"></i>
|
||||
<label class="b05-routeedit__terrain" hidden
|
||||
title="노선 편집 분석(등고선 · 지반고 · 기울기 · 횡단 미리보기 · 추천)에 쓸 지형 — 확정 지표면 · 종횡단은 안 바뀝니다">분석 지형
|
||||
<select class="ui-select ui-select--sm" data-act="terrain">
|
||||
@@ -70,27 +69,24 @@ export function createRouteEditChrome(
|
||||
<option value="sheet">수치지형도</option>
|
||||
</select>
|
||||
</label>
|
||||
<button type="button" class="ui-btn ui-btn--ghost" data-act="fit"
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="fit"
|
||||
title="등고 영역(등고선 범위 · 노선)을 평면 가운데 알맞게 맞춥니다 (회전은 풂)">맞춤</button>
|
||||
<button type="button" class="ui-btn ui-btn--ghost" data-act="contour-minor"
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="contour-minor"
|
||||
aria-pressed="false" disabled
|
||||
title="1m 간격 등고선을 얇고 옅게 겹칩니다 (확대하면 보임)">1m 등고선</button>
|
||||
<button type="button" class="ui-btn ui-btn--ghost" data-act="measure"
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="measure"
|
||||
title="노선 위 두 점을 눌러 거리·기울기를 잽니다 (Shift+클릭도 같음)">거리 재기</button>
|
||||
<button type="button" class="ui-btn ui-btn--ghost" data-act="station-snap"
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="station-snap"
|
||||
aria-pressed="false"
|
||||
title="곡선(호) 안 측점 하나를 곡선 중점(MC)으로 옮깁니다 — [저장] 때 저장">측점 스냅</button>
|
||||
<button type="button" class="ui-btn ui-btn--ghost" data-act="footprint"
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="footprint"
|
||||
title="도로 끝 · 비탈 끝(깎기 붉음 · 쌓기 파랑)을 평면에 겹칩니다">발자국</button>
|
||||
<i class="b05-routeedit__divider" aria-hidden="true"></i>
|
||||
<button type="button" class="ui-btn ui-btn--ghost" data-act="undo"
|
||||
<i class="b05-route__view-separator" aria-hidden="true"></i>
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="undo"
|
||||
title="되돌리기 (Ctrl+Z)" aria-label="되돌리기" disabled>↶</button>
|
||||
<button type="button" class="ui-btn ui-btn--ghost" data-act="redo"
|
||||
<button type="button" class="ui-btn ui-btn--glass" data-act="redo"
|
||||
title="다시하기 (Ctrl+Y)" aria-label="다시하기" disabled>↷</button>
|
||||
</span>
|
||||
</div>
|
||||
<div class="b05-routeedit__canvas-wrap">
|
||||
<canvas class="b05-routeedit__canvas"></canvas>
|
||||
</div>
|
||||
<div class="b05-routeedit__hint">
|
||||
<button type="button" class="ui-btn ui-btn--glass b05-routeedit__hint-toggle"
|
||||
data-act="hint-toggle" aria-expanded="false" title="조작 도움말 펼치기 · 접기">?</button>
|
||||
@@ -121,15 +117,16 @@ export function createRouteEditChrome(
|
||||
<button type="button" class="b05-routeedit__info-toggle" data-act="info-toggle"
|
||||
aria-expanded="true" title="상태 · 범례 글판 접기 · 펴기">▾</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="b05-routeedit__busy" hidden><span></span></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--ghost b05-routeedit__side-toggle"
|
||||
<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>`;
|
||||
parent.append(overlay);
|
||||
// 부른 쪽 단추([3D])도 같은 유리 단추로 — 지도 위에 떠 있는 도구줄.
|
||||
tools.forEach((tool) => tool.classList.replace("ui-btn--ghost", "ui-btn--glass"));
|
||||
overlay.querySelector('[data-slot="tools"]')!.replaceWith(...tools);
|
||||
|
||||
// 횡단 미리보기 = 접는 칸 — 좁은 화면은 접힌 채 시작(지도가 먼저다).
|
||||
@@ -137,6 +134,7 @@ export function createRouteEditChrome(
|
||||
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);
|
||||
|
||||
@@ -1,59 +1,37 @@
|
||||
/* 계획노선 편집(평면) — 종단 보기 가운데 위 본문(옛 3D 자리 · 345-3). 덮개 · 전체 화면은 걷음 —
|
||||
재계산 대기 막만 화면을 덮는다(노선 재탐색 · CLAUDE.md 5장). 색은 전부 테마 토큰을 쓴다. */
|
||||
|
||||
/* 평면 = 가운데 칸 전체(352-1) — 머리 줄 · 테두리 없음. 도구줄은 3D 와 같은 떠 있는 유리 단추
|
||||
(`.b05-route__view-controls` · ☰ 비킴 `--wf-burger-pad`) · 횡단 판은 오른쪽을 덮는 판. */
|
||||
.b05-routeedit {
|
||||
--b05-side-open: 0px; /* 횡단 판이 펴져 지도를 덮는 폭 */
|
||||
--b05-side-top: 64px; /* 접힌 [횡단] 단추가 위 오른쪽을 덮는 폭 */
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
gap: var(--spacing-8);
|
||||
min-height: 0;
|
||||
padding: var(--spacing-8);
|
||||
}
|
||||
|
||||
/* 메인 창은 **왼쪽**, 횡단 두 판은 오른쪽 세로 칸(2026-09-12 사용자 지시 ⑱).
|
||||
좁은 화면에서는 오른쪽 칸이 접히고 메인이 폭을 다 가진다. */
|
||||
.b05-routeedit__box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--color-surface-raised);
|
||||
.b05-routeedit.is-side-open {
|
||||
--b05-side-open: 460px;
|
||||
--b05-side-top: 460px;
|
||||
}
|
||||
|
||||
/* 머리 = 도구줄 — 왼쪽 이름 · 오른쪽 단추 묶음. */
|
||||
.b05-routeedit__head {
|
||||
display: flex;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
gap: var(--spacing-12);
|
||||
padding: var(--spacing-8) var(--spacing-12);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.b05-routeedit__head > h3 {
|
||||
margin: 0;
|
||||
font-size: var(--text-body);
|
||||
}
|
||||
|
||||
/* 제목행 — 왼쪽에 이름, **오른쪽 끝에 단추 묶음**(2026-09-12 사용자 지시 ⑪).
|
||||
단추는 공용 규격(`.ui-btn`)을 그대로 쓴다 — 모달이 따로 만든 크기를 걷어냈다. */
|
||||
.b05-routeedit__actions {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
/* 도구줄 — 3D 도구줄 규격 그대로 · 오른쪽 회전 단추 · 횡단 판을 비켜 줄바꿈. */
|
||||
.b05-routeedit__tools {
|
||||
right: calc(var(--spacing-12) + var(--b05-side-top) + 104px);
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: var(--spacing-8);
|
||||
pointer-events: none; /* 빈 자리는 지도 조작을 통과 */
|
||||
}
|
||||
|
||||
.b05-routeedit__tools > * {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.b05-routeedit__canvas-wrap {
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
background: var(--color-surface);
|
||||
@@ -86,10 +64,10 @@
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 조작 설명 — 지도 왼쪽 위 · 기본 접힘 · [?] 로 펼침(345-5 덧 3) · 펼치면 **2열**(사용자 지시 ⑩). */
|
||||
/* 조작 설명 — 도구줄 아래 왼쪽 · 기본 접힘 · [?] 로 펼침(345-5 덧 3 · 352-1) · 펼치면 **2열**(사용자 지시 ⑩). */
|
||||
.b05-routeedit__hint {
|
||||
top: var(--spacing-12);
|
||||
left: var(--spacing-12);
|
||||
top: calc(var(--spacing-16) + 34px + var(--spacing-8));
|
||||
left: var(--spacing-16);
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: var(--spacing-8);
|
||||
@@ -173,11 +151,11 @@
|
||||
color: var(--color-text-body);
|
||||
}
|
||||
|
||||
/* 회전 단추 — 지도 오른쪽 위(사용자 지시 ⑯). 여기만 클릭을 받는다. */
|
||||
/* 회전 단추 — 지도 오른쪽 위(사용자 지시 ⑯) · 횡단 판 왼쪽에 앉음(352-1). 여기만 클릭을 받는다. */
|
||||
.b05-routeedit__spin {
|
||||
position: absolute;
|
||||
top: var(--spacing-12);
|
||||
right: var(--spacing-12);
|
||||
top: var(--spacing-16);
|
||||
right: calc(var(--spacing-12) + var(--b05-side-top));
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
gap: var(--spacing-8);
|
||||
@@ -211,18 +189,34 @@
|
||||
border-top: 2px solid var(--map-route, #f97316);
|
||||
}
|
||||
|
||||
/* 오른쪽 세로 칸 — 위아래 반씩 나눠 **지금 횡단**과 **이전 횡단**이 앉는다. 접는 칸(345-3) —
|
||||
좁은 화면은 접힌 채 시작(`_Chrome`) · [횡단] 단추로 펴고 접는다. */
|
||||
/* 오른쪽 덮는 판 — 위아래 반씩 나눠 **지금 횡단**과 **이전 횡단**이 앉는다(352-1). 지도 위에 얹고
|
||||
아래 종단 판(z 3)이 그 위를 덮는다. 접는 칸(345-3) — 좁은 화면은 접힌 채 시작(`_Chrome`) ·
|
||||
[횡단] 단추로 펴고 접는다. 빈 자리는 지도 조작을 통과. */
|
||||
.b05-routeedit__side-wrap {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: var(--spacing-16);
|
||||
right: var(--spacing-12);
|
||||
bottom: var(--spacing-12);
|
||||
display: flex;
|
||||
flex: none;
|
||||
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 {
|
||||
@@ -323,21 +317,20 @@
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* ㉓ 거리 재기와 되돌리기 사이 구분선. */
|
||||
.b05-routeedit__divider {
|
||||
width: 1px;
|
||||
height: 20px;
|
||||
margin: 0 var(--spacing-4, 4px);
|
||||
background: var(--color-border);
|
||||
}
|
||||
|
||||
/* 분석 지형 고르기(PLAN 133-1) — 라이다 있는 프로젝트만 보임. */
|
||||
/* 분석 지형 고르기(PLAN 133-1) — 라이다 있는 프로젝트만 보임 · 글에 유리 바탕(352-1). */
|
||||
.b05-routeedit__terrain {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-4, 4px);
|
||||
height: 34px;
|
||||
padding: 0 var(--spacing-8);
|
||||
border: 1px solid color-mix(in srgb, var(--color-border) 65%, transparent);
|
||||
border-radius: var(--radius-8, 6px);
|
||||
background: color-mix(in srgb, var(--color-surface-raised) 72%, transparent);
|
||||
backdrop-filter: blur(6px);
|
||||
-webkit-backdrop-filter: blur(6px);
|
||||
font-size: 12px;
|
||||
color: var(--color-text-muted, inherit);
|
||||
color: var(--color-text-body);
|
||||
}
|
||||
|
||||
.b05-routeedit__terrain[hidden] {
|
||||
@@ -347,7 +340,7 @@
|
||||
/* ㉔ 잰 값 — 지도 오른쪽 아래 작은 창(뜬 종단 판이 덮으면 가려진 채 · 349-0). 닫으면 잰 것이 지워진다. */
|
||||
.b05-routeedit__measure {
|
||||
position: absolute;
|
||||
right: var(--spacing-12);
|
||||
right: calc(var(--spacing-12) + var(--b05-side-open));
|
||||
bottom: var(--spacing-12);
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
@@ -461,11 +454,3 @@
|
||||
color: var(--color-text-secondary);
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
/* 「거리 재기」가 켜진 동안 — 단추가 눌린 꼴로 남는다(2026-09-12 사용자 지시 ⑥).
|
||||
`is-active` 는 예전에도 붙고 있었으나 꼴이 없어 겉모습이 그대로였다. */
|
||||
.b05-routeedit__actions .ui-btn.is-active {
|
||||
border-color: transparent;
|
||||
background: var(--color-primary, #7c3aed);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@@ -61,6 +61,36 @@ def test_CSS_덮개_걷음_대기막은_전체():
|
||||
assert "@media (width < 1500px)" not in css # 접기는 단추로(처음만 폭으로)
|
||||
|
||||
|
||||
def test_352_1_머리줄_상자_없음_도구는_뜬_단추_횡단은_우측_덮개():
|
||||
chrome = _read("B05_Profile_UI_RouteEdit_Chrome.ts")
|
||||
for gone in ("b05-routeedit__box", "b05-routeedit__head", "b05-routeedit__actions", "<h3>"):
|
||||
assert gone not in chrome
|
||||
# 도구줄 = 3D 와 같은 떠 있는 유리 단추 · 구분선도 3D 것
|
||||
assert 'class="b05-route__view-controls b05-routeedit__tools"' in chrome
|
||||
assert "ui-btn--ghost" not in chrome.split("<aside", 1)[0]
|
||||
# 도구줄은 지도 칸 안 · [?] 는 도구줄 뒤
|
||||
wrap = chrome.index("b05-routeedit__canvas-wrap")
|
||||
assert wrap < chrome.index("b05-routeedit__tools") < chrome.index("b05-routeedit__hint")
|
||||
assert chrome.index("b05-routeedit__side-wrap") > chrome.index("b05-routeedit__busy")
|
||||
css = _read("B05_Profile_UI_Style_RouteEdit.css")
|
||||
for gone in (".b05-routeedit__box", ".b05-routeedit__head", ".b05-routeedit__actions"):
|
||||
assert gone not in css
|
||||
root = _block(css, ".b05-routeedit")
|
||||
assert "padding" not in root and "gap" not in root
|
||||
side = _block(css, ".b05-routeedit__side-wrap")
|
||||
assert "position: absolute;" in side and "right: var(--spacing-12);" in side
|
||||
z = int(re.search(r"z-index: (\d+);", side).group(1))
|
||||
assert z < 3 # 아래 종단 판(z 3)이 위
|
||||
style = _read("B05_Profile_UI_Style.css")
|
||||
assert "z-index: 3;" in _block(style, ".b05-route-profile")
|
||||
# 회전 단추 · 잰 값 창은 펴진 횡단 판을 비킴
|
||||
assert "var(--b05-side-top)" in _block(css, ".b05-routeedit__spin")
|
||||
assert "var(--b05-side-open)" in _block(css, ".b05-routeedit__measure")
|
||||
assert "is-side-open" in chrome
|
||||
glass = _block(css, ".b05-routeedit__terrain")
|
||||
assert "backdrop-filter: blur(6px);" in glass and "background:" in glass
|
||||
|
||||
|
||||
def test_페이지_수명_닫기_없음():
|
||||
main = _read("B05_Profile_UI_RouteEdit.ts")
|
||||
assert "openModal" not in main and "Escape" not in main
|
||||
|
||||
@@ -210,9 +210,9 @@ def test_노선_추천_다듬기_23_3():
|
||||
chrome = read("B05_Profile_UI_RouteEdit_Chrome.ts")
|
||||
# 345-4 — [노선 추천]은 좌측 칸 · 머리 구분선은 [3D](tools) 뒤 · 되돌리기 앞 둘 그대로
|
||||
tools = chrome.index('data-slot="tools"')
|
||||
divider = chrome.index("b05-routeedit__divider", tools)
|
||||
divider = chrome.index("b05-route__view-separator", tools) # 352-1 — 3D 도구줄 구분선 그대로
|
||||
assert tools < divider < chrome.index('data-act="contour-minor"')
|
||||
assert chrome.count("b05-routeedit__divider") == 2
|
||||
assert chrome.count("b05-route__view-separator") == 2
|
||||
shared = read("B05_Profile_UI_RouteEdit_Recommend_Map.ts")
|
||||
for name in ("bindRouteEditNavigation", "createMapRotation", "fitCanvas", "metricToScreen"):
|
||||
assert f"{name}(" in shared
|
||||
|
||||
Reference in New Issue
Block a user