feat(지도 도구줄): 좁으면 한 줄 가로 밀기 · 넘친 쪽 끝 흐림 · 휠 가로 밀기 · D03 도구줄이 겹 단추줄을 안 덮음 (PLAN 571-1 · 요구 399)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
|||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 도구줄 — 지도 왼쪽 위(공용 `ui-map-tools` · 넘치면 줄바꿈 · 빈 자리는 지도 조작 통과) · [?] 안내 판은 그 아래. */
|
/* 도구줄 — 지도 왼쪽 위(공용 `ui-map-tools` · 넘치면 가로 밀기 · 빈 자리는 지도 조작 통과) · [?] 안내 판은 그 아래. */
|
||||||
.b05-routeedit__tools {
|
.b05-routeedit__tools {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|||||||
@@ -25,10 +25,13 @@
|
|||||||
touch-action: none;
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 571-1 — 왼쪽은 겹 단추줄(222px) 오른쪽까지 · 그 사이가 모자라면 도구줄이 가로 밀림 · 오른쪽 붙임 그대로 */
|
||||||
.d03-plan__tools {
|
.d03-plan__tools {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: var(--spacing-8);
|
top: var(--spacing-8);
|
||||||
right: var(--spacing-8);
|
right: var(--spacing-8);
|
||||||
|
left: calc(2 * var(--spacing-8) + 222px);
|
||||||
|
align-items: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 569-2 바탕 겹 단추 — 왼쪽 위 · 급경사 범례 — 왼쪽 아래 */
|
/* 569-2 바탕 겹 단추 — 왼쪽 위 · 급경사 범례 — 왼쪽 아래 */
|
||||||
|
|||||||
@@ -79,3 +79,16 @@ def test_켬끔_안내_판():
|
|||||||
assert "display: none;" in hint[: hint.index("}")]
|
assert "display: none;" in hint[: hint.index("}")]
|
||||||
assert "display: grid;" in CSS[CSS.index(".ui-map-tools__hint.is-open {") :]
|
assert "display: grid;" in CSS[CSS.index(".ui-map-tools__hint.is-open {") :]
|
||||||
assert "pointer-events: none;" in CSS # 빈 자리 · 글판은 지도 조작 통과
|
assert "pointer-events: none;" in CSS # 빈 자리 · 글판은 지도 조작 통과
|
||||||
|
|
||||||
|
|
||||||
|
def test_571_1_한_줄_가로_밀기():
|
||||||
|
bar = CSS[CSS.index(".ui-map-tools > .ui-toolbar {") :]
|
||||||
|
bar = bar[: bar.index("}")]
|
||||||
|
assert "flex-wrap: nowrap;" in bar # 줄바꿈 없음
|
||||||
|
assert "overflow-x: auto;" in bar # 밀기 칸
|
||||||
|
assert "scrollbar-width: none;" in bar
|
||||||
|
assert "mask-image" in bar # 넘친 끝 흐림
|
||||||
|
assert ".ui-toolbar.is-more-end" in CSS and ".ui-toolbar.is-more-start" in CSS
|
||||||
|
assert "flex-shrink: 0;" in CSS # 단추가 찌그러지지 않음
|
||||||
|
assert "watchOverflow(bar);" in TS
|
||||||
|
assert '"wheel"' in TS and "passive: false" in TS # 휠 = 가로 밀기
|
||||||
|
|||||||
@@ -10,6 +10,36 @@
|
|||||||
.ui-map-tools > .ui-toolbar {
|
.ui-map-tools > .ui-toolbar {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
|
/* 571-1 — 한 줄 고정 · 모자라면 가로 밀기(막대 숨김) · 넘친 쪽 끝만 흐림 */
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
overflow-x: auto;
|
||||||
|
overscroll-behavior-x: contain;
|
||||||
|
scrollbar-width: none;
|
||||||
|
--map-tools-fade-start: 0px;
|
||||||
|
--map-tools-fade-end: 0px;
|
||||||
|
mask-image: linear-gradient(
|
||||||
|
to right,
|
||||||
|
transparent,
|
||||||
|
var(--color-text-body) var(--map-tools-fade-start),
|
||||||
|
var(--color-text-body) calc(100% - var(--map-tools-fade-end)),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-map-tools > .ui-toolbar::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-map-tools > .ui-toolbar > * {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-map-tools > .ui-toolbar.is-more-start {
|
||||||
|
--map-tools-fade-start: var(--spacing-24);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-map-tools > .ui-toolbar.is-more-end {
|
||||||
|
--map-tools-fade-end: var(--spacing-24);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 안내 판 — 기본 접힘 · 2열 · 글판은 클릭 통과 */
|
/* 안내 판 — 기본 접힘 · 2열 · 글판은 클릭 통과 */
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
* 꼴 = 유리 도구줄(`createToolbar` glass · 32) 한 줄 · 묶음 사이 나눔선 · 단추는 모두 아이콘(마우스 올리면 이름)
|
* 꼴 = 유리 도구줄(`createToolbar` glass · 32) 한 줄 · 묶음 사이 나눔선 · 단추는 모두 아이콘(마우스 올리면 이름)
|
||||||
* [?] 안내 판 = 도구줄 아래 2열 글판(기본 접힘 · 클릭은 지도로 통과)
|
* [?] 안내 판 = 도구줄 아래 2열 글판(기본 접힘 · 클릭은 지도로 통과)
|
||||||
* 크기 = 단 32 하나(지도 위 도구)
|
* 크기 = 단 32 하나(지도 위 도구)
|
||||||
|
* 좁을 때 = 줄바꿈 없이 가로 밀기(터치 · 휠) · 넘친 쪽 끝만 흐림(`is-more-start` · `is-more-end`)
|
||||||
* 상태 = 켬끔 단추는 `aria-pressed`(눌림 꼴) · 막힘 `disabled` · [?] 는 `aria-expanded`
|
* 상태 = 켬끔 단추는 `aria-pressed`(눌림 꼴) · 막힘 `disabled` · [?] 는 `aria-expanded`
|
||||||
* 쓰는 법 = createMapTools({ label: "평면 도구", groups: [["undo", "redo"], ["rotate-ccw", "rotate-cw", "measure"]],
|
* 쓰는 법 = createMapTools({ label: "평면 도구", groups: [["undo", "redo"], ["rotate-ccw", "rotate-cw", "measure"]],
|
||||||
* hint: { lines: ["휠 = 확대"] } }) → { root, bar, hint, button(act) }
|
* hint: { lines: ["휠 = 확대"] } }) → { root, bar, hint, button(act) }
|
||||||
@@ -74,6 +75,29 @@ export interface MapTools {
|
|||||||
button(act: MapToolAct): HTMLButtonElement | null;
|
button(act: MapToolAct): HTMLButtonElement | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 넘침 표시 + 휠을 가로 밀기로 — 도구줄이 넘칠 때만 */
|
||||||
|
function watchOverflow(bar: HTMLElement): void {
|
||||||
|
const mark = (): void => {
|
||||||
|
const max = bar.scrollWidth - bar.clientWidth;
|
||||||
|
bar.classList.toggle("is-more-start", bar.scrollLeft > 1);
|
||||||
|
bar.classList.toggle("is-more-end", max - bar.scrollLeft > 1);
|
||||||
|
};
|
||||||
|
bar.addEventListener("scroll", mark, { passive: true });
|
||||||
|
bar.addEventListener(
|
||||||
|
"wheel",
|
||||||
|
(ev) => {
|
||||||
|
if (bar.scrollWidth <= bar.clientWidth || Math.abs(ev.deltaX) > Math.abs(ev.deltaY)) return;
|
||||||
|
ev.preventDefault();
|
||||||
|
bar.scrollLeft += ev.deltaY;
|
||||||
|
},
|
||||||
|
{ passive: false },
|
||||||
|
);
|
||||||
|
if (typeof ResizeObserver === "undefined") return;
|
||||||
|
const observer = new ResizeObserver(mark);
|
||||||
|
observer.observe(bar);
|
||||||
|
for (const child of Array.from(bar.children)) observer.observe(child);
|
||||||
|
}
|
||||||
|
|
||||||
export function createMapTools(opts: MapToolsOptions): MapTools {
|
export function createMapTools(opts: MapToolsOptions): MapTools {
|
||||||
const root = document.createElement("div");
|
const root = document.createElement("div");
|
||||||
root.className = "ui-map-tools";
|
root.className = "ui-map-tools";
|
||||||
@@ -110,6 +134,7 @@ export function createMapTools(opts: MapToolsOptions): MapTools {
|
|||||||
});
|
});
|
||||||
root.append(bar);
|
root.append(bar);
|
||||||
if (hint) root.append(hint);
|
if (hint) root.append(hint);
|
||||||
|
watchOverflow(bar);
|
||||||
return {
|
return {
|
||||||
root,
|
root,
|
||||||
bar,
|
bar,
|
||||||
|
|||||||
Reference in New Issue
Block a user