diff --git a/resources/tester/helper_ui_data_table.cjs b/resources/tester/helper_ui_data_table.cjs index 3dad134c2..653e6e114 100644 --- a/resources/tester/helper_ui_data_table.cjs +++ b/resources/tester/helper_ui_data_table.cjs @@ -90,5 +90,19 @@ console.log( }), escaped: m.renderDataTableHtml({ columns: [{ key: "x", label: "" }], rows: [{ x: "a&<" }] }), noTotal: m.renderDataTableHtml({ columns: [tc], rows: [] }).includes(""), + scale: m.SCALE, + widths: m.renderDataTableHtml({ + columns: [ + { key: "a", label: "A" }, + { key: "b", label: "B", kind: "number" }, + { key: "c", label: "C", width: 120 }, + ], + rows: [{ a: 1 }], + frozen: 2, + }), + css: fs.readFileSync( + path.join(__dirname, "..", "..", "ui_template", "ui_template_data_table.css"), + "utf8", + ), }), ); diff --git a/resources/tester/test_ui_data_table.py b/resources/tester/test_ui_data_table.py index 56fe2c74a..d35017050 100644 --- a/resources/tester/test_ui_data_table.py +++ b/resources/tester/test_ui_data_table.py @@ -101,3 +101,14 @@ def test_줄_누름_옵션일_때만_data_i(r): assert '' in pick assert pick.count("data-i=") == 2 assert "data-i" not in r["opts"] and "is-clickable" not in r["foot"] + + +def test_155_1_글자_14px_열_폭_같은_비율(r): + # 155-1 — 표 글 12 → 14px · 열 폭(12px 글 기준 값)에 14/12 를 곱함 · 줄 높이 28px + assert abs(r["scale"] - 14 / 12) < 1e-9 + w = r["widths"] + assert '' in w + assert 'style="width:350px"' in w # 표 폭 = 112 + 98 + 140 + assert 'class="is-frozen is-edge" style="left:112px"' in w # 둘째 고정 열 left 도 같이 + assert "font-size: var(--text-body-sm);" in r["css"] + assert "--dt-row-h: 28px;" in r["css"] diff --git a/ui_template/ui_template_data_table.css b/ui_template/ui_template_data_table.css index db528c844..85ad737d7 100644 --- a/ui_template/ui_template_data_table.css +++ b/ui_template/ui_template_data_table.css @@ -4,7 +4,7 @@ * ========================================================================== */ .ui-data-table { - --dt-row-h: 24px; + --dt-row-h: 28px; --dt-zebra: var(--color-surface); --dt-hover: color-mix(in srgb, var(--color-accent) 14%, var(--color-canvas)); --dt-head: color-mix(in srgb, var(--color-accent) 6%, var(--color-surface)); @@ -30,7 +30,7 @@ border-collapse: separate; border-spacing: 0; color: var(--color-text-body); - font-size: var(--text-caption); + font-size: var(--text-body-sm); line-height: 1.3; } diff --git a/ui_template/ui_template_data_table.ts b/ui_template/ui_template_data_table.ts index e9c682480..5c64b59d2 100644 --- a/ui_template/ui_template_data_table.ts +++ b/ui_template/ui_template_data_table.ts @@ -26,7 +26,7 @@ export interface DataColumn { decimals?: number; /** 끝 0 지움(decimals 는 최대 자리) — 사용자가 넣는 값처럼 자리가 줄마다 다른 열 */ trim?: boolean; - /** 열 폭 px(기본 숫자 84 · 글 96) */ + /** 열 폭 px(12px 글 기준 · 기본 숫자 84 · 글 96) — 그릴 때 글 비 SCALE 을 곱함 */ width?: number; /** 맨 아래 머리 칸 풍선 글(기본 label) */ title?: string; @@ -70,8 +70,11 @@ const EMPTY = "-"; const ESC: Record = { "&": "&", "<": "<", ">": ">", '"': """ }; const esc = (s: string): string => s.replace(/[&<>"]/g, (c) => ESC[c]); +/** 글 크기 비(14px ÷ 12px) — 페이지가 준 열 폭(12px 글 기준)을 같은 비율로 넓힘 */ +export const SCALE = 14 / 12; + function colWidth(c: DataColumn): number { - return c.width ?? (c.kind === "number" ? 84 : 96); + return Math.round((c.width ?? (c.kind === "number" ? 84 : 96)) * SCALE); } /** 값 한 칸 → [보일 글, 빈 값인지] */ @@ -226,7 +229,7 @@ export function createDataTable(opts: DataTableOptions): DataTable { root.className = "ui-data-table"; root.tabIndex = 0; // 키보드로 표 안 스크롤 const state = { ...opts }; - let win: RowWindow = { from: -1, to: -1, rowH: 24 }; // --dt-row-h · 그린 뒤 재서 고침 + let win: RowWindow = { from: -1, to: -1, rowH: 28 }; // --dt-row-h · 그린 뒤 재서 고침 // 보이는 줄 근처만 그림 — 줄 1,000개를 다 배치하면 수백 ms const draw = (force: boolean) => { const n = state.rows.length;