feat(B06): 구조물 선택 = 카드 선택·면적 강조와 같은 레벨, 붉은 강조
- 강조 색을 --color-danger(붉은색)로 변경. - 구조물을 고르면 그 측점 카드도 같이 선택된다. 이미 선택된 카드 안에서 다른 구조물을 고를 때는 강조만 옮겨 가고 카드 선택은 건드리지 않는다. - 구조물 선택과 절·성토 면적 강조는 같은 레벨 — 하나를 고르면 다른 하나가 풀린다. 카드가 선택에서 빠져도 구조물 선택은 풀린다. - 조정 버튼이 안 보이던 원인: .b06-cross-card__revetctl 스타일과 .is-hidden 규칙이 아예 없었다. 스타일을 넣고 "기슭막이" 라벨을 붙여 표시 반폭 그룹과 구분했다. 미선택 카드에서 구조물이 먹히지 않던 버그도 잡았다 — 면적 비우기(onAreaSelect)가 먼저 카드를 선택해 버려, 뒤이은 onSelect가 "같은 측점 재클릭 = 해제"로 상쇄됐다. 검증(공용 브라우저 4+4.3): 미선택 카드에서 구조물 클릭 → 벽 강조 + 화살표 + 카드 선택. 같은 카드 다른 구조물 → 강조만 이동. 면적칩 → 구조물 해제. 다시 구조물 → 면적 해제. tsc 통과, pytest 148 pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -211,8 +211,14 @@ export function createCrossSectionCard(
|
||||
let activeRevet: RevetKey | null = revetOffset?.selectedFor(section) ?? null;
|
||||
let setRevetActive: RevetHighlightSetter = () => undefined;
|
||||
let showRevetControl: (visible: boolean) => void = () => undefined;
|
||||
/** 기슭막이를 고르면 면적 강조는 끈다 — **구조물 선택이 우선**(2026-08-21 사용자 ①). */
|
||||
/**
|
||||
* 기슭막이를 고른다. 구조물 선택과 절·성토 면적 강조는 **같은 레벨**이라 하나를
|
||||
* 고르면 다른 하나는 풀린다(2026-08-21 사용자). 또 구조물을 고르면 그 **측점 카드도
|
||||
* 같이 선택**된다 — 이미 선택된 카드 안에서 다른 구조물을 고를 때는 선택이 옮겨만
|
||||
* 가고 카드 선택은 건드리지 않는다.
|
||||
*/
|
||||
const toggleRevet = (key: RevetKey): void => {
|
||||
const wasSelected = isSelected;
|
||||
activeRevet = activeRevet === key ? null : key;
|
||||
setRevetActive(activeRevet);
|
||||
showRevetControl(activeRevet !== null);
|
||||
@@ -221,7 +227,14 @@ export function createCrossSectionCard(
|
||||
activeArea = null;
|
||||
setBandActive(null);
|
||||
setChipActive(null);
|
||||
onAreaSelect?.(section.station_id, null);
|
||||
}
|
||||
if (activeRevet !== null) {
|
||||
// 미선택 카드는 **카드 선택만** 부른다. 여기서 면적 비우기(onAreaSelect)를 먼저
|
||||
// 부르면 그쪽이 카드를 선택해 버려, 뒤이은 onSelect가 "같은 측점 재클릭 = 해제"로
|
||||
// 먹혀 아무 일도 일어나지 않는다(2026-08-21 화면 확인). 카드 선택 경로가 부모의
|
||||
// 면적 강조를 이미 비운다.
|
||||
if (wasSelected) onAreaSelect?.(section.station_id, null);
|
||||
else onSelect(section.station_id);
|
||||
}
|
||||
};
|
||||
card.applySelection = (nextSelected, areaKey) => {
|
||||
@@ -230,6 +243,13 @@ export function createCrossSectionCard(
|
||||
activeArea = nextSelected ? (areaKey ?? null) : null;
|
||||
setBandActive(activeArea);
|
||||
setChipActive(activeArea);
|
||||
// 면적이 켜졌거나 카드가 선택에서 빠지면 구조물 선택은 풀린다(같은 레벨).
|
||||
if ((activeArea !== null || !nextSelected) && activeRevet !== null) {
|
||||
activeRevet = null;
|
||||
setRevetActive(null);
|
||||
showRevetControl(false);
|
||||
revetOffset?.select(section.chainage_m, null);
|
||||
}
|
||||
};
|
||||
const toggleArea = (key: CrossAreaKey): void => {
|
||||
if (!isSelected) {
|
||||
@@ -613,7 +633,11 @@ export function createCrossSectionCard(
|
||||
revetOffset.adjust(section.chainage_m, activeRevet, screenDeltaM * outwardOf(activeRevet));
|
||||
}
|
||||
};
|
||||
const revetLabel = document.createElement("span");
|
||||
revetLabel.className = "b06-cross-card__revetctl-label";
|
||||
revetLabel.textContent = L("B06_Cross_Revet_Label");
|
||||
revetControl.append(
|
||||
revetLabel,
|
||||
makeButton("◀", L("B06_Cross_Revet_Left"), nudge(0.1)),
|
||||
makeButton("▶", L("B06_Cross_Revet_Right"), nudge(-0.1)),
|
||||
makeButton("↺", L("B06_Cross_Revet_Reset"), () => {
|
||||
|
||||
@@ -563,6 +563,26 @@
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
/* 기슭막이 X 자리 ◀/▶/↺(2026-08-21) — 벽을 골랐을 때만 보인다. 표시 반폭 그룹과
|
||||
나란히 서므로 어느 쪽 조작구인지 라벨로 가른다. */
|
||||
.b06-cross-card__revetctl {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
margin-left: var(--spacing-8);
|
||||
}
|
||||
|
||||
.b06-cross-card__revetctl.is-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.b06-cross-card__revetctl-label {
|
||||
color: var(--color-danger);
|
||||
font-size: var(--text-caption);
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
/* 줌 버튼 — 그래프 우측 상단 오버레이. 휠 대신 쓰는 조작구다(2026-08-02 사용자 확정). */
|
||||
.b06-cross-card__zoom {
|
||||
position: absolute;
|
||||
|
||||
@@ -193,8 +193,8 @@
|
||||
}
|
||||
|
||||
.b06-chart__culvert-revet.is-active {
|
||||
fill: color-mix(in srgb, var(--color-royal-amethyst) 45%, transparent);
|
||||
stroke: var(--color-royal-amethyst);
|
||||
fill: color-mix(in srgb, var(--color-danger) 45%, transparent);
|
||||
stroke: var(--color-danger);
|
||||
stroke-width: 2.2;
|
||||
}
|
||||
|
||||
|
||||
@@ -239,6 +239,7 @@ export const ui_locales_b2 = {
|
||||
"기슭막이 선택 — 화살표로 자리 조절",
|
||||
"Select revetment — nudge with arrows",
|
||||
],
|
||||
B06_Cross_Revet_Label: ["기슭막이", "Revetment"],
|
||||
B06_Cross_Revet_Left: ["기슭막이 0.1m 왼쪽으로", "Move revetment 0.1m left"],
|
||||
B06_Cross_Revet_Right: ["기슭막이 0.1m 오른쪽으로", "Move revetment 0.1m right"],
|
||||
B06_Cross_Revet_Reset: ["기슭막이 자동 자리로 초기화", "Reset revetment to solved position"],
|
||||
|
||||
Reference in New Issue
Block a user