diff --git a/E02_StabGround/E02_StabGround_UI_Style.css b/E02_StabGround/E02_StabGround_UI_Style.css index 3e715fb20..bade5d2fd 100644 --- a/E02_StabGround/E02_StabGround_UI_Style.css +++ b/E02_StabGround/E02_StabGround_UI_Style.css @@ -41,38 +41,11 @@ gap: var(--spacing-4); } -.e02-table { - width: 100%; - border-collapse: collapse; - font-size: var(--text-body-sm); - color: var(--color-text-body); -} - -.e02-table th { - padding: var(--spacing-4); - border-bottom: 1px solid var(--color-border); - color: var(--color-text-secondary); - font-weight: var(--font-weight-medium); - text-align: left; - white-space: nowrap; -} - -.e02-table td { - padding: 2px var(--spacing-4); - vertical-align: middle; -} - +/* 표 모양은 표 부품 — 여기는 읽기 표 줄 안 줄바꿈만 */ .e02-table--read td { - padding: 2px var(--spacing-8); - border-bottom: 1px solid var(--color-border); white-space: nowrap; } -.e02-table--read tr.is-zoned td { - background: var(--color-mist-violet); - color: var(--color-text); -} - .e02-stations { max-height: 320px; overflow: auto; @@ -112,14 +85,6 @@ font-size: var(--text-body-sm); } -.e02-field { - display: flex; - flex-direction: column; - gap: 2px; - font-size: var(--text-caption); - color: var(--color-text-secondary); -} - .e02-status { margin: var(--spacing-8) 0 0; white-space: pre-line; diff --git a/E02_StabGround/E02_StabGround_UI_Tables.ts b/E02_StabGround/E02_StabGround_UI_Tables.ts index 7f9967e9e..2c352bc21 100644 --- a/E02_StabGround/E02_StabGround_UI_Tables.ts +++ b/E02_StabGround/E02_StabGround_UI_Tables.ts @@ -15,6 +15,7 @@ import { } from "@ui/ui_template_elements"; import { createCard } from "@ui/ui_template_card"; import { createCheckbox } from "@ui/ui_template_checkbox"; +import { createTable } from "@ui/ui_template_table"; import { createText } from "@ui/ui_template_text"; import { t, type LocaleKey } from "@ui/ui_template_locale"; import { inferStationInterval, stationLabel } from "../common_util/common_util_station"; @@ -119,16 +120,15 @@ export function headButtons( head.append(...buttons); } -export function table(headers: string[], rows: HTMLElement[][]): HTMLTableElement { - const node = el("table", { className: "e02-table" }) as HTMLTableElement; - const tr = node.createTHead().insertRow(); - for (const text of headers) tr.append(el("th", { text })); - const body = node.createTBody(); - for (const cells of rows) { - const row = body.insertRow(); - for (const cell of cells) row.insertCell().append(cell); - } - return node; +/** 표 부품(데이터표) — 머리 글 "" = 줄 끝 단추 칸 · 돌려주는 것 = 표 감싸개(속 `table.e02-table`) */ +export function table(headers: string[], rows: HTMLElement[][]): HTMLElement { + const wrap = createTable( + headers.map((label) => ({ label })), + rows, + { density: "data" }, + ); + wrap.querySelector("table")?.classList.add("e02-table"); + return wrap; } function defaultMaterial(view: E02View, id: string): Material | undefined { @@ -200,9 +200,9 @@ function materialsCard(view: E02View): HTMLElement { const mapRow = el("div", { className: "e02-map" }); mapRow.append(el("span", { className: "e02-map__title", text: t("E02_LabelMap") })); for (const label of LABELS) { - const field = el("label", { className: "e02-field" }); + const field = el("label", { className: "ui-field e02-field" }); field.append( - el("span", { text: L(`E02_Label_${label}`) }), + el("span", { className: "ui-field__label", text: L(`E02_Label_${label}`) }), selectInput(view, `label_map.${label}`, layerOptions(g), g.label_map[label], (v) => { g.label_map[label] = v; view.rebuild(); @@ -327,8 +327,11 @@ function zonesCard(view: E02View): { section: HTMLElement; refresh: () => void } el("span", { text: fmt(r.soil_thickness_m) }), ]), ); - resolved.forEach((r, i) => node.tBodies[0].rows[i].classList.toggle("is-zoned", r.zoned)); - node.classList.add("e02-table--read"); + node.querySelectorAll("tbody tr").forEach((tr, i) => { + tr.classList.toggle("is-zoned", resolved[i].zoned); + tr.classList.toggle("is-active", resolved[i].zoned); + }); + node.querySelector("table")?.classList.add("e02-table--read"); stationsHost.append(node); }; refresh(); @@ -393,7 +396,7 @@ function safetyCard(view: E02View): HTMLElement { ]); const { section, head } = card( "E02_Card_Safety", - table(["", ...SLOPES.map((s) => L(`E02_Slope_${s}`))], rows), + table(["\u00a0", ...SLOPES.map((s) => L(`E02_Slope_${s}`))], rows), ); headButtons( view, @@ -416,8 +419,8 @@ function loadsCard(view: E02View): HTMLElement { const g = view.ground; const d = view.defaults; const field = (label: string, input: HTMLElement): HTMLElement => { - const node = el("label", { className: "e02-field" }); - node.append(el("span", { text: label }), input); + const node = el("label", { className: "ui-field e02-field" }); + node.append(el("span", { className: "ui-field__label", text: label }), input); return node; }; const kh = numInput(view, "seismic.kh", g.seismic.kh, (v) => (g.seismic.kh = v as number), { diff --git a/E02_StabGround/E02_StabGround_UI_Water.ts b/E02_StabGround/E02_StabGround_UI_Water.ts index 08d1fbba6..e2b8e720f 100644 --- a/E02_StabGround/E02_StabGround_UI_Water.ts +++ b/E02_StabGround/E02_StabGround_UI_Water.ts @@ -23,8 +23,8 @@ import { const L = (key: string): string => t(key as LocaleKey); function field(label: string, input: HTMLElement): HTMLElement { - const node = el("label", { className: "e02-field" }); - node.append(el("span", { text: label }), input); + const node = el("label", { className: "ui-field e02-field" }); + node.append(el("span", { className: "ui-field__label", text: label }), input); return node; } diff --git a/resources/tester/test_553_4_de_parts.py b/resources/tester/test_553_4_de_parts.py index f22a3a7e0..120e4582f 100644 --- a/resources/tester/test_553_4_de_parts.py +++ b/resources/tester/test_553_4_de_parts.py @@ -79,3 +79,6 @@ def test_e02_parts(): for dead in (".e02-card__head", ".e02-card__title", ".e02-hint", ".e02-empty"): assert dead not in css, dead _no_hex("E02_StabGround/E02_StabGround_UI_Style.css") + assert "createTable(" in tables and "createTHead" not in tables + assert 'className: "ui-field e02-field"' in tables # 칸 이름 줄은 입력 부품의 ui-field + assert ".e02-field" not in css and "border-collapse" not in css