From 31ea5a6e083629d6b9051c2e9e65a47504ba7d80 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Thu, 8 Oct 2026 20:03:56 +0900 Subject: [PATCH] =?UTF-8?q?feat(M02):=20=EB=A9=B4=EC=A0=81=EC=82=B0?= =?UTF-8?q?=EC=B6=9C=20=EC=95=84=EB=9E=98=20=EB=A7=89=EB=8C=80=20=EB=8F=84?= =?UTF-8?q?=EB=A9=B4=20=EC=B9=A9=20=3D=20=EB=9D=BC=EC=9A=B4=EB=93=9C=20?= =?UTF-8?q?=EC=82=AC=EA=B0=81=20=C2=B7=20=EA=B0=92=20=EB=A7=9E=EC=9D=8C/?= =?UTF-8?q?=EB=8B=A4=EB=A6=84=20=3D=20=E2=9C=93=20/=20=E2=9C=97(=EB=9C=BB?= =?UTF-8?q?=EC=9D=80=20title)=20=C2=B7=20=EC=95=8C=EC=95=BD=20=C2=B7=20[?= =?UTF-8?q?=EC=97=B0=EA=B2=B0=20=EB=AA=A8=EB=91=90=20=ED=95=B4=EC=A0=9C]?= =?UTF-8?q?=20=EA=B8=80=20=EC=84=B8=EB=A1=9C=20=EA=B0=80=EC=9A=B4=EB=8D=B0?= =?UTF-8?q?(128-2=20=C2=B7=20128-3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7 --- A00_Common/spreadsheet/spreadsheet_links.css | 18 ++++-- .../M02_MasterTemplete_AreaToDrawing.ts | 9 +-- .../tester/test_m02_128_icon_chip_center.py | 59 +++++++++++++++++++ resources/tester/test_m02_area_old_links.py | 6 +- 4 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 resources/tester/test_m02_128_icon_chip_center.py diff --git a/A00_Common/spreadsheet/spreadsheet_links.css b/A00_Common/spreadsheet/spreadsheet_links.css index 3e63d0d85..185a59526 100644 --- a/A00_Common/spreadsheet/spreadsheet_links.css +++ b/A00_Common/spreadsheet/spreadsheet_links.css @@ -10,11 +10,15 @@ background: var(--color-surface); } +/* 글 세로 가운데(128-3) — 막대가 줄 높이로 늘려도 글은 가운데 · 높이 · 줄 높이 고정 */ .ss-link { display: inline-flex; - align-items: baseline; + align-items: center; + box-sizing: border-box; + min-height: 22px; gap: var(--spacing-4); - padding: 2px 10px; + padding: 0 10px; + line-height: 16px; border: 1px solid var(--color-accent); border-radius: 999px; background: var(--color-surface-raised); @@ -279,10 +283,16 @@ cursor: pointer; } -/* 아래 막대 도면 알약(114-3) — 테두리 = 시트 위 그 범위 테두리 색(점선) · 상태는 공용 꼬리표(ui-tag) */ +/* 아래 막대 도면 칩(114-3 · 128-2) — 라운드 사각(입력 알약과 모양으로 가름) · 테두리 = 시트 위 그 범위 + * 테두리 색(점선) · 상태는 공용 꼬리표(ui-tag · ✓ / ✗) — 막대 높이에 맞춰 줄임 */ .ss-link--range { - align-items: center; border: 2px dashed hsl(var(--ss-link-h, 0) var(--ss-link-s) var(--ss-link-l)); + border-radius: calc(var(--radius-buttons) / 2); +} + +.ss-link--range .ui-tag { + padding: 0 6px; + line-height: 16px; } .ss-link-range__tag:hover, diff --git a/M02_MasterTemplete/M02_MasterTemplete_AreaToDrawing.ts b/M02_MasterTemplete/M02_MasterTemplete_AreaToDrawing.ts index ccdd2b03a..ca104a0f5 100644 --- a/M02_MasterTemplete/M02_MasterTemplete_AreaToDrawing.ts +++ b/M02_MasterTemplete/M02_MasterTemplete_AreaToDrawing.ts @@ -90,10 +90,11 @@ const TEXT = { tip: "도면 표 {id} 로 보낸 범위 {range} · 글자 {size}", updated: "표 {n}개를 지금 면적 값으로 바꿈 — [저장]하면 남음", rangeGone: "보낸 범위가 지워져 연결을 끊음 — {ids}(도면 표는 남음)", - same: "값 맞음", - sameTip: "도면 표 칸 글 = 지금 면적 값", - diff: "값 다름", - diffTip: "면적 값이 도면 표와 다름 — 면적 [저장] 때 도면 표를 맞춤", + // 값 맞음 · 다름 = 기호(128-2) · 뜻은 마우스 올림 글 + same: "✓", + sameTip: "값 맞음 — 도면 표 칸 글 = 지금 면적 값", + diff: "✗", + diffTip: "값 다름 — 면적 값이 도면 표와 다름 · 면적 [저장] 때 도면 표를 맞춤", noTable: "도면에 표 없음", noTableTip: "도면(저장본)에 이 연결 표가 없음 — × 로 보내기 취소", gone: "범위 없음", diff --git a/resources/tester/test_m02_128_icon_chip_center.py b/resources/tester/test_m02_128_icon_chip_center.py new file mode 100644 index 000000000..1606e2029 --- /dev/null +++ b/resources/tester/test_m02_128_icon_chip_center.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +"""128 — 구조물 조합 다이어그램 아이콘 단추 · 면적산출 아래 막대 도면 칩(✓ / ✗) · 알약 글 세로 가운데(원문 · CSS 단언).""" + +import os +import re + +HERE = os.path.dirname(os.path.abspath(__file__)) +ROOT = os.path.join(HERE, "..", "..") + + +def _read(*parts: str) -> str: + with open(os.path.join(ROOT, *parts), encoding="utf-8") as f: + return f.read() + + +def _block(css: str, selector: str) -> str: + return css.split(f"\n{selector} {{", 1)[1].split("}", 1)[0] + + +def test_다이어그램_작게_크게_한눈에_아이콘_단추_128_1(): + src = _read("M02_MasterTemplete", "M02_MasterTemplete_Labor_Diagram.ts") + # 공용 단추 + 기호 · 글은 title · aria-label + assert 'createButton({ label: glyph, variant: "ghost", size: "sm", onClick })' in src + assert "b.title = td(key);" in src and 'b.setAttribute("aria-label", td(key));' in src + assert 'icon("−", "Zoom_Out"' in src + assert 'icon("+", "Zoom_In"' in src + assert 'icon("⤢", "Fit"' in src + # 글 단추로 남은 것 없음 + assert 'label: td("Zoom_' not in src and 'label: td("Fit")' not in src + css = _read("M02_MasterTemplete", "M02_MasterTemplete_Labor_Diagram.css") + assert "min-width" in _block(css, ".m02-labordg__icon") + + +def test_도면_칩_라운드_사각_값_맞음_다름_기호_128_2(): + src = _read("M02_MasterTemplete", "M02_MasterTemplete_AreaToDrawing.ts") + assert 'same: "✓"' in src and 'diff: "✗"' in src + # 뜻은 마우스 올림 글(설명 → 꼬리표 title) + assert re.search(r'sameTip: "값 맞음 — ', src) and re.search(r'diffTip: "값 다름 — ', src) + assert 'noTable: "도면에 표 없음"' in src and 'gone: "범위 없음"' in src # 막힘은 글 그대로 + rng = _read("A00_Common", "spreadsheet", "spreadsheet_link_range.ts") + assert "if (tag && state?.설명) tag.title = state.설명;" in rng + css = _read("A00_Common", "spreadsheet", "spreadsheet_links.css") + chip = _block(css, ".ss-link--range") + assert "border-radius: calc(var(--radius-buttons) / 2)" in chip # 알약(999px)과 다른 모양 + assert "999px" in _block(css, ".ss-link") # 입력 알약은 그대로 + assert "line-height: 16px" in _block(css, ".ss-link--range .ui-tag") + + +def test_알약_연결_모두_해제_글_세로_가운데_128_3(): + css = _read("A00_Common", "spreadsheet", "spreadsheet_links.css") + pill = _block(css, ".ss-link") + assert "align-items: center" in pill and "baseline" not in pill + assert "min-height: 22px" in pill and "line-height: 16px" in pill + assert "box-sizing: border-box" in pill + # [연결 모두 해제] · [+ 자재 추가] 는 .ss-link 를 이어받음 — 따로 세로 맞춤을 덮지 않음 + for sel in (".ss-link--clear", ".ss-link--add"): + assert "align-items" not in _block(css, sel) and "line-height" not in _block(css, sel) + links = _read("A00_Common", "spreadsheet", "spreadsheet_links.ts") + assert 'className: "ss-link ss-link--clear"' in links diff --git a/resources/tester/test_m02_area_old_links.py b/resources/tester/test_m02_area_old_links.py index 1473d69d1..f07b77eca 100644 --- a/resources/tester/test_m02_area_old_links.py +++ b/resources/tester/test_m02_area_old_links.py @@ -268,14 +268,14 @@ def test_아래_막대_도면_알약_상태_누르면_고름_x_는_보내기_취 } out = _node({"book": book, "drawing": {"연결표": []}, "drawing3": drawing3, "book3": book}) assert out["states"]["first"] == [ - ["값 맞음", "success"], + ["✓", "success"], # 값 맞음 · 다름 = 기호(128-2) ["도면에 표 없음", "danger"], ["범위 없음", "danger"], ] - assert out["states"]["edited"] == ["값 다름"] # 저장 전 칸 고침 = 지금 책으로 판정 + assert out["states"]["edited"] == ["✗"] # 저장 전 칸 고침 = 지금 책으로 판정 p = out["pills"] assert [x["text"] for x in p["made"]] == ["T1 도면 A1:B2", "T2 도면 B1", "T3 도면"] - assert p["made"][0]["tag"] == ["ui-tag ui-tag--success", "값 맞음"] # 공용 꼬리표 + assert p["made"][0]["tag"] == ["ui-tag ui-tag--success", "✓"] # 공용 꼬리표 assert p["made"][1]["tag"] == ["ui-tag ui-tag--danger", "도면에 표 없음"] assert all(x["x"] and x["cls"] == "ss-link ss-link--range" for x in p["made"]) assert all(x["hue"] == "string" for x in p["made"]) # 색 = 시트 위 테두리 색