/* ============================================================================= * ui_template_table.ts * 부품 「표」(552-3 · 목록 18) — 머리 줄 + 줄들 · 세로선 없음 · 카드 테두리 · 넘치면 가로 스크롤. * 꼴 = 일반표(줄 40 · 기본) · 데이터표(`density: "data"` · 줄 28 · 글 12) · ⋯ 칸(columns 의 label "" — 줄 끝 `createRowMenu`) * · 한글 배지 칸(칸에 배지 요소) · 오른쪽 맞춤 칸(`align: "end"` · 수) · 빈 줄(`emptyRow`) · 펼침 줄(tr.is-sub) * 크기 = 줄 40 / 28 · 머리 36 / 28 * 상태 = 줄 마우스(옅은 바탕) · 고름(tr.is-active / aria-selected) · 바뀜(tr.is-changed) · 지움(tr.is-removed · 줄 그음) * 쓰는 법 = `createTable([{ label: "이름" }, { label: "", width: "44px" }], [["임도 1", createRowMenu([…])]])` * · 줄을 나중에 채우면 `const { root, tbody } = tableShell(columns); tbody.append(tableRow(columns, cells))` * 대신하는 옛 변종 = B01 `dataTable` · `tableShell`(`.b01-pg-table`) · `.b01-proj-table` · `.ui-general-block__table` · D04 · E02 · E03 · E06 · E07 손 표 · M01 · M02 표(목록 4장) * 옛 `.ui-data-table`(끌어 고치는 큰 표 · `ui_template_data_table.ts`)은 따로 그대로. * ========================================================================== */ import { el } from "./ui_template_elements_base"; import "./ui_template_table.css"; export type Cell = string | Node; export interface Column { label: string; /** 칸 너비(CSS) — 없으면 나눠 가짐 */ width?: string; align?: "end"; } export interface TableOptions { /** 데이터표(줄 28 · 글 12) */ density?: "data"; } /** 표 껍데기 — 머리 + 빈 tbody (줄은 호출 쪽이 채움 · 펼침 줄 같은 것을 끼우려고 떼어 둠) */ export function tableShell( columns: Column[], opts: TableOptions = {}, ): { root: HTMLElement; tbody: HTMLElement } { const table = el("table", { className: `ui-table${opts.density === "data" ? " ui-table--data" : ""}`, }); const hr = el("tr"); for (const col of columns) { const th = el("th", { className: col.align ? "is-end" : "", text: col.label }); if (col.width) th.style.width = col.width; hr.append(th); } const tbody = el("tbody"); table.append(el("thead", { children: [hr] }), tbody); return { root: el("div", { className: "ui-table-wrap", children: [table] }), tbody }; } /** 한 줄 — 칸 수는 columns 와 같게 · label "" 인 칸 = ⋯ 칸 */ export function tableRow(columns: Column[], cells: Cell[]): HTMLTableRowElement { const tr = el("tr"); cells.forEach((cell, i) => { const col = columns[i]; const td = el("td", { className: col?.align ? "is-end" : col?.label === "" ? "ui-table__menucell" : "", }); td.append(cell); tr.append(td); }); return tr; } /** 빈 줄 — 칸을 다 합쳐 한 줄 안내 */ export function emptyRow(columns: Column[], text: string): HTMLTableRowElement { const td = el("td", { className: "ui-table__empty", text }); td.colSpan = columns.length; return el("tr", { children: [td] }); } /** 표 — 줄이 없으면 `empty` 글 한 줄 */ export function createTable( columns: Column[], rows: Cell[][], opts: TableOptions & { empty?: string } = {}, ): HTMLElement { const { root, tbody } = tableShell(columns, opts); tbody.append(...rows.map((cells) => tableRow(columns, cells))); if (!rows.length && opts.empty) tbody.append(emptyRow(columns, opts.empty)); return root; }