Files
Aislo/ui_template/ui_template_table.ts
T
eomsangdonandClaude Opus 5.5 47b396b53d feat(ui-kit): 묶음 부품 다섯 — 표 · ⋯ 메뉴 · 모달 · 확인창 · 설정 줄 · 파일 놓기 칸 (PLAN 552-3)
- 새 부품 파일: ui_template_table · setting_row · drop · createRowMenu(context_menu) · 모달 폭 단 · askConfirm · askText(window.prompt 대신) · confirmPanel
- 단추 = 552-2 단추 부품(⋯ 아이콘 단추 28 · 띠 알림 닫기 20 · 놓기 칸 [파일 고르기] 28)
- 대시보드 PageKit 의 dataTable · tableShell · tableRow · rowMenu · settingRow · settingCard · valueText = 부품을 다시 내보냄(한 벌 · 부름 꼴 그대로) · B01 옛 CSS 걷음
- showConfirmDialog 는 모달 부품으로 옮기고 본체가 다시 내보냄 · 모달 가림막 옛 보라 → --color-scrim
- 시험: test_552_3_* 다섯 더함 · 옮긴 함수 자리를 읽던 test_290_1 · test_505_2 고침 · 부품 CSS import 를 못 읽던 시험 도우미 넷(130 · 153 · 280_5 · 311)이 .css 를 건너뜀
- 전후 촬영: B01 여덟 화면 자리 같음 · ⋯ 아이콘만 1 px 왼쪽(단추 부품 가운데 맞춤)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 21:55:11 +09:00

82 lines
3.5 KiB
TypeScript

/* =============================================================================
* 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;
}