From 8eff5b61e951126bb9effbf616038300c235db2c Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sat, 10 Oct 2026 14:35:29 +0900 Subject: [PATCH] =?UTF-8?q?style(B05):=20=EA=B5=AC=EC=A1=B0=EB=AC=BC=20?= =?UTF-8?q?=EB=B0=B0=EC=B9=98=20=EB=A7=A8=20=EC=95=84=EB=9E=98=20[?= =?UTF-8?q?=EC=B6=94=EA=B0=80]=C2=B7[=EC=82=AD=EC=A0=9C]=C2=B7[=EB=A6=AC?= =?UTF-8?q?=EC=85=8B]=20=EC=A4=84=20=EB=86=92=EC=9D=B4=20=3D=20=EC=83=81?= =?UTF-8?q?=EC=9E=90=20=EC=95=88=20=EB=8B=A8=EC=B6=94=20=C2=B7=20=EB=8A=98?= =?UTF-8?q?=20=EB=B3=B4=EC=9E=84(205-1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 단추 높이 33 → 26(--b05-control-h) · 스크롤 영역 아래 끝에 붙음 - test_205_1 신규 Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_015sDZSjFvoiDjdGpgj3muc3 --- .../B05_Profile_UI_Style_Structures.css | 20 +++++++- .../test_205_1_structure_actions_height.py | 50 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 resources/tester/test_205_1_structure_actions_height.py diff --git a/B05_Profile/B05_Profile_UI_Style_Structures.css b/B05_Profile/B05_Profile_UI_Style_Structures.css index d8fcc2277..ed8512694 100644 --- a/B05_Profile/B05_Profile_UI_Style_Structures.css +++ b/B05_Profile/B05_Profile_UI_Style_Structures.css @@ -569,7 +569,7 @@ } /* 상자 안 작은 단추 템플릿(54-41) — 높이 = 숫자 칸 [-][+](`--b05-control-h`) · 글 · 안 여백도 그 높이에 · - * 상자 이름표 [삭제]도 같은 틀(136-3) · 상자 밖 [추가] · [삭제] · [리셋]은 제외 */ + * 상자 이름표 [삭제]도 같은 틀(136-3) · 상자 밖 [추가] · [삭제] · [리셋]은 아래 205-1 */ .b05-structure__group-body button:not(.b05-structure__step), .b05-structure__group > legend > button { box-sizing: border-box; @@ -580,6 +580,24 @@ line-height: 1; } +/* 「구조물 배치」 맨 아래 [추가] · [삭제] · [리셋] 줄(205-1) — 단추 높이 = 상자 안 작은 단추(`--b05-control-h`) · + * 폼이 길어도 스크롤 영역 아래 끝에 붙어 늘 보임(자리 고정 · 뒤 내용이 비치지 않게 불투명 배경) */ +.b05-structure-section .b05-route__irregular-actions { + position: sticky; + bottom: 0; + z-index: 1; + background: var(--color-surface-raised); +} + +.b05-structure-section .b05-route__irregular-actions > button { + box-sizing: border-box; + height: var(--b05-control-h); + min-height: 0; + padding-block: 0; + font-size: var(--text-caption); + line-height: 1; +} + /* 노면공 「확폭 구간」 상자(PLAN 87-3) — 구간마다 단추 한 줄 */ .b05-structure__widening[hidden] { display: none; diff --git a/resources/tester/test_205_1_structure_actions_height.py b/resources/tester/test_205_1_structure_actions_height.py new file mode 100644 index 000000000..9d3ae79b4 --- /dev/null +++ b/resources/tester/test_205_1_structure_actions_height.py @@ -0,0 +1,50 @@ +"""205-1 「구조물 배치」 맨 아래 [추가] · [삭제] · [리셋] 줄 — 단추 높이 = 상자 안 작은 단추 · 늘 보임. + +- 높이 = `--b05-control-h`(상자 안 단추 · 입력 칸과 같은 값) · 상자 이름표 [삭제]와 같은 높이 식 +- 줄 = 스크롤 영역 아래 끝에 붙음(sticky · bottom 0) · 단추 · 줄에 hidden · display none · visibility · + 호버 조건이 없음 +""" + +import re +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] +CSS = (ROOT / "B05_Profile/B05_Profile_UI_Style_Structures.css").read_text(encoding="utf-8") +FORM = (ROOT / "B05_Profile/B05_Profile_UI_Structures_Form.ts").read_text(encoding="utf-8") +SECTION = ".b05-structure-section .b05-route__irregular-actions" + + +def _block(selector: str) -> str: + m = re.search(r"(?m)^" + re.escape(selector) + r"\s*\{([^}]*)\}", CSS) + assert m, selector + return m.group(1) + + +def _decl(block: str, prop: str) -> str: + m = re.search(r"(?:^|;|\s)" + re.escape(prop) + r"\s*:\s*([^;]+);", block) + assert m, prop + return m.group(1).strip() + + +def test_buttons_same_height_as_inner_buttons(): + outer = _block(SECTION + " > button") + inner = re.search(r"\.b05-structure__group > legend > button\s*\{([^}]*)\}", CSS).group(1) + assert _decl(outer, "height") == "var(--b05-control-h)" + for prop in ("height", "box-sizing", "padding-block", "font-size", "line-height"): + assert _decl(outer, prop) == _decl(inner, prop), prop + assert re.search(r"--b05-control-h:\s*26px;", CSS) + + +def test_row_always_visible(): + row = _block(SECTION) + assert _decl(row, "position") == "sticky" + assert _decl(row, "bottom") == "0" + assert "background" in row + for text in (_block(SECTION), _block(SECTION + " > button")): + assert not re.search(r"display\s*:\s*none|visibility|opacity|overflow", text) + assert not re.search(re.escape(SECTION) + r"[^{]*(:hover|:focus-within|\[hidden\])", CSS) + + +def test_form_never_hides_buttons(): + assert "removeButton.hidden" not in FORM and "resetButton.hidden" not in FORM + assert "actions.hidden" not in FORM