dsh-plugin-core 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/design/tokens-css.generated.d.ts +1 -1
  2. package/dist/design/tokens-css.generated.d.ts.map +1 -1
  3. package/dist/design/tokens-css.generated.js +1 -1
  4. package/dist/design/tokens-css.generated.js.map +1 -1
  5. package/dist/ui/Loader.d.ts.map +1 -1
  6. package/dist/ui/Loader.js +10 -6
  7. package/dist/ui/Loader.js.map +1 -1
  8. package/dist/ui/LoaderBar.d.ts.map +1 -1
  9. package/dist/ui/LoaderBar.js +10 -4
  10. package/dist/ui/LoaderBar.js.map +1 -1
  11. package/dist/ui/Pagination.d.ts +59 -0
  12. package/dist/ui/Pagination.d.ts.map +1 -0
  13. package/dist/ui/Pagination.js +110 -0
  14. package/dist/ui/Pagination.js.map +1 -0
  15. package/dist/ui/SectionHead.d.ts +24 -5
  16. package/dist/ui/SectionHead.d.ts.map +1 -1
  17. package/dist/ui/SectionHead.js +32 -5
  18. package/dist/ui/SectionHead.js.map +1 -1
  19. package/dist/ui/Table.d.ts +30 -0
  20. package/dist/ui/Table.d.ts.map +1 -0
  21. package/dist/ui/Table.js +92 -0
  22. package/dist/ui/Table.js.map +1 -0
  23. package/dist/ui/controls/pagination-css.generated.d.ts +2 -0
  24. package/dist/ui/controls/pagination-css.generated.d.ts.map +1 -0
  25. package/dist/ui/controls/pagination-css.generated.js +4 -0
  26. package/dist/ui/controls/pagination-css.generated.js.map +1 -0
  27. package/dist/ui/controls/section-head-css.generated.d.ts +2 -0
  28. package/dist/ui/controls/section-head-css.generated.d.ts.map +1 -0
  29. package/dist/ui/controls/section-head-css.generated.js +4 -0
  30. package/dist/ui/controls/section-head-css.generated.js.map +1 -0
  31. package/dist/ui/controls/table-css.generated.d.ts +2 -0
  32. package/dist/ui/controls/table-css.generated.d.ts.map +1 -0
  33. package/dist/ui/controls/table-css.generated.js +4 -0
  34. package/dist/ui/controls/table-css.generated.js.map +1 -0
  35. package/dist/ui/controls/table-plain-css.generated.d.ts +2 -0
  36. package/dist/ui/controls/table-plain-css.generated.d.ts.map +1 -0
  37. package/dist/ui/controls/table-plain-css.generated.js +4 -0
  38. package/dist/ui/controls/table-plain-css.generated.js.map +1 -0
  39. package/dist/ui/controls-css.d.ts +4 -0
  40. package/dist/ui/controls-css.d.ts.map +1 -1
  41. package/dist/ui/controls-css.js +7 -0
  42. package/dist/ui/controls-css.js.map +1 -1
  43. package/dist/ui/index.d.ts +5 -1
  44. package/dist/ui/index.d.ts.map +1 -1
  45. package/dist/ui/index.js +6 -0
  46. package/dist/ui/index.js.map +1 -1
  47. package/dist/ui/pagination-logic.d.ts +36 -0
  48. package/dist/ui/pagination-logic.d.ts.map +1 -0
  49. package/dist/ui/pagination-logic.js +73 -0
  50. package/dist/ui/pagination-logic.js.map +1 -0
  51. package/dist/ui/table-logic.d.ts +110 -0
  52. package/dist/ui/table-logic.d.ts.map +1 -0
  53. package/dist/ui/table-logic.js +81 -0
  54. package/dist/ui/table-logic.js.map +1 -0
  55. package/dist/ui/table-shared.d.ts +100 -0
  56. package/dist/ui/table-shared.d.ts.map +1 -0
  57. package/dist/ui/table-shared.js +222 -0
  58. package/dist/ui/table-shared.js.map +1 -0
  59. package/dist/utils/i18n.d.ts +1 -1
  60. package/dist/utils/i18n.d.ts.map +1 -1
  61. package/dist/utils/i18n.js +24 -0
  62. package/dist/utils/i18n.js.map +1 -1
  63. package/docs/design/structure.md +5 -3
  64. package/docs/help/ui.doc.ts +221 -2
  65. package/docs/help/ui.md +211 -2
  66. package/docs/requirements.md +47 -0
  67. package/package.json +1 -1
