fix(b08,b09): 보조 탭 단추 높이 한 꼴 — 공용 토큰 24px · 공용 보조 탭 줄 양식 · 도구는 줄 높이 안 바꿈 (279)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD
This commit is contained in:
2026-10-12 18:58:56 +09:00
co-authored by Claude Opus 5.5
parent fa5fa3bff9
commit bb6ae4faf5
9 changed files with 87 additions and 8 deletions
+1 -1
View File
@@ -287,7 +287,7 @@ export async function renderEarthwork(host: HTMLElement, projectId: string): Pro
applyRock();
const tabs = document.createElement("div");
tabs.className = "b08-quantity__tabs b08-earthwork__tabs";
tabs.className = "b08-quantity__tabs ui-subtabs b08-earthwork__tabs";
tabs.setAttribute("role", "tablist");
const view = document.createElement("div");
let current: SheetId = "summary";
+1 -1
View File
@@ -110,7 +110,7 @@ export async function renderHydro(host: HTMLElement, projectId: string): Promise
) as unknown as HydroInputs;
const tabs = document.createElement("div");
tabs.className = "b08-quantity__tabs b08-hydro__tabs";
tabs.className = "b08-quantity__tabs ui-subtabs b08-hydro__tabs";
tabs.setAttribute("role", "tablist");
const save = createButton({
label: "저장",
+1 -1
View File
@@ -213,7 +213,7 @@ function tableView(projectId: string): MilestoneView {
export function renderMilestone(host: HTMLElement, projectId: string): void {
const tabs = el("div", {
className: "b08-quantity__tabs b08-structure__tabs",
className: "b08-quantity__tabs ui-subtabs b08-structure__tabs",
attrs: { role: "tablist" },
});
const view = el("div");
+2 -2
View File
@@ -57,7 +57,7 @@ function pendingNote(): HTMLElement {
/** 자재 탭 — 보조 탭 줄 + 몸통(보조 탭마다 새 몸통 · 늦은 응답이 다른 보조 탭을 덮지 않게). */
function renderMaterials(host: HTMLElement, projectId: string | null): void {
const tabs = document.createElement("div");
tabs.className = "b08-quantity__tabs b08-structure__tabs";
tabs.className = "b08-quantity__tabs ui-subtabs b08-structure__tabs";
tabs.setAttribute("role", "tablist");
const view = document.createElement("div");
const select = (picked: SheetId): void => {
@@ -92,7 +92,7 @@ function renderTab(host: HTMLElement, tab: TabId, projectId: string | null): voi
if (tab === "summary" && projectId) {
// 보조 탭 줄 자리(170-4) — 보이지 않는 sm 단추 한 줄 · 자재 탭과 같은 높이라 탭 바꿀 때 안 튐
const blank = document.createElement("div");
blank.className = "b08-quantity__tabs b08-quantity__tabs--blank";
blank.className = "b08-quantity__tabs ui-subtabs b08-quantity__tabs--blank";
blank.setAttribute("aria-hidden", "true");
const ghost = createButton({ label: L(SHEETS[0].label), variant: "ghost", size: "sm" });
ghost.tabIndex = -1;
+2 -2
View File
@@ -37,9 +37,9 @@ export function createTabBars(onPick: (tab: TabId) => void): TabBars {
top.className = "b09-estimation__tabs";
top.setAttribute("role", "tablist");
const sub = document.createElement("div");
sub.className = "b09-estimation__tabs";
sub.className = "b09-estimation__tabs ui-subtabs";
const tools = document.createElement("div");
tools.className = "b09-estimation__tools";
tools.className = "b09-estimation__tools ui-subtabs__tools";
const lastSeen = new Map<TabId, TabId>();
const draw = (tab: TabId): void => {
+1 -1
View File
@@ -14,7 +14,7 @@ PAGE_CSS = (ROOT / "B08_Quantity/B08_Quantity_UI_Page.css").read_text(encoding="
def test_170_4_집계표_보조_탭_줄_자리():
branch = PAGE.split('if (tab === "summary" && projectId) {', 1)[1].split("\n }", 1)[0]
# 자재 탭 보조 탭 줄과 같은 클래스 · sm 단추 하나(보이지 않음 · 초점 안 감)
assert '"b08-quantity__tabs b08-quantity__tabs--blank"' in branch
assert '"b08-quantity__tabs ui-subtabs b08-quantity__tabs--blank"' in branch # 279 공용 양식
assert 'size: "sm"' in branch and "ghost.tabIndex = -1" in branch
assert 'setAttribute("aria-hidden", "true")' in branch
# 집계표는 줄 아래 몸통에 그림(replaceChildren 이 빈 줄을 지우지 않게)
@@ -0,0 +1,62 @@
"""279 B08 · B09 보조 탭 단추 높이 한 꼴.
- 테마 토큰 `--subtab-height` = 24px(B09 단가산출근거 박스보기 때 잰 값)
- 공용 양식 `.ui-subtabs`(가운데 맞춤 · 단추 높이 = 토큰) · `.ui-subtabs__tools`(높이 = 토큰 · 줄 높이 안 바꿈)
- B09 아래 줄 · 도구 · B08 보조 탭 줄 모두(빈 줄 자리 포함)가 씀 · 위 탭 줄은 안 씀
- `ui-btn--sm` 전체는 그대로
"""
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
def _read(rel: str) -> str:
return (ROOT / rel).read_text(encoding="utf-8")
def _block(css: str, selector: str) -> str:
m = re.search(re.escape(selector) + r"\s*\{([^}]*)\}", css)
assert m, selector
return m.group(1)
def test_token_is_box_view_height():
theme = _read("ui_template/ui_template_theme.css")
assert re.search(r"--subtab-height:\s*24px;", theme)
def test_shared_class_centers_and_fixes_height():
css = _read("ui_template/ui_template_general_layout.css")
assert "align-items: center" in _block(css, ".ui-subtabs")
assert "height: var(--subtab-height)" in _block(css, ".ui-subtabs > .ui-btn")
tools = _block(css, ".ui-subtabs__tools")
assert "align-items: center" in tools
assert "height: var(--subtab-height)" in tools
def test_sm_button_untouched():
styles = _read("ui_template/ui_template_elements_styles.ts")
assert "height" not in _block(styles, ".ui-btn--sm")
def test_b09_sub_row_and_tools_use_shared_class():
bar = _read("B09_Estimation/B09_Estimation_UI_TabBar.ts")
assert 'sub.className = "b09-estimation__tabs ui-subtabs"' in bar
assert 'tools.className = "b09-estimation__tools ui-subtabs__tools"' in bar
assert 'top.className = "b09-estimation__tabs"' in bar # 위 탭은 그대로
def test_b08_sub_rows_use_shared_class():
sub_rows = {
"B08_Quantity/B08_Quantity_UI_Page.ts": 2, # 자재 보조 탭 · 구조물 집계표 빈 줄 자리
"B08_Quantity/B08_Quantity_UI_Earthwork.ts": 1,
"B08_Quantity/B08_Quantity_UI_Hydro.ts": 1,
"B08_Quantity/B08_Quantity_UI_Milestone.ts": 1,
}
for rel, n in sub_rows.items():
src = _read(rel)
assert src.count('"b08-quantity__tabs ui-subtabs') == n, rel
page = _read("B08_Quantity/B08_Quantity_UI_Page.ts")
assert 'tabBar.className = "b08-quantity__tabs";' in page # 위 탭은 그대로
@@ -55,6 +55,21 @@
gap: var(--btn-group-gap);
}
/* 보조 탭 줄(B08 · B09) — 단추 높이 = `--subtab-height` · 줄 안 도구는 가운데 맞춤 · 줄 높이를 바꾸지 않음 */
.ui-subtabs {
align-items: center;
}
.ui-subtabs > .ui-btn {
height: var(--subtab-height);
}
.ui-subtabs__tools {
display: flex;
align-items: center;
height: var(--subtab-height);
}
.ui-general-block__table-wrap {
overflow-x: auto;
}
+2
View File
@@ -168,6 +168,8 @@
/* 줄 위 작은 단추 한 규격 — 종단 머리 줄 [초기화]~▼ · [배수유역도] · [새 창] 이 함께 씀(높이 = 글자 12 + 여백 2 + 테두리 2) */
--btn-bar-padding: 1px var(--spacing-8);
--btn-bar-font-size: var(--text-caption);
/* 보조 탭 단추 높이 — B08 · B09 보조 탭 줄(.ui-subtabs) 한 꼴 */
--subtab-height: 24px;
/* ---------------------------------------------------------------------------
* 6. 그림자 (Shadows) — 블루틴트, 서브틀 (최대 32px blur / 6% opacity)