From 815aa464cc5de10bda92eaae727a433b8a8f55cc Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 26 Oct 2026 22:46:03 +0900 Subject: [PATCH] =?UTF-8?q?fix(cad):=20=EB=B6=80=ED=92=88=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=20=EB=B3=B4=EA=B0=95=20=E2=80=94=20DOM=20=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EC=8B=9C=ED=97=98=EC=97=90=EC=84=A0=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=20=EA=BC=B4=20=EC=A3=BC=EC=9E=85=20=EA=B1=B4=EB=84=88?= =?UTF-8?q?=EB=9C=80=20=C2=B7=20=EB=AA=A9=EB=A1=9D=20=EC=A4=84=20CSS=20?= =?UTF-8?q?=EC=8B=A4=EC=9D=8C=20=C2=B7=20=EB=B8=94=EB=A1=9D=20=ED=8C=90=20?= =?UTF-8?q?=EB=8B=A8=EC=B6=94=20=EC=A4=84=20=EB=84=98=EA=B9=80=20=C2=B7=20?= =?UTF-8?q?=EC=A7=80=ED=82=B4=20=EC=8B=9C=ED=97=98=20(PLAN=20553-6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - integration/ui-kit.ts: document 없을 때 injectBaseStyles 안 부름(vitest ime-sink 깨짐) · ui_template_list_row.css 실음(블록 이름 줄 = ui-sidebar-row) - 블록 라이브러리 [파일로 내보내기] [파일에서 가져오기] = 글 12 로 한 줄에 둘이 안 들어가 줄을 넘김(글 자르지 않음) - resources/tester/test_553_6_cad_parts.py: 부품 클래스 · 확인창(window.confirm · prompt 0) · 부품 CSS 먼저 · 날 색 · 보라 별칭 · 옛 자체 단추 규칙 없음 Co-Authored-By: Claude Opus 5.5 --- .../openwebcad/src/App_Layers.css | 6 +- .../openwebcad/src/integration/ui-kit.ts | 6 +- resources/tester/test_553_6_cad_parts.py | 73 +++++++++++++++++++ 3 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 resources/tester/test_553_6_cad_parts.py diff --git a/B07_DesignDetail/openwebcad/src/App_Layers.css b/B07_DesignDetail/openwebcad/src/App_Layers.css index 040234e55..fabf5e440 100644 --- a/B07_DesignDetail/openwebcad/src/App_Layers.css +++ b/B07_DesignDetail/openwebcad/src/App_Layers.css @@ -283,14 +283,16 @@ body.cad-file-dragging::after { text-overflow: ellipsis; white-space: nowrap; } -/* 단추 = 단추 부품(보조 · 단 24) · 여기는 둘이 폭을 나눔만 */ +/* 단추 = 단추 부품(보조 · 단 24) · 여기는 폭 나눔만 — 글 12 로 한 줄에 둘이 안 들어가면 줄을 넘김 */ .cad-block-library__actions { display: flex; + flex-wrap: wrap; gap: 6px; margin-top: 8px; } .cad-block-library__actions > .ui-btn { - flex: 1; + flex: 1 1 auto; + white-space: nowrap; } /* 도각 자리표 패널 — 도각 편집으로 도면을 실었을 때만 뜬다 (2026-09-06 사용자 지시로 diff --git a/B07_DesignDetail/openwebcad/src/integration/ui-kit.ts b/B07_DesignDetail/openwebcad/src/integration/ui-kit.ts index 1cdc55074..d5d68ee64 100644 --- a/B07_DesignDetail/openwebcad/src/integration/ui-kit.ts +++ b/B07_DesignDetail/openwebcad/src/integration/ui-kit.ts @@ -1,7 +1,7 @@ /** * 부품 상자(`ui_template/`) CAD 쪽 한 벌(553-6) — CAD 겉도 앱 화면과 같은 부품 꼴을 씀. * 부품 CSS 를 싣고 단추 · 확인창 기본 꼴(`injectBaseStyles`)을 한 번 넣음 · 확인창 · 글 묻기를 다시 냄. - * React 화면은 부품 클래스(`ui-btn` · `ui-icon-btn` · `ui-toggle--chip` · `ui-tabs` · `ui-float-panel` · `ui-ctx-menu` · `ui-empty` · `ui-text` · `ui-input`)와 + * React 화면은 부품 클래스(`ui-btn` · `ui-icon-btn` · `ui-toggle--chip` · `ui-tabs` · `ui-float-panel` · `ui-ctx-menu` · `ui-empty` · `ui-text` · `ui-input` · `ui-sidebar-row`)와 * `data-size` 단을 직접 붙임 · 자리 · 폭은 App.css 의 `cad-*` 가 맡음 · 도면 그림 색(`--draw-*`)은 안 건드림. */ import '../../../../ui_template/ui_template_tabs.css'; @@ -11,8 +11,10 @@ import '../../../../ui_template/ui_template_context_menu.css'; import '../../../../ui_template/ui_template_empty.css'; import '../../../../ui_template/ui_template_input.css'; import '../../../../ui_template/ui_template_text.css'; +import '../../../../ui_template/ui_template_list_row.css'; import { injectBaseStyles } from '../../../../ui_template/ui_template_elements_styles.ts'; export { askConfirm, askText } from '../../../../ui_template/ui_template_modal.ts'; -injectBaseStyles(); +// DOM 없는 시험(vitest node)에선 건너뜀 +if (typeof document !== 'undefined') injectBaseStyles(); diff --git a/resources/tester/test_553_6_cad_parts.py b/resources/tester/test_553_6_cad_parts.py new file mode 100644 index 000000000..9c6b62f53 --- /dev/null +++ b/resources/tester/test_553_6_cad_parts.py @@ -0,0 +1,73 @@ +"""553-6 CAD 앱 겉 = 부품 상자 부품 — 화면 없이 소스로 지킴. + +상태막대 켜기 칩 · 특성/레이어 탭 · 떠 있는 판 · 메뉴 · 아이콘 단추 · 확인창(window.confirm · prompt 없음) · +부품 CSS 를 앱 CSS 보다 먼저 실음 · 옛 자체 단추 규칙 · 보라 별칭 · 날 색 없음 · 도면 바탕 = --draw-canvas. +""" + +import re +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] +CAD = ROOT / "B07_DesignDetail" / "openwebcad" / "src" + + +def _t(rel: str) -> str: + return (CAD / rel).read_text("utf-8") + + +def test_parts_markup(): + status = _t("components/StatusBar.tsx") + assert status.count('className="ui-toggle ui-toggle--chip"') == 6 + assert 'data-size="22"' in status and "aria-pressed=" in status + inspector = _t("components/InspectorPanel.tsx") + assert '"ui-tabs cad-inspector-tabs"' in inspector and inspector.count("ui-tabs__tab") == 2 + for rel in ( + "components/QuickProperties.tsx", + "components/BlockLibraryPanel.tsx", + "components/FramePlaceholderPanel.tsx", + ): + src = _t(rel) + assert ( + "ui-float-panel" in src + and "ui-float-panel__head" in src + and "ui-float-panel__body" in src + ), rel + assert "ui-ctx-menu cad-ribbon-overflow" in _t("ribbon/Ribbon.tsx") + assert "ui-ctx-menu cad-command-suggestions" in _t("components/CommandLine.tsx") + assert "ui-ctx-menu cad-snap-menu" in _t("inputController/snap-menu.ts") + assert _t("components/ViewControls.tsx").count("{...ICON_BUTTON}") == 5 + assert "ui-icon-btn" in _t("components/QuickAccessBar.tsx") + assert "h-[42px]" in _t("components/Button.tsx") + + +def test_no_system_dialogs(): + for path in CAD.rglob("*.ts*"): + if ".test." in path.name: + continue + src = path.read_text("utf-8") + assert "window.confirm(" not in src and "window.prompt(" not in src, path.name + assert "askConfirm" in _t("components/BlockLibraryPanel.tsx") + assert "askText" in _t("commands/commands.insert.ts") + + +def test_kit_loaded_before_app_css(): + kit = _t("integration/ui-kit.ts") + assert "if (typeof document !== 'undefined') injectBaseStyles();" in kit + main = _t("main.tsx") + assert main.index("./integration/ui-kit.ts") < main.index("import App from './App.tsx'") + + +def test_css_tokens_only(): + css = _t("App.css") + _t("App_Layers.css") + _t("inputController/snap-menu.css") + assert "--cad-canvas: var(--draw-canvas);" in css + assert "mist-violet" not in css + assert not re.search(r"#[0-9a-fA-F]{3,6}\b", css) + # 옛 자체 단추 규칙은 부품이 대신함 + for gone in ( + ".cad-statusbar button", + ".cad-view-controls button", + ".cad-quick-properties__header", + ".cad-frame-tokens__button", + ".cad-inspector-tabs button", + ): + assert gone not in css, gone