@@ -0,0 +1,73 @@
1
+ /**
2
+ * 分页纯逻辑:总页数、页码夹取、省略号窗口、当前页可见区间。
3
+ *
4
+ * 零 React 运行时依赖(只 `import type`,编译后不留痕迹),可被 node 单测直接引。
5
+ *
6
+ * 口径照通行的分页约定(Ant Design / MUI / Element Plus 一致):
7
+ * 调用方只给「当前页 / 每页条数 / 总条数」,总页数与省略窗口一律由这里算,
8
+ * **消费方永远不自己算页数、也不自己拼页码**。
9
+ */
10
+ /** 总页数:`ceil(total / pageSize)`,至少 1 页(空数据也显示单页)。 */
11
+ export function pageCountOf(total, pageSize) {
12
+ const size = Math.max(1, Math.floor(pageSize));
13
+ const rows = Math.max(0, Math.floor(total));
14
+ return Math.max(1, Math.ceil(rows / size));
15
+ }
16
+ /** 把页码夹回 `[1, pageCount]`(越界 / NaN 一律落到第 1 页)。 */
17
+ export function clampPage(page, pageCount) {
18
+ const count = Math.max(1, Math.floor(pageCount));
19
+ if (!Number.isFinite(page))
20
+ return 1;
21
+ return Math.min(Math.max(1, Math.floor(page)), count);
22
+ }
23
+ /**
24
+ * 当前页在数据里的区间(1 起的闭区间行号)。
25
+ * 空数据返回 `[0, 0]`(调用方据此显示「共 0 条」而不是「第 0-0 条」)。
26
+ */
27
+ export function pageRange(page, pageSize, total) {
28
+ const rows = Math.max(0, Math.floor(total));
29
+ if (rows === 0)
30
+ return [0, 0];
31
+ const size = Math.max(1, Math.floor(pageSize));
32
+ const current = clampPage(page, pageCountOf(rows, size));
33
+ const from = (current - 1) * size + 1;
34
+ return [from, Math.min(rows, from + size - 1)];
35
+ }
36
+ function range(start, end) {
37
+ const out = [];
38
+ for (let n = start; n <= end; n += 1)
39
+ out.push(n);
40
+ return out;
41
+ }
42
+ /**
43
+ * 页码条上的项序列(含省略号占位)。
44
+ *
45
+ * 窗口算法照 MUI 的实现:首尾各固定 `boundaryCount` 页,当前页两侧各留 `siblingCount` 页,
46
+ * 中间不足的部分收成 `'gap'`。默认 1 / 1 —— 最多 7 个位置(与 Element Plus `pager-count: 7` 等价)。
47
+ *
48
+ * 关键细节(各家一致,别改成「有缝就画省略号」):间隔**正好 1 页**时直接显示那个页号,
49
+ * 不画省略号,否则会出现 `1 2 … 4` 这种丑态。
50
+ */
51
+ export function pageItems(page, pageCount, siblingCount = 1, boundaryCount = 1) {
52
+ const count = Math.max(1, Math.floor(pageCount));
53
+ const current = clampPage(page, count);
54
+ const boundary = Math.max(0, Math.floor(boundaryCount));
55
+ const siblings = Math.max(0, Math.floor(siblingCount));
56
+ const startPages = range(1, Math.min(boundary, count));
57
+ const endPages = range(Math.max(count - boundary + 1, boundary + 1), count);
58
+ const siblingsStart = Math.max(Math.min(current - siblings, count - boundary - siblings * 2 - 1), boundary + 2);
59
+ const siblingsEnd = Math.min(Math.max(current + siblings, boundary + siblings * 2 + 2), endPages.length > 0 ? endPages[0] - 2 : count - 1);
60
+ const items = [...startPages];
61
+ if (siblingsStart > boundary + 2)
62
+ items.push('gap');
63
+ else if (boundary + 1 < count - boundary)
64
+ items.push(boundary + 1);
65
+ items.push(...range(siblingsStart, siblingsEnd));
66
+ if (siblingsEnd < count - boundary - 1)
67
+ items.push('gap');
68
+ else if (count - boundary > boundary)
69
+ items.push(count - boundary);
70
+ items.push(...endPages);
71
+ return items;
72
+ }
73
+ //# sourceMappingURL=pagination-logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination-logic.js","sourceRoot":"","sources":["../../src/ui/pagination-logic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * 表格纯逻辑:列树 → 表头单元格(colSpan / rowSpan)。
3
+ *
4
+ * 零 React 运行时依赖(只 `import type`,编译后不留痕迹),可被 node 单测直接引。
5
+ * 组件层只负责把这里算好的表头画出来;分组表头到底占几行、跨几列,一律由本文件决定。
6
+ *
7
+ * 列模型:`children` 存在且非空 ⇒ 该列是分组表头(自身 key 不产出单元格,只做表头);
8
+ * 否则是叶子列,`rows` 里按叶子 key 取单元格内容。
9
+ */
10
+ import type { ReactNode } from 'react';
11
+ /** 单元格水平对齐(默认 left)。 */
12
+ export type TableAlign = 'left' | 'center' | 'right';
13
+ /** 行密度:决定行高与水平内距(参考稿是 default 档)。 */
14
+ export type TableDensity = 'compact' | 'default' | 'comfortable';
15
+ /** 外框范围:y 只有上下两条(组件默认,无左右边)/ all 四边 / x 只有左右两条 / none 全不要。 */
16
+ export type TableBorders = 'all' | 'x' | 'y' | 'none';
17
+ /**
18
+ * 表头底色档位。与全库语义色同名(default 是皮肤默认灰底)。
19
+ * 一律映射到既有 token,不许传任意色值 —— 换主题 / 暗色自动成立。
20
+ */
21
+ export type TableTone = 'default' | 'business' | 'success' | 'warning' | 'danger' | 'purple' | 'pink' | 'cyan' | 'teal' | 'orange' | 'indigo' | 'rose' | 'slate';
22
+ /** 一列(可嵌套 children 形成多行分组表头)。 */
23
+ export interface TableColumn {
24
+ /** 叶子列的 key 同时是 `TableRow.cells` 的取值键;分组列只用于 React key / 调试。 */
25
+ key: string;
26
+ /** 表头文案(分组列即分组名)。 */
27
+ title: ReactNode;
28
+ /** 子列:有子列时本列是分组表头,不产出数据单元格。 */
29
+ children?: readonly TableColumn[];
30
+ /** 列宽:数字按 px;不传由 `table-layout:fixed` 平均分。 */
31
+ width?: number | string;
32
+ /** 对齐(表头与数据格同源,默认 left)。 */
33
+ align?: TableAlign;
34
+ /**
35
+ * 该列左缘是否画竖分隔线(默认 false = 不画,表格默认只有横线);首列恒不画(那是外框的位置)。
36
+ * 分组列自己不写时,跟随它第一个叶子列 —— 组头的左缘和第一个子列的左缘是同一条线。
37
+ */
38
+ divider?: boolean;
39
+ /** 该列水平内距(px),覆盖 density 档;不传走密度档。 */
40
+ padding?: number;
41
+ /** 该列表头底色档位(默认 default = 皮肤灰底)。 */
42
+ headerTone?: TableTone;
43
+ }
44
+ /**
45
+ * 单元格对象写法:内容 + 跨列 / 跨行 / 对齐。
46
+ * 不写对象、直接给 ReactNode 即普通单元格(最常用)。
47
+ */
48
+ export interface TableCellSpec {
49
+ content: ReactNode;
50
+ /** 横向跨几列(原生 colspan)。 */
51
+ colSpan?: number;
52
+ /** 纵向跨几行(原生 rowspan);下一行不要给同一列 key。 */
53
+ rowSpan?: number;
54
+ /** 覆盖该列对齐。 */
55
+ align?: TableAlign;
56
+ }
57
+ /** 一个单元格:ReactNode(普通)或对象(跨列 / 跨行 / 对齐)。 */
58
+ export type TableCell = ReactNode | TableCellSpec;
59
+ /** 一行数据:key 兼作选中标识与 React key,cells 按叶子列 key 取内容。 */
60
+ export interface TableRow {
61
+ key: string | number;
62
+ /**
63
+ * cells 按叶子列 key 取内容。
64
+ * 缺 key(undefined)= 该格不渲染,给上一行的 rowSpan 让位;要空单元格请显式传 null。
65
+ */
66
+ cells: Record<string, TableCell>;
67
+ }
68
+ /**
69
+ * 一个分组(通栏段):自带一行横跨所有列的通栏标题、自己的表头、自己的数据行。
70
+ * 多个分组垂直连续排布(中间没有空隙),用于「一个表格里展示多个工作区 / 多个板块」。
71
+ */
72
+ export interface TableGroup {
73
+ key: string | number;
74
+ /** 通栏标题(横跨全部列)。 */
75
+ title: ReactNode;
76
+ rows: readonly TableRow[];
77
+ }
78
+ /** 一个表头单元格:它覆盖的列(可能跨列 / 跨行)。 */
79
+ export interface TableHeaderCell {
80
+ column: TableColumn;
81
+ colSpan: number;
82
+ rowSpan: number;
83
+ /** 该表头覆盖的叶子列 key(按从左到右顺序)。 */
84
+ leafKeys: string[];
85
+ }
86
+ /** 叶子列判断:没有 children 或 children 为空。 */
87
+ export declare function isLeafColumn(column: TableColumn): boolean;
88
+ /**
89
+ * 单元格值是不是「对象写法」(跨列 / 跨行 / 对齐)。
90
+ *
91
+ * 判别不引 React:React 元素一定有 `$$typeof`(内部标记),而单元格对象没有 ——
92
+ * 用它把「传进来一个 React 元素」和「传进来一个单元格配置」分开。
93
+ * 放在纯逻辑层,node 单测可直接覆盖。
94
+ */
95
+ export declare function isTableCellSpec(value: unknown): value is TableCellSpec;
96
+ /** 按深度优先顺序取全部叶子列(表格的列顺序 = 数据格的列顺序)。 */
97
+ export declare function leafColumns(columns: readonly TableColumn[]): TableColumn[];
98
+ /** 列树深度 = 表头行数(全叶子列时为 1)。 */
99
+ export declare function tableDepth(columns: readonly TableColumn[]): number;
100
+ /**
101
+ * 列树 → 逐行表头。
102
+ *
103
+ * - 叶子列:`rowSpan = 深度 - 当前层`,一直竖跨到表头底部;
104
+ * - 分组列:`colSpan = 其下叶子数`,`rowSpan = 1`。
105
+ *
106
+ * 例:`[ID, Patient[Name, Age], Status]` ⇒ 第 0 行 `[ID(1×2), Patient(2×1), Status(1×2)]`,
107
+ * 第 1 行 `[Name(1×1), Age(1×1)]`。
108
+ */
109
+ export declare function headerRows(columns: readonly TableColumn[]): TableHeaderCell[][];
110
+ //# sourceMappingURL=table-logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-logic.d.ts","sourceRoot":"","sources":["../../src/ui/table-logic.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,wBAAwB;AACxB,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;AAEpD,qCAAqC;AACrC,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAA;AAEhE,8DAA8D;AAC9D,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,MAAM,CAAA;AAErD;;;GAGG;AACH,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,UAAU,GACV,SAAS,GACT,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,MAAM,GACN,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,OAAO,CAAA;AAEX,iCAAiC;AACjC,MAAM,WAAW,WAAW;IAC1B,gEAAgE;IAChE,GAAG,EAAE,MAAM,CAAA;IACX,qBAAqB;IACrB,KAAK,EAAE,SAAS,CAAA;IAChB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IACjC,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mCAAmC;IACnC,UAAU,CAAC,EAAE,SAAS,CAAA;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,SAAS,CAAA;IAClB,yBAAyB;IACzB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,cAAc;IACd,KAAK,CAAC,EAAE,UAAU,CAAA;CACnB;AAED,4CAA4C;AAC5C,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,aAAa,CAAA;AAEjD,qDAAqD;AACrD,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;IACpB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CACjC;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;IACpB,mBAAmB;IACnB,KAAK,EAAE,SAAS,CAAA;IAChB,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAA;CAC1B;AAED,gCAAgC;AAChC,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,WAAW,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,uCAAuC;AACvC,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAEzD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAItE;AAED,uCAAuC;AACvC,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,EAAE,CAQ1E;AAED,6BAA6B;AAC7B,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CAQlE;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,eAAe,EAAE,EAAE,CAmB/E"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * 表格纯逻辑:列树 → 表头单元格(colSpan / rowSpan)。
3
+ *
4
+ * 零 React 运行时依赖(只 `import type`,编译后不留痕迹),可被 node 单测直接引。
5
+ * 组件层只负责把这里算好的表头画出来;分组表头到底占几行、跨几列,一律由本文件决定。
6
+ *
7
+ * 列模型:`children` 存在且非空 ⇒ 该列是分组表头(自身 key 不产出单元格,只做表头);
8
+ * 否则是叶子列,`rows` 里按叶子 key 取单元格内容。
9
+ */
10
+ /** 叶子列判断:没有 children 或 children 为空。 */
11
+ export function isLeafColumn(column) {
12
+ return column.children === undefined || column.children.length === 0;
13
+ }
14
+ /**
15
+ * 单元格值是不是「对象写法」(跨列 / 跨行 / 对齐)。
16
+ *
17
+ * 判别不引 React:React 元素一定有 `$$typeof`(内部标记),而单元格对象没有 ——
18
+ * 用它把「传进来一个 React 元素」和「传进来一个单元格配置」分开。
19
+ * 放在纯逻辑层,node 单测可直接覆盖。
20
+ */
21
+ export function isTableCellSpec(value) {
22
+ if (typeof value !== 'object' || value === null)
23
+ return false;
24
+ if ('$$typeof' in value)
25
+ return false;
26
+ return 'content' in value;
27
+ }
28
+ /** 按深度优先顺序取全部叶子列(表格的列顺序 = 数据格的列顺序)。 */
29
+ export function leafColumns(columns) {
30
+ const out = [];
31
+ for (const column of columns) {
32
+ const children = column.children;
33
+ if (children === undefined || children.length === 0)
34
+ out.push(column);
35
+ else
36
+ out.push(...leafColumns(children));
37
+ }
38
+ return out;
39
+ }
40
+ /** 列树深度 = 表头行数(全叶子列时为 1)。 */
41
+ export function tableDepth(columns) {
42
+ let depth = 1;
43
+ for (const column of columns) {
44
+ const children = column.children;
45
+ if (children === undefined || children.length === 0)
46
+ continue;
47
+ depth = Math.max(depth, 1 + tableDepth(children));
48
+ }
49
+ return depth;
50
+ }
51
+ /**
52
+ * 列树 → 逐行表头。
53
+ *
54
+ * - 叶子列:`rowSpan = 深度 - 当前层`,一直竖跨到表头底部;
55
+ * - 分组列:`colSpan = 其下叶子数`,`rowSpan = 1`。
56
+ *
57
+ * 例:`[ID, Patient[Name, Age], Status]` ⇒ 第 0 行 `[ID(1×2), Patient(2×1), Status(1×2)]`,
58
+ * 第 1 行 `[Name(1×1), Age(1×1)]`。
59
+ */
60
+ export function headerRows(columns) {
61
+ const rows = [];
62
+ const depth = tableDepth(columns);
63
+ for (let level = 0; level < depth; level += 1)
64
+ rows.push([]);
65
+ const visit = (column, level) => {
66
+ const children = column.children;
67
+ if (children === undefined || children.length === 0) {
68
+ rows[level].push({ column, colSpan: 1, rowSpan: depth - level, leafKeys: [column.key] });
69
+ return [column.key];
70
+ }
71
+ const keys = [];
72
+ for (const child of children)
73
+ keys.push(...visit(child, level + 1));
74
+ rows[level].push({ column, colSpan: keys.length, rowSpan: 1, leafKeys: keys });
75
+ return keys;
76
+ };
77
+ for (const column of columns)
78
+ visit(column, 0);
79
+ return rows;
80
+ }
81
+ //# sourceMappingURL=table-logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-logic.js","sourceRoot":"","sources":["../../src/ui/table-logic.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAsGH,uCAAuC;AACvC,MAAM,UAAU,YAAY,CAAC,MAAmB;IAC9C,OAAO,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAA;AACtE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAC7D,IAAI,UAAU,IAAI,KAAK;QAAE,OAAO,KAAK,CAAA;IACrC,OAAO,SAAS,IAAI,KAAK,CAAA;AAC3B,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,WAAW,CAAC,OAA+B;IACzD,MAAM,GAAG,GAAkB,EAAE,CAAA;IAC7B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;QAChC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;;YAChE,GAAG,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAA;IACzC,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,6BAA6B;AAC7B,MAAM,UAAU,UAAU,CAAC,OAA+B;IACxD,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;QAChC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,SAAQ;QAC7D,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAA;IACnD,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,OAA+B;IACxD,MAAM,IAAI,GAAwB,EAAE,CAAA;IACpC,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;IACjC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,EAAE,KAAK,IAAI,CAAC;QAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAE5D,MAAM,KAAK,GAAG,CAAC,MAAmB,EAAE,KAAa,EAAY,EAAE;QAC7D,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;QAChC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpD,IAAI,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,GAAG,KAAK,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACzF,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACrB,CAAC;QACD,MAAM,IAAI,GAAa,EAAE,CAAA;QACzB,KAAK,MAAM,KAAK,IAAI,QAAQ;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAA;QACnE,IAAI,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;QAC/E,OAAO,IAAI,CAAA;IACb,CAAC,CAAA;IAED,KAAK,MAAM,MAAM,IAAI,OAAO;QAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;IAC9C,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -0,0 +1,100 @@
1
+ import { createElement as h, type CSSProperties, type ReactNode } from 'react';
2
+ import { type Translate } from '../utils/i18n.js';
3
+ import type { TablePaginationConfig } from './Pagination.js';
4
+ import { type SectionHeadAccent } from './SectionHead.js';
5
+ import { type TableBorders, type TableColumn, type TableDensity, type TableGroup, type TableRow } from './table-logic.js';
6
+ /**
7
+ * 表格外观的公共 props。**对外组件各自继承它,不要直接把本接口给消费方**:
8
+ * 消费方看到的是 `TableProps` 这类具名类型,外观由「引哪个组件」决定。
9
+ */
10
+ export interface TableSharedProps {
11
+ /** 列定义;`children` 非空即分组表头(组件自动算 colSpan / rowSpan)。 */
12
+ columns: readonly TableColumn[];
13
+ /**
14
+ * 行数据;`key` 兼作选中标识,`cells` 按叶子列 key 取内容。
15
+ * 值可以是任意 ReactNode,也可以是 `{ content, colSpan, rowSpan, align }` 对象;
16
+ * 某列 key 缺省(undefined)= 该格不渲染,给上一行的 rowSpan 让位。
17
+ */
18
+ rows?: readonly TableRow[];
19
+ /**
20
+ * 分组数据:每组带一行通栏标题 + 自己的表头 + 自己的数据行,多组连续排布。
21
+ * 与 `rows` 二选一;传了 `groups` 就忽略 `rows`(用于「一个表里多个工作区 / 板块」)。
22
+ */
23
+ groups?: readonly TableGroup[];
24
+ /**
25
+ * 通栏标题前的固定标签(画出来的短竖线)颜色(只对 `groups` 模式生效):内置语义色名
26
+ * (business / success / warning / danger / purple / pink / cyan / teal / orange / indigo /
27
+ * rose / slate)或任意 CSS 色值;`'default'` / 不传 = 主题默认(浅色深灰、深色浅灰);
28
+ * `false` = 不画这条竖线。绘制与样式归 `SectionHead`,Table 只把标题装进通栏。
29
+ */
30
+ groupAccent?: SectionHeadAccent | false;
31
+ /** 行密度(行高 + 水平内距),默认 default。 */
32
+ density?: TableDensity;
33
+ /** 斑马纹(偶数行淡底),默认 false。 */
34
+ striped?: boolean;
35
+ /** 外框范围:y 只上下两条(默认,无左右边)/ all 四边 / x 只左右两条 / none 全不要。 */
36
+ borders?: TableBorders;
37
+ /** 选中行(高亮 + 左侧竖条由皮肤决定)。 */
38
+ selectedKeys?: readonly (string | number)[];
39
+ /** 传了才可点:行获得指针 / 键盘(Enter、空格)激活能力。 */
40
+ onRowClick?: (row: TableRow, index: number) => void;
41
+ /** 空数据文案;不传走内置字典(中英随 `setLocale`)。 */
42
+ emptyText?: ReactNode;
43
+ /** 无障碍名(表格没有可见标题时请务必给)。 */
44
+ ariaLabel?: string;
45
+ /**
46
+ * 内建分页(**只在 `Table` 上生效**,`tableShell` 自己不读它):给出即按当前页切片 `rows`
47
+ * 并在表格下方渲染分页条;`total` 缺省 = `rows.length`(本地分页),给了就按服务端分页处理
48
+ * (不切片)。`groups` 模式不分页 —— 传了 `groups` 就忽略本项。
49
+ */
50
+ pagination?: TablePaginationConfig;
51
+ /**
52
+ * 整表加载中(首屏还没有任何数据时用):表格主体换成一块较高的占位区(居中三块加载动画,最大号,无文案)。
53
+ * 已有数据时不遮挡数据 —— 追加下一页请用 `loadingMore`。
54
+ */
55
+ loading?: boolean;
56
+ /** 整表加载占位区的高度(px),默认 160。 */
57
+ loadingHeight?: number;
58
+ /**
59
+ * 底部「加载更多」中(已有数据、正在取下一页):在数据行下方插一行中号三块加载动画(无文案)。
60
+ * 只在给了 `onLoadMore` 时生效。
61
+ */
62
+ loadingMore?: boolean;
63
+ /**
64
+ * 是否还有下一页,默认 true。`false` 时底部显示「没有更多数据」;
65
+ * 文案可用 `noMoreText` 换,给 `false` 整行不渲染。只在给了 `onLoadMore` 时生效。
66
+ */
67
+ hasMore?: boolean;
68
+ /** 到底文案;不传走内置字典(中英随 `setLocale`)。 */
69
+ noMoreText?: ReactNode;
70
+ /**
71
+ * 滚动到底自动加载下一页:**这个 props 本身就是开关** —— 传了就装底部哨兵并监听,
72
+ * 不传完全不监听、也不触发。正在加载(`loading` / `loadingMore`)或已到底(`hasMore: false`)
73
+ * 时不会重复触发。与 `pagination` / `groups` 同时给时忽略(一个表里两套翻页说不清)。
74
+ */
75
+ onLoadMore?: () => void;
76
+ /** 追加 class(只允许补布局,不许覆盖皮肤)。 */
77
+ className?: string;
78
+ style?: CSSProperties;
79
+ /** 覆盖内置文案翻译(如插件自带 i18n)。 */
80
+ translate?: Translate;
81
+ }
82
+ /** `tableShell` 的渲染选项(内部参数,不进公开 props)。 */
83
+ interface TableShellOptions {
84
+ /**
85
+ * 底部哨兵元素的 ref:给了才渲染哨兵行(供调用方挂 IntersectionObserver)。
86
+ * 不给 = 不做滚动监听(`onLoadMore` 仍可透传,但不会自动触发)。
87
+ */
88
+ sentinelRef?: (node: HTMLTableRowElement | null) => void;
89
+ }
90
+ /**
91
+ * 表格共享渲染壳(**内部件,不进公开导出**)。
92
+ *
93
+ * 职责:基础层样式登记 + 语义化 `<table>` 结构 + 表头分组计算 + 行交互 + 列/单元格配置落地。
94
+ * 外观(表头底色 / 分隔线 / 悬浮 / 选中)由调用方的皮肤 CSS 负责:每个公开组件
95
+ * (`Table`、将来的 `TableGrid` / `TableZebra`)只 import 自己那份皮肤,并把自己的
96
+ * modifier class 传进来。这样消费方引哪个就只打包哪个 —— 绝不用 `variant` 汇总多份皮肤。
97
+ */
98
+ export declare function tableShell(skinClass: string, props: TableSharedProps, options?: TableShellOptions): ReturnType<typeof h>;
99
+ export {};
100
+ //# sourceMappingURL=table-shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-shared.d.ts","sourceRoot":"","sources":["../../src/ui/table-shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,CAAC,EAAE,KAAK,aAAa,EAAsB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAClG,OAAO,EAAK,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAGpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAE5D,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACtE,OAAO,EAKL,KAAK,YAAY,EAEjB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,UAAU,EAEf,KAAK,QAAQ,EACd,MAAM,kBAAkB,CAAA;AAEzB;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,OAAO,EAAE,SAAS,WAAW,EAAE,CAAA;IAC/B;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAA;IAC1B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;IAC9B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IACvC,iCAAiC;IACjC,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,2BAA2B;IAC3B,YAAY,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;IAC3C,sCAAsC;IACtC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACnD,sCAAsC;IACtC,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,qBAAqB,CAAA;IAClC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,6BAA6B;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qCAAqC;IACrC,UAAU,CAAC,EAAE,SAAS,CAAA;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AA2BD,2CAA2C;AAC3C,UAAU,iBAAiB;IACzB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,KAAK,IAAI,CAAA;CACzD;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,gBAAgB,EACvB,OAAO,GAAE,iBAAsB,GAC9B,UAAU,CAAC,OAAO,CAAC,CAAC,CAmStB"}
@@ -0,0 +1,222 @@
1
+ import { createElement as h } from 'react';
2
+ import { t } from '../utils/i18n.js';
3
+ import { ensureComponentStyles } from './css.js';
4
+ import { TABLE_BASE_CSS } from './controls-css.js';
5
+ import { Loader } from './Loader.js';
6
+ import { SectionHead } from './SectionHead.js';
7
+ import { headerRows, isTableCellSpec, leafColumns, } from './table-logic.js';
8
+ function widthOf(width) {
9
+ if (width === undefined)
10
+ return undefined;
11
+ return typeof width === 'number' ? `${width}px` : width;
12
+ }
13
+ /** 列级水平内距(覆盖 density 档);不传交给 CSS。 */
14
+ function padStyle(column) {
15
+ return column.padding === undefined ? undefined : { paddingInline: `${column.padding}px` };
16
+ }
17
+ function alignClass(prefix, align) {
18
+ return align === undefined || align === 'left' ? '' : ` ${prefix}--${align}`;
19
+ }
20
+ /**
21
+ * 某列在叶子序列里的位置决定画不画左竖线:
22
+ * 首列恒不画(那是外框的位置);其余列只在「想要线」时画。
23
+ * 分组列自己不写 `divider` 时,跟随它第一个叶子列 —— 组头的左缘和第一个子列的左缘
24
+ * 是同一条线,否则「组头无线、下面子列有线」会断成两截(2026-10-30 用户真机指出)。
25
+ */
26
+ function dividerAttr(leafIndex, wanted) {
27
+ if (leafIndex === 0)
28
+ return undefined;
29
+ return wanted === true ? 'left' : undefined;
30
+ }
31
+ /**
32
+ * 表格共享渲染壳(**内部件,不进公开导出**)。
33
+ *
34
+ * 职责:基础层样式登记 + 语义化 `<table>` 结构 + 表头分组计算 + 行交互 + 列/单元格配置落地。
35
+ * 外观(表头底色 / 分隔线 / 悬浮 / 选中)由调用方的皮肤 CSS 负责:每个公开组件
36
+ * (`Table`、将来的 `TableGrid` / `TableZebra`)只 import 自己那份皮肤,并把自己的
37
+ * modifier class 传进来。这样消费方引哪个就只打包哪个 —— 绝不用 `variant` 汇总多份皮肤。
38
+ */
39
+ export function tableShell(skinClass, props, options = {}) {
40
+ ensureComponentStyles('table-core', TABLE_BASE_CSS);
41
+ const tt = props.translate ?? t;
42
+ const headRows = headerRows(props.columns);
43
+ const leaves = leafColumns(props.columns);
44
+ const leafIndexByKey = new Map();
45
+ leaves.forEach((column, index) => {
46
+ leafIndexByKey.set(column.key, index);
47
+ });
48
+ const selected = new Set(props.selectedKeys ?? []);
49
+ const onRowClick = props.onRowClick;
50
+ const density = props.density ?? 'default';
51
+ const borders = props.borders ?? 'y';
52
+ /** 表头一行:分组表头按层级逐行渲染(每组重复渲染它,分组模式也要表头)。 */
53
+ const headRowOf = (cells, level) => h('tr', { key: `head-${level}`, className: 'dshpc-table__head-row' }, ...cells.map((cell) => {
54
+ const group = cell.colSpan > 1;
55
+ const firstLeafIndex = leafIndexByKey.get(cell.leafKeys[0] ?? '');
56
+ // 分组列没写 divider ⇒ 跟第一个叶子列走(两行列的左缘是同一条线)。
57
+ const firstLeaf = firstLeafIndex === undefined ? undefined : leaves[firstLeafIndex];
58
+ const className = `dshpc-table__head-cell${group ? ' dshpc-table__head-cell--group' : ''}${alignClass('dshpc-table__head-cell', cell.column.align)}`;
59
+ const tone = cell.column.headerTone;
60
+ return h('th', {
61
+ key: cell.column.key,
62
+ scope: group ? 'colgroup' : 'col',
63
+ colSpan: cell.colSpan > 1 ? cell.colSpan : undefined,
64
+ rowSpan: cell.rowSpan > 1 ? cell.rowSpan : undefined,
65
+ className,
66
+ style: padStyle(cell.column),
67
+ 'data-divider': firstLeafIndex === undefined
68
+ ? undefined
69
+ : dividerAttr(firstLeafIndex, cell.column.divider ?? firstLeaf?.divider),
70
+ 'data-header-tone': tone === undefined || tone === 'default' ? undefined : tone,
71
+ }, cell.column.title);
72
+ }));
73
+ /**
74
+ * 跨行单元格(rowSpan)把上下几行连成一个视觉块:块里任意一行被选中,整块都算选中。
75
+ * 先按 rowSpan 求每行所属块的范围 [start, end],再判断块内有没有选中行 ——
76
+ * 不依赖点击的是块里的哪一行,也不要求调用方自己展开。
77
+ */
78
+ const selectedBlocksOf = (rows) => {
79
+ const blocks = rows.map((_, index) => ({ start: index, end: index }));
80
+ rows.forEach((row, index) => {
81
+ for (const cell of Object.values(row.cells)) {
82
+ if (!isTableCellSpec(cell) || cell.rowSpan === undefined || cell.rowSpan <= 1)
83
+ continue;
84
+ const end = Math.min(index + cell.rowSpan - 1, rows.length - 1);
85
+ for (let line = index; line <= end; line += 1) {
86
+ const block = blocks[line];
87
+ if (block === undefined)
88
+ continue;
89
+ block.start = Math.min(block.start, index);
90
+ block.end = Math.max(block.end, end);
91
+ }
92
+ }
93
+ });
94
+ return blocks.map((block) => {
95
+ for (let line = block.start; line <= block.end; line += 1) {
96
+ const row = rows[line];
97
+ if (row !== undefined && selected.has(row.key))
98
+ return true;
99
+ }
100
+ return false;
101
+ });
102
+ };
103
+ /** 一组数据行(选中 / 可点 / 单元格配置都在这里落地)。 */
104
+ const dataRowsOf = (rows, offset = 0) => {
105
+ const selectedBlocks = selectedBlocksOf(rows);
106
+ return rows.map((row, index) => h('tr', {
107
+ key: row.key,
108
+ className: 'dshpc-table__row',
109
+ 'data-selected': selectedBlocks[index] === true ? 'true' : undefined,
110
+ 'data-interactive': onRowClick === undefined ? undefined : 'true',
111
+ tabIndex: onRowClick === undefined ? undefined : 0,
112
+ onClick: onRowClick === undefined ? undefined : () => onRowClick(row, offset + index),
113
+ onKeyDown: onRowClick === undefined
114
+ ? undefined
115
+ : (event) => {
116
+ if (event.key !== 'Enter' && event.key !== ' ')
117
+ return;
118
+ event.preventDefault();
119
+ onRowClick(row, offset + index);
120
+ },
121
+ }, ...leaves.map((column, leafIndex) => {
122
+ const cell = row.cells[column.key];
123
+ // 缺 key = 该格不渲染(上一行的 rowSpan 已经占了这个位置);要空格请显式传 null。
124
+ if (cell === undefined)
125
+ return null;
126
+ let spec;
127
+ let content;
128
+ if (isTableCellSpec(cell)) {
129
+ spec = cell;
130
+ content = cell.content;
131
+ }
132
+ else {
133
+ content = cell;
134
+ }
135
+ const align = spec?.align ?? column.align;
136
+ return h('td', {
137
+ key: column.key,
138
+ className: `dshpc-table__cell${alignClass('dshpc-table__cell', align)}`,
139
+ style: padStyle(column),
140
+ colSpan: spec?.colSpan !== undefined && spec.colSpan > 1 ? spec.colSpan : undefined,
141
+ rowSpan: spec?.rowSpan !== undefined && spec.rowSpan > 1 ? spec.rowSpan : undefined,
142
+ 'data-divider': dividerAttr(leafIndex, column.divider),
143
+ }, content ?? null);
144
+ })));
145
+ };
146
+ const colSpan = leaves.length > 0 ? leaves.length : undefined;
147
+ const emptyRow = h('tr', { key: 'empty', className: 'dshpc-table__row' }, h('td', { className: 'dshpc-table__empty', colSpan }, props.emptyText ?? tt('tableEmpty')));
148
+ // 整表加载:只在一条数据都没有时占位,不遮挡已有行(追加下一页请用 loadingMore)。
149
+ const loadingRow = h('tr', { key: 'loading', className: 'dshpc-table__state-row' }, h('td', { className: 'dshpc-table__state-cell', colSpan }, h('div', {
150
+ className: 'dshpc-table__state dshpc-table__state--full',
151
+ style: props.loadingHeight === undefined ? undefined : { height: `${props.loadingHeight}px` },
152
+ }, h(Loader, { variant: 'blocks', size: 'xl', label: tt('tableLoading') }))));
153
+ // 底部加载态:只在给了 onLoadMore(开关)时渲染,且 loadingMore 优先于「没有更多」。
154
+ const infinite = props.onLoadMore !== undefined;
155
+ const loadingMore = infinite && props.loadingMore === true;
156
+ const showNoMore = infinite && !loadingMore && props.hasMore === false && props.noMoreText !== false;
157
+ const footerRows = [];
158
+ if (loadingMore) {
159
+ footerRows.push(h('tr', { key: 'more', className: 'dshpc-table__state-row dshpc-table__state-row--footer' }, h('td', { className: 'dshpc-table__state-cell', colSpan }, h('div', { className: 'dshpc-table__state' }, h(Loader, { variant: 'blocks', size: 'md', label: tt('tableLoadingMore') })))));
160
+ }
161
+ else if (showNoMore) {
162
+ footerRows.push(h('tr', { key: 'end', className: 'dshpc-table__state-row dshpc-table__state-row--footer' }, h('td', { className: 'dshpc-table__state-cell', colSpan }, h('div', { className: 'dshpc-table__state' }, h('span', { className: 'dshpc-table__state-text' }, props.noMoreText === undefined ? tt('tableNoMore') : props.noMoreText)))));
163
+ }
164
+ // 底部哨兵:IntersectionObserver 的落点;hasMore === false 时没有下一页,不必再监听。
165
+ const sentinelRow = infinite && props.hasMore !== false && options.sentinelRef !== undefined
166
+ ? h('tr', {
167
+ key: 'sentinel',
168
+ ref: options.sentinelRef,
169
+ className: 'dshpc-table__sentinel',
170
+ 'aria-hidden': 'true',
171
+ }, h('td', { colSpan }))
172
+ : null;
173
+ // 没有左右外框(y / none)且底部有状态行时,表底那条横线也去掉 ——
174
+ // 状态行只保留上方一条实线,否则图标下面会多出一条孤线(2026-10-31 用户定)。
175
+ const flatFoot = footerRows.length > 0 && (borders === 'y' || borders === 'none');
176
+ const tableClass = [
177
+ 'dshpc-table',
178
+ skinClass,
179
+ `dshpc-table--density-${density}`,
180
+ `dshpc-table--borders-${borders}`,
181
+ props.striped === true ? 'dshpc-table--striped' : '',
182
+ flatFoot ? 'dshpc-table--foot-no-bottom' : '',
183
+ props.className ?? '',
184
+ ]
185
+ .filter((s) => s !== '')
186
+ .join(' ');
187
+ const groups = props.groups ?? [];
188
+ const body = groups.length > 0
189
+ ? groups.map((group, groupIndex) => h('tbody', { key: group.key, className: 'dshpc-table__body dshpc-table__group-body' },
190
+ // 通栏标题行:横跨所有列,充当这一组的「大标题」。
191
+ h('tr', { className: 'dshpc-table__group-row' }, h('th', {
192
+ className: 'dshpc-table__group-cell',
193
+ scope: 'colgroup',
194
+ colSpan: leaves.length > 0 ? leaves.length : undefined,
195
+ },
196
+ // 标题的固定标签(短竖线)与排版归 SectionHead —— Table 只负责把标题装进通栏。
197
+ h(SectionHead, {
198
+ title: group.title,
199
+ accent: props.groupAccent ?? 'default',
200
+ flush: true,
201
+ }))),
202
+ // 每组自带表头:分组模式不放在 <thead>(一个 table 只能有一个 thead)
203
+ ...headRows.map((cells, level) => headRowOf(cells, `g${groupIndex}-${level}`)), ...dataRowsOf(group.rows, 0)))
204
+ : [
205
+ h('tbody', { key: 'body', className: 'dshpc-table__body' }, props.loading === true && (props.rows?.length ?? 0) === 0
206
+ ? loadingRow
207
+ : props.rows !== undefined && props.rows.length > 0
208
+ ? dataRowsOf(props.rows)
209
+ : emptyRow, ...footerRows, sentinelRow),
210
+ ];
211
+ return h('table', { className: tableClass, style: props.style, 'aria-label': props.ariaLabel }, leaves.length === 0
212
+ ? null
213
+ : h('colgroup', null, ...leaves.map((column) => h('col', {
214
+ key: column.key,
215
+ style: widthOf(column.width) === undefined ? undefined : { width: widthOf(column.width) },
216
+ }))),
217
+ // 有分组时,每组的表头在各自的 tbody 里;单一表时表头在 thead。
218
+ groups.length > 0
219
+ ? null
220
+ : h('thead', { className: 'dshpc-table__head' }, ...headRows.map((cells, level) => headRowOf(cells, level))), ...body);
221
+ }
222
+ //# sourceMappingURL=table-shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-shared.js","sourceRoot":"","sources":["../../src/ui/table-shared.ts"],"names":[],"mappings":"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"}