feat(B05): 선택 상자 [빼기] → [삭제] · 이름표 단추 작은 단추 틀(136-3)

- 공용 명세 폼 이름표 단추 글 「삭제」 + title(관 · BOX · 세월교 · 물넘이 · 노면공 상세 · M02 미리보기)
- 이름표 단추도 「구조물 조합」 [선택]과 같은 작은 단추 틀 · 흐림은 이름표 글에만
- 시험: test_136_3_remove_button 새로 · helper_54_10 에 이름표 단추 결과

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015sDZSjFvoiDjdGpgj3muc3
This commit is contained in:
2026-10-09 14:52:56 +09:00
co-authored by Claude Opus 5.5
parent b66dce4313
commit f8b38d828b
4 changed files with 57 additions and 4 deletions
+2 -1
View File
@@ -269,7 +269,8 @@ export function createSpecForm(links: SpecLinks | null, hooks: SpecFormHooks = {
const remove = document.createElement("button");
remove.type = "button";
remove.className = "b05-route__irregular-btn";
remove.textContent = "빼기";
remove.textContent = "삭제";
remove.title = `${c.title} 상자 삭제`;
remove.dataset.specRemove = c.id;
remove.addEventListener("click", () => {
const list = state[c.id];
@@ -168,7 +168,8 @@
.b05-structure__group > legend {
padding: 0 4px;
font-size: 11px;
opacity: 0.8;
/* 흐림은 이름표 글에만 — 안 [삭제] 단추는 제 색(136-3) */
color: color-mix(in srgb, currentColor 80%, transparent);
}
.b05-structure__group-body {
@@ -561,8 +562,9 @@
}
/* 상자 안 작은 단추 템플릿(54-41) — 높이 = 숫자 칸 [-][+](`--b05-control-h`) · 글 · 안 여백도 그 높이에 ·
* 상자 이름표 [빼기] · 상자 밖 [추가] · [삭제] · [리셋]은 제외 */
.b05-structure__group-body button:not(.b05-structure__step) {
* 상자 이름표 [삭제]도 같은 틀(136-3) · 상자 밖 [추가] · [삭제] · [리셋]은 제외 */
.b05-structure__group-body button:not(.b05-structure__step),
.b05-structure__group > legend > button {
box-sizing: border-box;
height: var(--b05-control-h);
min-height: 0;
@@ -200,7 +200,13 @@ form.write(PIPE_SPEC, {
soil_add_1_form: "콘크리트",
soil_add_2_form: "돌망태",
soil_add_2_height: 1.5,
chute_add_1_structure: "돌붙임",
});
// 상자 이름표 단추(136-3) — 글 「삭제」 + title
out.remove = form.root
.querySelectorAll("button")
.filter((b) => b.dataset.specRemove)
.map((b) => ({ id: b.dataset.specRemove, text: b.textContent, title: b.title }));
const boxes = () =>
form.root.children.filter((k) => k.dataset?.specContainer === "soil_add").length;
const soilKeys = () =>
@@ -0,0 +1,44 @@
"""136-3 상자 이름표 [빼기] → [삭제] · 「구조물 조합」 [선택]과 같은 작은 단추 틀 ·
흐림은 이름표 글에만.
공용 명세 폼(`design_structure_form.ts`)을 그 자리에서 돌린 값
(`helper_54_10_soil_tiers.cjs` 의 `remove`) + CSS 규칙(`B05_Profile_UI_Style_Structures.css`).
"""
import json
import subprocess
from pathlib import Path
import pytest
HERE = Path(__file__).parent
ROOT = HERE.parents[1]
CSS = (ROOT / "B05_Profile" / "B05_Profile_UI_Style_Structures.css").read_text(encoding="utf-8")
def _rule(selector: str) -> str:
"""선택자부터 그 규칙 끝(`}`)까지."""
at = CSS.index(selector)
return CSS[at : CSS.index("}", at)]
@pytest.mark.skipif(not (ROOT / "config" / "node_modules").is_dir(), reason="의존성 미설치")
def test_이름표_단추_글은_삭제():
done = subprocess.run( # noqa: S603 — 고정 실행 파일
["node", str(HERE / "helper_54_10_soil_tiers.cjs")],
capture_output=True,
text=True,
encoding="utf-8",
)
assert done.returncode == 0, done.stderr
remove = json.loads(done.stdout)["remove"]
assert {"id": "chute_add", "text": "삭제", "title": "도수로/돌붙임 상자 삭제"} in remove
assert all(b["text"] == "삭제" for b in remove)
def test_이름표_단추는_작은_단추_틀_흐림은_글에만():
small = _rule(".b05-structure__group > legend > button")
assert ".b05-structure__group-body button:not(.b05-structure__step)" in CSS
assert "height: var(--b05-control-h)" in small and "padding-block: 0" in small
legend = _rule(".b05-structure__group > legend {")
assert "opacity" not in legend and "currentColor 80%" in legend