@canvas-components/list-table 0.3.15 → 0.3.17
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.
- package/README.md +57 -2
- package/dist/index.cjs +222 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -5
- package/dist/index.d.ts +52 -5
- package/dist/index.js +223 -58
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -26,14 +26,69 @@
|
|
|
26
26
|
显式传入 `pagination.pageSize` 时以受控值为准。外部负责请求的封装(如 WWISuperTable)应在首次请求前读取缓存,初始化自己的分页状态,避免只改变显示值而请求条数不一致:
|
|
27
27
|
|
|
28
28
|
```ts
|
|
29
|
-
import { getListTableStoredPageSize } from
|
|
29
|
+
import { getListTableStoredPageSize } from "@canvas-components/list-table";
|
|
30
30
|
|
|
31
|
-
const initialPageSize =
|
|
31
|
+
const initialPageSize =
|
|
32
|
+
explicitPageSize ?? getListTableStoredPageSize(storageKey) ?? 10;
|
|
32
33
|
// 将 initialPageSize 用于首次请求和受控 pagination.pageSize。
|
|
33
34
|
```
|
|
34
35
|
|
|
35
36
|
该读取方法也由 `@canvas-components/react-list-table` 导出。
|
|
36
37
|
|
|
38
|
+
## 分区 CSS 样式
|
|
39
|
+
|
|
40
|
+
原生 `ListTable` 和 `ReactListTable` 均支持 `styles`。Canvas 区域通过 CSS 属性映射到绘制参数,不创建单元格 DOM,不注入全局样式。
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
styles: {
|
|
44
|
+
cell: { fontSize: '14px', padding: '2px 12px', borderColor: '#d9e1ec' },
|
|
45
|
+
header: { backgroundColor: '#f0f9ff', color: '#075985', fontWeight: 700, textAlign: 'center' },
|
|
46
|
+
body: { color: '#334155' },
|
|
47
|
+
summary: { backgroundColor: '#f0fdf4', color: '#166534', textAlign: 'right' },
|
|
48
|
+
activeCell: { backgroundColor: '#fef3c7', borderColor: '#d97706', borderWidth: '2px' },
|
|
49
|
+
activeRow: { backgroundColor: '#e0e7ff', color: '#3730a3' },
|
|
50
|
+
scrollVertical: { width: '14px', color: '#94a3b8', backgroundColor: '#f1f5f9', borderRadius: 4 },
|
|
51
|
+
scrollHorizontal: { height: '12px', color: '#64748b', backgroundColor: '#f8fafc' },
|
|
52
|
+
pagination: {
|
|
53
|
+
root: { backgroundColor: '#f8fafc', color: '#334155', fontSize: '14px' },
|
|
54
|
+
total: { color: '#64748b' },
|
|
55
|
+
pageItem: { borderRadius: 4 },
|
|
56
|
+
activePageItem: { backgroundColor: '#1677ff', color: '#fff' },
|
|
57
|
+
sizeChanger: { width: 140 },
|
|
58
|
+
quickJumperInput: { width: 64 },
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- `cell` 是表头、表体和汇总单元格的通用默认值;分区覆盖通用值,列级 `headerStyle` / `cellStyle` / `summaryStyle` 优先。
|
|
64
|
+
- Canvas 分区支持 `backgroundColor`、`color`、`fontSize`、`fontWeight`、`fontFamily`、`textAlign`、`verticalAlign`、`padding`、`paddingInline`、`paddingBlock`、`borderColor`、`borderWidth`。长度只支持非负数字或 `px`,`padding` 支持一值或“上下 左右”两值;不支持百分比、`em` 或 DOM 布局属性。
|
|
65
|
+
- `activeCell` 支持背景、文字和边框,`activeRow` 支持背景与文字;仅改变已有选中状态的绘制,不改变选择模式。校验错误提示仍优先。
|
|
66
|
+
- 滚动条 `color` 对应滑块、`backgroundColor` 对应槽色;纵轴 `width`、横轴 `height` 对应厚度。显式 `scrollbar.vertical/horizontal: false` 仍禁止对应轴显示。
|
|
67
|
+
- `pagination` 按节点直接应用 DOM CSS,使用 camelCase 属性名,数字长度按 React DOM 规则处理;仅影响当前实例。通过原生 UI 回调自行渲染分页器时,从 `PaginationConfig.styles` 读取并应用样式。当前分页占位高度仍由表格密度决定,避免设置超出该高度的高度或纵向间距。
|
|
68
|
+
|
|
69
|
+
分页器支持以下节点:
|
|
70
|
+
|
|
71
|
+
| 节点 | 作用 |
|
|
72
|
+
| --------------------------- | ---------------------------------------------------- |
|
|
73
|
+
| `root` | 分页器根容器,颜色、字体等可向内部继承 |
|
|
74
|
+
| `total` | 总条数文本 |
|
|
75
|
+
| `pages` | 页码列表容器 |
|
|
76
|
+
| `pageItem` | 普通页码按钮;简易模式下为页码文本 |
|
|
77
|
+
| `activePageItem` | 当前页按钮,叠加并覆盖 `pageItem` |
|
|
78
|
+
| `prevButton` / `nextButton` | 上一页 / 下一页按钮 |
|
|
79
|
+
| `prevIcon` / `nextIcon` | 上一页 / 下一页箭头,通过 `borderColor` 设置箭头颜色 |
|
|
80
|
+
| `ellipsis` | 页码省略号 |
|
|
81
|
+
| `sizeChanger` | 分页尺寸选择控件,不包含弹出选项面板 |
|
|
82
|
+
| `quickJumper` | 快速跳转区域容器 |
|
|
83
|
+
| `quickJumperText` | “跳至”和“页”文本 |
|
|
84
|
+
| `quickJumperInput` | 跳转输入控件外框,可设置宽度、背景与边框 |
|
|
85
|
+
|
|
86
|
+
节点样式优先于默认样式;未配置节点保持原样。独立使用 `ReactPagination` 时也支持同名 `styles`,其中 `styles.root` 优先于 `style`。
|
|
87
|
+
|
|
88
|
+
- 更新或移除 `styles` 后即时生效;不额外持久化 `styles` 对象,已有列配置缓存中的对齐设置仍优先。嵌套子表格的独立内容样式仍通过其列/内容配置指定。
|
|
89
|
+
|
|
90
|
+
文档站“主题”示例增加了“启用分区 CSS 样式”开关,可切换验证。
|
|
91
|
+
|
|
37
92
|
## 安装方法
|
|
38
93
|
|
|
39
94
|
```bash
|
package/dist/index.cjs
CHANGED
|
@@ -71,6 +71,87 @@ var DebugManager = class {
|
|
|
71
71
|
console.info(`[ListTable Debug] ${label}`, payload);
|
|
72
72
|
}
|
|
73
73
|
};
|
|
74
|
+
|
|
75
|
+
// src/services/table-styles-service.ts
|
|
76
|
+
function resolveStylePixels(value) {
|
|
77
|
+
if (typeof value === "string" && !/^\s*\d+(?:\.\d+)?(?:px)?\s*$/.test(value))
|
|
78
|
+
return void 0;
|
|
79
|
+
const number = typeof value === "string" ? parseFloat(value) : value;
|
|
80
|
+
return number != null && Number.isFinite(number) && number >= 0 ? number : void 0;
|
|
81
|
+
}
|
|
82
|
+
function resolveCanvasCellStyle(style) {
|
|
83
|
+
if (!style) return void 0;
|
|
84
|
+
const padding = typeof style.padding === "string" ? style.padding.trim().split(/\s+/) : [style.padding];
|
|
85
|
+
const result = {
|
|
86
|
+
backgroundColor: style.backgroundColor,
|
|
87
|
+
color: style.color,
|
|
88
|
+
fontSize: resolveStylePixels(style.fontSize),
|
|
89
|
+
fontWeight: style.fontWeight == null ? void 0 : String(style.fontWeight),
|
|
90
|
+
fontFamily: style.fontFamily,
|
|
91
|
+
textAlign: style.textAlign,
|
|
92
|
+
verticalAlign: style.verticalAlign,
|
|
93
|
+
paddingInline: resolveStylePixels(style.paddingInline) ?? (padding.length <= 2 ? resolveStylePixels(padding[1] ?? padding[0]) : void 0),
|
|
94
|
+
paddingBlock: resolveStylePixels(style.paddingBlock) ?? (padding.length <= 2 ? resolveStylePixels(padding[0]) : void 0),
|
|
95
|
+
borderColor: style.borderColor,
|
|
96
|
+
borderWidth: resolveStylePixels(style.borderWidth)
|
|
97
|
+
};
|
|
98
|
+
return Object.fromEntries(
|
|
99
|
+
Object.entries(result).filter(([, value]) => value !== void 0)
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
function resolveListTableStyleOptions(options) {
|
|
103
|
+
const styles = options.styles;
|
|
104
|
+
if (!styles) return options;
|
|
105
|
+
const cell = resolveCanvasCellStyle(styles.cell) ?? {};
|
|
106
|
+
const header = { ...cell, ...resolveCanvasCellStyle(styles.header) };
|
|
107
|
+
const body = { ...cell, ...resolveCanvasCellStyle(styles.body) };
|
|
108
|
+
const summary = { ...cell, ...resolveCanvasCellStyle(styles.summary) };
|
|
109
|
+
const mapColumns = (columns) => columns.map((column) => ({
|
|
110
|
+
...column,
|
|
111
|
+
align: column.align ?? (column.cellStyle?.textAlign ?? body.textAlign),
|
|
112
|
+
headerAlign: column.headerAlign ?? (column.headerStyle?.textAlign ?? column.align ?? header.textAlign),
|
|
113
|
+
cellStyle: { ...body, ...column.cellStyle },
|
|
114
|
+
headerStyle: { ...header, ...column.headerStyle },
|
|
115
|
+
summaryStyle: { ...summary, ...column.summaryStyle },
|
|
116
|
+
children: column.children ? mapColumns(column.children) : void 0
|
|
117
|
+
}));
|
|
118
|
+
const scrollbar = { ...options.scrollbar };
|
|
119
|
+
for (const axis of ["vertical", "horizontal"]) {
|
|
120
|
+
const style = axis === "vertical" ? styles.scrollVertical : styles.scrollHorizontal;
|
|
121
|
+
if (!style || scrollbar[axis] === false) continue;
|
|
122
|
+
const mapped = {
|
|
123
|
+
thumbColor: style.color,
|
|
124
|
+
trackColor: style.backgroundColor,
|
|
125
|
+
thickness: resolveStylePixels(
|
|
126
|
+
axis === "vertical" ? style.width : style.height
|
|
127
|
+
),
|
|
128
|
+
thumbRadius: resolveStylePixels(style.borderRadius)
|
|
129
|
+
};
|
|
130
|
+
scrollbar[axis] = {
|
|
131
|
+
...scrollbar[axis],
|
|
132
|
+
...Object.fromEntries(
|
|
133
|
+
Object.entries(mapped).filter(([, value]) => value !== void 0)
|
|
134
|
+
)
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
...options,
|
|
139
|
+
columns: mapColumns(options.columns),
|
|
140
|
+
scrollbar,
|
|
141
|
+
theme: {
|
|
142
|
+
...options.theme,
|
|
143
|
+
...cell.borderColor ? { borderColor: cell.borderColor } : {},
|
|
144
|
+
...cell.fontSize != null ? { fontSize: cell.fontSize } : {},
|
|
145
|
+
...cell.fontFamily ? { fontFamily: cell.fontFamily } : {},
|
|
146
|
+
...body.color ? { textColor: body.color } : {},
|
|
147
|
+
...header.backgroundColor ? { headerBackgroundColor: header.backgroundColor } : {},
|
|
148
|
+
...header.color ? { headerTextColor: header.color } : {},
|
|
149
|
+
...body.backgroundColor ? { backgroundColor: body.backgroundColor } : {},
|
|
150
|
+
activeCellStyle: resolveCanvasCellStyle(styles.activeCell),
|
|
151
|
+
activeRowStyle: resolveCanvasCellStyle(styles.activeRow)
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
74
155
|
function resolveColumnKey(column) {
|
|
75
156
|
return column.key?.trim() || utils.stringifyDataIndex(column.dataIndex);
|
|
76
157
|
}
|
|
@@ -585,15 +666,19 @@ function stretchColumnWidths(columns, containerWidth) {
|
|
|
585
666
|
}
|
|
586
667
|
const extra = containerWidth - totalWidth;
|
|
587
668
|
const stretchableWidth = computeColumnWidths(stretchableColumns);
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
669
|
+
let accumulatedWidth = 0;
|
|
670
|
+
let allocatedExtra = 0;
|
|
671
|
+
stretchableColumns.forEach((column, index) => {
|
|
672
|
+
accumulatedWidth += column.width;
|
|
673
|
+
const targetExtra = index === stretchableColumns.length - 1 ? extra : Math.min(
|
|
674
|
+
extra,
|
|
675
|
+
Math.floor(
|
|
676
|
+
extra * (stretchableWidth > 0 ? accumulatedWidth / stretchableWidth : (index + 1) / stretchableColumns.length)
|
|
677
|
+
)
|
|
678
|
+
);
|
|
679
|
+
column.width += targetExtra - allocatedExtra;
|
|
680
|
+
allocatedExtra = targetExtra;
|
|
681
|
+
});
|
|
597
682
|
}
|
|
598
683
|
function shrinkColumnWidthsToFit(columns, containerWidth) {
|
|
599
684
|
let remaining = Math.max(
|
|
@@ -693,6 +778,7 @@ function normalizeColumn(column, depth, parentKey) {
|
|
|
693
778
|
moneyFormat: column.moneyFormat,
|
|
694
779
|
dataFormat: column.dataFormat,
|
|
695
780
|
headerStyle: column.headerStyle,
|
|
781
|
+
summaryStyle: column.summaryStyle,
|
|
696
782
|
summary: column.summary,
|
|
697
783
|
summaryTitle: column.summaryTitle,
|
|
698
784
|
meta: column.meta,
|
|
@@ -7203,10 +7289,11 @@ function roundRectPath(ctx, x, y, width, height, radius) {
|
|
|
7203
7289
|
}
|
|
7204
7290
|
|
|
7205
7291
|
// src/rendering/primitives/draw-grid.ts
|
|
7206
|
-
function drawGridRect(ctx, rect, theme, borderColor = theme.borderColor) {
|
|
7292
|
+
function drawGridRect(ctx, rect, theme, borderColor = theme.borderColor, borderWidth = 1) {
|
|
7293
|
+
if (borderWidth <= 0) return;
|
|
7207
7294
|
ctx.save();
|
|
7208
7295
|
ctx.strokeStyle = borderColor;
|
|
7209
|
-
ctx.lineWidth =
|
|
7296
|
+
ctx.lineWidth = borderWidth;
|
|
7210
7297
|
ctx.beginPath();
|
|
7211
7298
|
const showTop = rect.y > 0;
|
|
7212
7299
|
const showLeft = rect.x > 0;
|
|
@@ -7238,7 +7325,8 @@ function resolveHeaderTextLayout(params) {
|
|
|
7238
7325
|
allowActions,
|
|
7239
7326
|
hasFilter,
|
|
7240
7327
|
contentInsetStart = 0,
|
|
7241
|
-
contentInsetEnd = 0
|
|
7328
|
+
contentInsetEnd = 0,
|
|
7329
|
+
paddingInline = HEADER_TEXT_PADDING
|
|
7242
7330
|
} = params;
|
|
7243
7331
|
const contentRect = {
|
|
7244
7332
|
x: rect.x + contentInsetStart,
|
|
@@ -7260,11 +7348,11 @@ function resolveHeaderTextLayout(params) {
|
|
|
7260
7348
|
contentRect,
|
|
7261
7349
|
contentVisibleRect,
|
|
7262
7350
|
align,
|
|
7263
|
-
|
|
7351
|
+
paddingInline
|
|
7264
7352
|
);
|
|
7265
7353
|
const baseLayout = {
|
|
7266
7354
|
align,
|
|
7267
|
-
maxWidth: Math.max(contentVisibleRect.width -
|
|
7355
|
+
maxWidth: Math.max(contentVisibleRect.width - paddingInline * 2, 12),
|
|
7268
7356
|
x: baseX
|
|
7269
7357
|
};
|
|
7270
7358
|
if (!allowActions || !actionVisibilityState.visible || align === "left") {
|
|
@@ -7276,10 +7364,10 @@ function resolveHeaderTextLayout(params) {
|
|
|
7276
7364
|
trailingInset: contentInsetEnd
|
|
7277
7365
|
});
|
|
7278
7366
|
const textRight = Math.min(
|
|
7279
|
-
contentVisibleRect.x + contentVisibleRect.width -
|
|
7280
|
-
actionLayout.startX -
|
|
7367
|
+
contentVisibleRect.x + contentVisibleRect.width - paddingInline,
|
|
7368
|
+
actionLayout.startX - paddingInline
|
|
7281
7369
|
);
|
|
7282
|
-
const textLeft = contentVisibleRect.x +
|
|
7370
|
+
const textLeft = contentVisibleRect.x + paddingInline;
|
|
7283
7371
|
if (align === "center") {
|
|
7284
7372
|
const centeredWidth = Math.max(
|
|
7285
7373
|
Math.min(baseX - textLeft, textRight - baseX) * 2,
|
|
@@ -7414,9 +7502,15 @@ function drawHeaderCell(params, cell, clipRect) {
|
|
|
7414
7502
|
const isRangeSelected = isHeaderCellInRange(params.rangeHighlight, cell);
|
|
7415
7503
|
ctx.fillStyle = isSelected || isRangeSelected ? theme.selectionBackgroundColor : cell.node.style?.backgroundColor ?? theme.headerBackgroundColor;
|
|
7416
7504
|
ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
|
|
7417
|
-
drawGridRect(
|
|
7505
|
+
drawGridRect(
|
|
7506
|
+
ctx,
|
|
7507
|
+
rect,
|
|
7508
|
+
theme,
|
|
7509
|
+
cell.node.style?.borderColor,
|
|
7510
|
+
cell.node.style?.borderWidth
|
|
7511
|
+
);
|
|
7418
7512
|
ctx.fillStyle = cell.node.style?.color ?? theme.headerTextColor;
|
|
7419
|
-
ctx.font = `${theme.headerFontWeight} ${theme.fontSize}px ${theme.fontFamily}`;
|
|
7513
|
+
ctx.font = `${cell.node.style?.fontWeight ?? theme.headerFontWeight} ${cell.node.style?.fontSize ?? theme.fontSize}px ${cell.node.style?.fontFamily ?? theme.fontFamily}`;
|
|
7420
7514
|
ctx.textBaseline = "middle";
|
|
7421
7515
|
const visibleRect = clipRect ? intersectRects(rect, clipRect) : rect;
|
|
7422
7516
|
if (!visibleRect) {
|
|
@@ -7448,6 +7542,7 @@ function drawHeaderCell(params, cell, clipRect) {
|
|
|
7448
7542
|
allowActions: cell.node.children.length === 0,
|
|
7449
7543
|
hasFilter: params.filterableColumnKeys.has(cell.node.key),
|
|
7450
7544
|
contentWidth: measureHeaderContentWidth(ctx, titleContent),
|
|
7545
|
+
paddingInline: cell.node.style?.paddingInline,
|
|
7451
7546
|
contentInsetStart: resolveHeaderContentInsetStart({
|
|
7452
7547
|
columnKey: cell.node.key,
|
|
7453
7548
|
hasChildren: cell.node.children.length > 0,
|
|
@@ -7459,7 +7554,7 @@ function drawHeaderCell(params, cell, clipRect) {
|
|
|
7459
7554
|
const textY = resolveHeaderContentCenterY(
|
|
7460
7555
|
rect,
|
|
7461
7556
|
titleContent,
|
|
7462
|
-
theme.fontSize,
|
|
7557
|
+
cell.node.style?.fontSize ?? theme.fontSize,
|
|
7463
7558
|
cell.node.style?.paddingBlock ?? params.defaultPaddingBlock ?? resolveDensityPaddingBlock(cell.height),
|
|
7464
7559
|
cell.node.style?.verticalAlign
|
|
7465
7560
|
);
|
|
@@ -8121,6 +8216,11 @@ function drawSummarySegment(params, columns, clipRect, defaultTitleColumnKey) {
|
|
|
8121
8216
|
function drawSummaryCell(ctx, rect, column, theme, summaryValues, selectedHeaderKey, summarySelected, rangeHighlight, clipRect, descriptors, inlineContentInset, defaultTitleColumnKey, textSelection) {
|
|
8122
8217
|
ctx.save();
|
|
8123
8218
|
const cellClip = clipRect ? intersectRects2(rect, clipRect) : rect;
|
|
8219
|
+
const style = column.summaryStyle;
|
|
8220
|
+
const fontSize = style?.fontSize ?? theme.fontSize;
|
|
8221
|
+
const paddingInline = style?.paddingInline ?? 12;
|
|
8222
|
+
const paddingBlock = style?.paddingBlock ?? 0;
|
|
8223
|
+
const textY = style?.verticalAlign === "top" ? rect.y + paddingBlock + fontSize / 2 : style?.verticalAlign === "bottom" ? rect.y + rect.height - paddingBlock - fontSize / 2 : rect.y + rect.height / 2;
|
|
8124
8224
|
if (!cellClip) {
|
|
8125
8225
|
ctx.restore();
|
|
8126
8226
|
return;
|
|
@@ -8130,9 +8230,9 @@ function drawSummaryCell(ctx, rect, column, theme, summaryValues, selectedHeader
|
|
|
8130
8230
|
column.leafIndex,
|
|
8131
8231
|
(rangeHighlight ?? EMPTY_RANGE_HIGHLIGHT2).selectedColumnRange
|
|
8132
8232
|
);
|
|
8133
|
-
ctx.fillStyle = summarySelected || isHeaderColumnSelected || isColumnRangeSelected ? theme.selectionBackgroundColor : theme.headerBackgroundColor;
|
|
8233
|
+
ctx.fillStyle = summarySelected || isHeaderColumnSelected || isColumnRangeSelected ? theme.selectionBackgroundColor : style?.backgroundColor ?? theme.headerBackgroundColor;
|
|
8134
8234
|
ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
|
|
8135
|
-
drawGridRect(ctx, rect, theme);
|
|
8235
|
+
drawGridRect(ctx, rect, theme, style?.borderColor, style?.borderWidth);
|
|
8136
8236
|
const resolvedDisplayValue = resolveSummaryCellDisplayValue(
|
|
8137
8237
|
column,
|
|
8138
8238
|
summaryValues?.get(column.key),
|
|
@@ -8143,10 +8243,10 @@ function drawSummaryCell(ctx, rect, column, theme, summaryValues, selectedHeader
|
|
|
8143
8243
|
ctx.beginPath();
|
|
8144
8244
|
ctx.rect(cellClip.x, cellClip.y, cellClip.width, cellClip.height);
|
|
8145
8245
|
ctx.clip();
|
|
8146
|
-
ctx.fillStyle = theme.headerTextColor;
|
|
8147
|
-
ctx.font =
|
|
8246
|
+
ctx.fillStyle = style?.color ?? theme.headerTextColor;
|
|
8247
|
+
ctx.font = `${style?.fontWeight ?? "600"} ${fontSize}px ${style?.fontFamily ?? theme.fontFamily}`;
|
|
8148
8248
|
ctx.textBaseline = "middle";
|
|
8149
|
-
const align = column.align ?? "left";
|
|
8249
|
+
const align = style?.textAlign ?? column.align ?? "left";
|
|
8150
8250
|
ctx.textAlign = align;
|
|
8151
8251
|
const contentInsetStart = column.key === inlineContentInset?.columnKey ? inlineContentInset.width : 0;
|
|
8152
8252
|
const contentRect = {
|
|
@@ -8159,16 +8259,16 @@ function drawSummaryCell(ctx, rect, column, theme, summaryValues, selectedHeader
|
|
|
8159
8259
|
rect: contentRect,
|
|
8160
8260
|
visibleRect,
|
|
8161
8261
|
align,
|
|
8162
|
-
padding:
|
|
8262
|
+
padding: paddingInline
|
|
8163
8263
|
});
|
|
8164
8264
|
const displayText = resolveSummaryDisplayText(ctx, {
|
|
8165
8265
|
text: resolvedDisplayValue,
|
|
8166
8266
|
visibleRect,
|
|
8167
|
-
padding:
|
|
8267
|
+
padding: paddingInline
|
|
8168
8268
|
});
|
|
8169
8269
|
const textWidth = ctx.measureText(displayText).width;
|
|
8170
8270
|
const textOriginX = textX - (align === "right" ? textWidth : align === "center" ? textWidth / 2 : 0);
|
|
8171
|
-
const textTop =
|
|
8271
|
+
const textTop = textY - fontSize / 2;
|
|
8172
8272
|
const fragmentKey = `summary:${column.key}`;
|
|
8173
8273
|
drawSelectableTextSelectionBackground({
|
|
8174
8274
|
ctx,
|
|
@@ -8176,14 +8276,14 @@ function drawSummaryCell(ctx, rect, column, theme, summaryValues, selectedHeader
|
|
|
8176
8276
|
textSelection,
|
|
8177
8277
|
textOriginX,
|
|
8178
8278
|
textTop,
|
|
8179
|
-
textHeight:
|
|
8279
|
+
textHeight: fontSize,
|
|
8180
8280
|
rowIndex: Number.MAX_SAFE_INTEGER,
|
|
8181
8281
|
columnKey: column.key,
|
|
8182
8282
|
contentIndex: 0,
|
|
8183
8283
|
fragmentKey,
|
|
8184
8284
|
color: theme.textSelectionBackgroundColor ?? "#99c2ff"
|
|
8185
8285
|
});
|
|
8186
|
-
ctx.fillText(displayText, textX,
|
|
8286
|
+
ctx.fillText(displayText, textX, textY);
|
|
8187
8287
|
textDescriptor = {
|
|
8188
8288
|
rowIndex: Number.MAX_SAFE_INTEGER,
|
|
8189
8289
|
contentIndex: 0,
|
|
@@ -8196,7 +8296,7 @@ function drawSummaryCell(ctx, rect, column, theme, summaryValues, selectedHeader
|
|
|
8196
8296
|
x: textOriginX,
|
|
8197
8297
|
y: textTop,
|
|
8198
8298
|
width: textWidth,
|
|
8199
|
-
height:
|
|
8299
|
+
height: fontSize
|
|
8200
8300
|
},
|
|
8201
8301
|
cellClip
|
|
8202
8302
|
) ?? void 0,
|
|
@@ -10957,6 +11057,25 @@ function normalizeCellContents(contents) {
|
|
|
10957
11057
|
}
|
|
10958
11058
|
return [normalizeCellContentItem(contents)];
|
|
10959
11059
|
}
|
|
11060
|
+
function applyCellTextStyle(contents, column) {
|
|
11061
|
+
const { color, fontSize, fontWeight, fontFamily } = column.cellStyle ?? {};
|
|
11062
|
+
if (color == null && fontSize == null && fontWeight == null && fontFamily == null)
|
|
11063
|
+
return contents;
|
|
11064
|
+
return contents.map((content) => ({
|
|
11065
|
+
...content,
|
|
11066
|
+
style: {
|
|
11067
|
+
...color != null ? { color } : {},
|
|
11068
|
+
...fontSize != null ? { fontSize } : {},
|
|
11069
|
+
...fontWeight != null ? { fontWeight } : {},
|
|
11070
|
+
...fontFamily != null ? { fontFamily } : {},
|
|
11071
|
+
..."color" in content && content.color != null ? { color: content.color } : {},
|
|
11072
|
+
..."textColor" in content && content.textColor != null ? { color: content.textColor } : {},
|
|
11073
|
+
..."fontSize" in content && content.fontSize != null ? { fontSize: content.fontSize } : {},
|
|
11074
|
+
..."fontWeight" in content && content.fontWeight != null ? { fontWeight: content.fontWeight } : {},
|
|
11075
|
+
...content.style
|
|
11076
|
+
}
|
|
11077
|
+
}));
|
|
11078
|
+
}
|
|
10960
11079
|
function normalizeDrawableCellContents(contents) {
|
|
10961
11080
|
return contents.filter(
|
|
10962
11081
|
(content) => content.visible !== false && content.style?.display !== "none"
|
|
@@ -11130,7 +11249,10 @@ function drawBodyCellContents(params) {
|
|
|
11130
11249
|
skipNestedTableOuterBorders,
|
|
11131
11250
|
defaultRowHeight
|
|
11132
11251
|
} = params;
|
|
11133
|
-
const contents =
|
|
11252
|
+
const contents = applyCellTextStyle(
|
|
11253
|
+
normalizeDrawableCellContents(params.contents),
|
|
11254
|
+
column
|
|
11255
|
+
);
|
|
11134
11256
|
if (contents.length === 0) {
|
|
11135
11257
|
return void 0;
|
|
11136
11258
|
}
|
|
@@ -11365,7 +11487,10 @@ function appendClippedContentDescriptors(descriptors, itemDescriptors, visibleRe
|
|
|
11365
11487
|
}
|
|
11366
11488
|
function measureBodyCellContentsHeight(params) {
|
|
11367
11489
|
const { ctx, column, theme } = params;
|
|
11368
|
-
const contents =
|
|
11490
|
+
const contents = applyCellTextStyle(
|
|
11491
|
+
normalizeDrawableCellContents(params.contents),
|
|
11492
|
+
column
|
|
11493
|
+
);
|
|
11369
11494
|
if (contents.length === 0) {
|
|
11370
11495
|
return 0;
|
|
11371
11496
|
}
|
|
@@ -11395,7 +11520,10 @@ function measureBodyCellContentsHeight(params) {
|
|
|
11395
11520
|
}
|
|
11396
11521
|
function measureBodyCellContentsWidth(params) {
|
|
11397
11522
|
const { ctx, column, theme } = params;
|
|
11398
|
-
const contents =
|
|
11523
|
+
const contents = applyCellTextStyle(
|
|
11524
|
+
normalizeDrawableCellContents(params.contents),
|
|
11525
|
+
column
|
|
11526
|
+
);
|
|
11399
11527
|
if (contents.length === 0) {
|
|
11400
11528
|
return 0;
|
|
11401
11529
|
}
|
|
@@ -20324,7 +20452,9 @@ var ListTableEventController = class {
|
|
|
20324
20452
|
event.clientX,
|
|
20325
20453
|
event.clientY
|
|
20326
20454
|
);
|
|
20327
|
-
const result = this.host.resolvePointerHit(position.x, position.y
|
|
20455
|
+
const result = this.host.resolvePointerHit(position.x, position.y, {
|
|
20456
|
+
excludeKinds: ["resize-handle"]
|
|
20457
|
+
});
|
|
20328
20458
|
const rawContextResult = typeof result.hitRowIndex === "number" ? { ...result, rowIndex: result.hitRowIndex } : result;
|
|
20329
20459
|
const bodyRows = this.resolveBodyRows();
|
|
20330
20460
|
const contextResult = hydrateBodyContentHitResult({
|
|
@@ -24286,13 +24416,22 @@ function drawSegmentRows(params, segment, columns, startRowIndex, endRowIndex, r
|
|
|
24286
24416
|
collapseConfig: params.collapseConfig
|
|
24287
24417
|
}) : [];
|
|
24288
24418
|
const cellDescriptorStartIndex = params.descriptors.length;
|
|
24419
|
+
const activeStyle = isSelected || isSelectedCellRange ? params.theme.activeCellStyle : isRangeHighlighted ? params.theme.activeRowStyle : void 0;
|
|
24420
|
+
const styledColumn = activeStyle ? {
|
|
24421
|
+
...cell.column,
|
|
24422
|
+
cellStyle: { ...cell.column.cellStyle, ...activeStyle }
|
|
24423
|
+
} : cell.column;
|
|
24424
|
+
const cellTheme = activeStyle?.backgroundColor ? {
|
|
24425
|
+
...params.theme,
|
|
24426
|
+
selectionBackgroundColor: activeStyle.backgroundColor
|
|
24427
|
+
} : params.theme;
|
|
24289
24428
|
const cellTooltip = drawBodyCell(
|
|
24290
24429
|
ctx,
|
|
24291
24430
|
rect,
|
|
24292
24431
|
cell.record,
|
|
24293
24432
|
cell.sourceRowIndex,
|
|
24294
|
-
|
|
24295
|
-
|
|
24433
|
+
styledColumn,
|
|
24434
|
+
cellTheme,
|
|
24296
24435
|
params.rowBackgroundColor,
|
|
24297
24436
|
params.striped === true,
|
|
24298
24437
|
isHovered,
|
|
@@ -24339,11 +24478,12 @@ function drawSegmentRows(params, segment, columns, startRowIndex, endRowIndex, r
|
|
|
24339
24478
|
}
|
|
24340
24479
|
ctx.restore();
|
|
24341
24480
|
}
|
|
24342
|
-
function drawActiveCellBorder(ctx, rect) {
|
|
24343
|
-
|
|
24481
|
+
function drawActiveCellBorder(ctx, rect, borderColor = ACTIVE_CELL_BORDER_COLOR, borderWidth = 1) {
|
|
24482
|
+
if (borderWidth <= 0) return;
|
|
24483
|
+
const inset = borderWidth / 2;
|
|
24344
24484
|
ctx.save();
|
|
24345
|
-
ctx.strokeStyle =
|
|
24346
|
-
ctx.lineWidth =
|
|
24485
|
+
ctx.strokeStyle = borderColor;
|
|
24486
|
+
ctx.lineWidth = borderWidth;
|
|
24347
24487
|
ctx.strokeRect(
|
|
24348
24488
|
rect.x + inset,
|
|
24349
24489
|
rect.y + inset,
|
|
@@ -25011,7 +25151,13 @@ function drawBodyCell(ctx, rect, record, rowIndex, column, theme, rowBackgroundC
|
|
|
25011
25151
|
validationMessage
|
|
25012
25152
|
);
|
|
25013
25153
|
}
|
|
25014
|
-
drawGridRect(
|
|
25154
|
+
drawGridRect(
|
|
25155
|
+
ctx,
|
|
25156
|
+
rect,
|
|
25157
|
+
theme,
|
|
25158
|
+
column.cellStyle?.borderColor ?? theme.borderColor,
|
|
25159
|
+
column.cellStyle?.borderWidth
|
|
25160
|
+
);
|
|
25015
25161
|
ctx.restore();
|
|
25016
25162
|
return validationMessage ? {
|
|
25017
25163
|
text: validationMessage,
|
|
@@ -28524,6 +28670,7 @@ function renderListTablePagination(params) {
|
|
|
28524
28670
|
return;
|
|
28525
28671
|
}
|
|
28526
28672
|
const paginationConfig = {
|
|
28673
|
+
styles: options.styles?.pagination,
|
|
28527
28674
|
mode: paginationOptions.mode,
|
|
28528
28675
|
current: state.currentPage,
|
|
28529
28676
|
total: getPaginationTotal(options, total),
|
|
@@ -29271,6 +29418,7 @@ function drawActiveCellOverlay(params) {
|
|
|
29271
29418
|
return;
|
|
29272
29419
|
}
|
|
29273
29420
|
const { ctx, layout } = params;
|
|
29421
|
+
if (params.borderWidth === 0) return;
|
|
29274
29422
|
if (layout.rangeSegments?.length) {
|
|
29275
29423
|
layout.rangeSegments.forEach((segment) => {
|
|
29276
29424
|
ctx.save();
|
|
@@ -29282,8 +29430,8 @@ function drawActiveCellOverlay(params) {
|
|
|
29282
29430
|
segment.clipRect.height
|
|
29283
29431
|
);
|
|
29284
29432
|
ctx.clip();
|
|
29285
|
-
ctx.strokeStyle = "#1677ff";
|
|
29286
|
-
ctx.lineWidth = 1;
|
|
29433
|
+
ctx.strokeStyle = params.borderColor ?? "#1677ff";
|
|
29434
|
+
ctx.lineWidth = params.borderWidth ?? 1;
|
|
29287
29435
|
ctx.beginPath();
|
|
29288
29436
|
ctx.moveTo(segment.startX, segment.startY);
|
|
29289
29437
|
if (segment.controlX != null && segment.controlY != null) {
|
|
@@ -29305,7 +29453,13 @@ function drawActiveCellOverlay(params) {
|
|
|
29305
29453
|
ctx.beginPath();
|
|
29306
29454
|
ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
|
|
29307
29455
|
ctx.clip();
|
|
29308
|
-
drawRangeHighlightBorder(
|
|
29456
|
+
drawRangeHighlightBorder(
|
|
29457
|
+
ctx,
|
|
29458
|
+
rect,
|
|
29459
|
+
{ omitLeft, omitRight },
|
|
29460
|
+
params.borderColor,
|
|
29461
|
+
params.borderWidth
|
|
29462
|
+
);
|
|
29309
29463
|
ctx.restore();
|
|
29310
29464
|
});
|
|
29311
29465
|
}
|
|
@@ -29319,7 +29473,12 @@ function drawActiveCellOverlay(params) {
|
|
|
29319
29473
|
layout.clipRect.height
|
|
29320
29474
|
);
|
|
29321
29475
|
ctx.clip();
|
|
29322
|
-
drawActiveCellBorder(
|
|
29476
|
+
drawActiveCellBorder(
|
|
29477
|
+
ctx,
|
|
29478
|
+
layout.rect,
|
|
29479
|
+
params.borderColor,
|
|
29480
|
+
params.borderWidth
|
|
29481
|
+
);
|
|
29323
29482
|
ctx.restore();
|
|
29324
29483
|
}
|
|
29325
29484
|
}
|
|
@@ -29417,10 +29576,7 @@ function removeRangeSegmentsAtSharedLayerBoundaries(segments, ranges) {
|
|
|
29417
29576
|
return;
|
|
29418
29577
|
}
|
|
29419
29578
|
const top = Math.max(left.y, right.y);
|
|
29420
|
-
const bottom = Math.min(
|
|
29421
|
-
left.y + left.height,
|
|
29422
|
-
right.y + right.height
|
|
29423
|
-
);
|
|
29579
|
+
const bottom = Math.min(left.y + left.height, right.y + right.height);
|
|
29424
29580
|
if (bottom > top) {
|
|
29425
29581
|
sharedBoundaries.push({ x: boundary, top, bottom });
|
|
29426
29582
|
}
|
|
@@ -29610,10 +29766,10 @@ function subtractCoveredIntervals(start, end, coveredIntervals) {
|
|
|
29610
29766
|
([currentStart, currentEnd]) => currentEnd > currentStart
|
|
29611
29767
|
);
|
|
29612
29768
|
}
|
|
29613
|
-
function drawRangeHighlightBorder(ctx, rect, edges = {}) {
|
|
29769
|
+
function drawRangeHighlightBorder(ctx, rect, edges = {}, borderColor = "#1677ff", borderWidth = 1) {
|
|
29614
29770
|
ctx.save();
|
|
29615
|
-
ctx.strokeStyle =
|
|
29616
|
-
ctx.lineWidth =
|
|
29771
|
+
ctx.strokeStyle = borderColor;
|
|
29772
|
+
ctx.lineWidth = borderWidth;
|
|
29617
29773
|
const left = rect.x + 0.5;
|
|
29618
29774
|
const top = rect.y + 0.5;
|
|
29619
29775
|
const right = rect.x + Math.max(rect.width - 0.5, 0);
|
|
@@ -29909,6 +30065,8 @@ function executeListTableRenderPipeline(params) {
|
|
|
29909
30065
|
);
|
|
29910
30066
|
drawActiveCellOverlay({
|
|
29911
30067
|
ctx,
|
|
30068
|
+
borderColor: theme.activeCellStyle?.borderColor,
|
|
30069
|
+
borderWidth: theme.activeCellStyle?.borderWidth,
|
|
29912
30070
|
layout: resolveActiveCellOverlayLayout({
|
|
29913
30071
|
descriptors,
|
|
29914
30072
|
selection,
|
|
@@ -30353,9 +30511,10 @@ var ListTableRenderController = class {
|
|
|
30353
30511
|
const availableHeight = this.options.getContainerClientHeight() > 0 ? this.options.getContainerClientHeight() : hostSize.height;
|
|
30354
30512
|
const zoom = this.resolveZoom();
|
|
30355
30513
|
const layoutWidth = hostSize.width / zoom;
|
|
30356
|
-
const
|
|
30357
|
-
|
|
30358
|
-
|
|
30514
|
+
const measureSnapshot = this.buildSnapshot(
|
|
30515
|
+
layoutWidth,
|
|
30516
|
+
hostSize.height / zoom
|
|
30517
|
+
);
|
|
30359
30518
|
if (!measureSnapshot) {
|
|
30360
30519
|
this.options.setFittedHeight(null);
|
|
30361
30520
|
return;
|
|
@@ -30374,10 +30533,13 @@ var ListTableRenderController = class {
|
|
|
30374
30533
|
summaryHeight: measureSnapshot.bodyLayout.summaryHeight
|
|
30375
30534
|
});
|
|
30376
30535
|
const paginationElement = this.options.getPaginationElement();
|
|
30536
|
+
const scrollbar = this.options.getOptions().scrollbar;
|
|
30537
|
+
const horizontal = utils.resolveCanvasScrollbarAxis(scrollbar, "horizontal");
|
|
30538
|
+
const horizontalReserve = horizontal.visible && measureSnapshot.columnMetrics.centerContentWidth - measureSnapshot.columnMetrics.availableCenterWidth > 1 ? horizontal.thickness + Math.max(scrollbar?.horizontalBottom ?? 0, 0) : 0;
|
|
30377
30539
|
const paginationHeight = paginationElement && paginationElement.style.display !== "none" ? paginationElement.offsetHeight : 0;
|
|
30378
30540
|
const fittedHeight = resolveFittedTableHeight({
|
|
30379
30541
|
availableHeight,
|
|
30380
|
-
contentHeight: contentHeight * zoom + paginationHeight
|
|
30542
|
+
contentHeight: (contentHeight + horizontalReserve) * zoom + paginationHeight
|
|
30381
30543
|
});
|
|
30382
30544
|
this.options.setFittedHeight(
|
|
30383
30545
|
fittedHeight == null ? null : fittedHeight + TABLE_CONTENT_BORDER_SIZE
|
|
@@ -30663,6 +30825,7 @@ function resolvePaginationSignature(params) {
|
|
|
30663
30825
|
paginationConfig ? "enabled" : "disabled",
|
|
30664
30826
|
paginationConfig?.mode ?? "",
|
|
30665
30827
|
paginationConfig?.total ?? params.total,
|
|
30828
|
+
JSON.stringify(params.options.styles?.pagination ?? null),
|
|
30666
30829
|
params.total > 0 ? "nonempty" : "empty",
|
|
30667
30830
|
params.currentPage,
|
|
30668
30831
|
params.pageSize,
|
|
@@ -32568,6 +32731,7 @@ var ListTableCore = class {
|
|
|
32568
32731
|
/** 由 assembleListTableCoreControllers 在构造阶段挂载。 */
|
|
32569
32732
|
__publicField(this, "renderController");
|
|
32570
32733
|
__publicField(this, "debugManager");
|
|
32734
|
+
options = resolveListTableStyleOptions(options);
|
|
32571
32735
|
this.container = container;
|
|
32572
32736
|
this.options = options;
|
|
32573
32737
|
applyInitialColumnVisibility(options.columns);
|
|
@@ -32622,6 +32786,7 @@ var ListTableCore = class {
|
|
|
32622
32786
|
* @param options 新配置。
|
|
32623
32787
|
*/
|
|
32624
32788
|
updateOptions(options) {
|
|
32789
|
+
options = resolveListTableStyleOptions(options);
|
|
32625
32790
|
this.animationController.stopCarouselScroll();
|
|
32626
32791
|
const host = this.asAssemblyHost();
|
|
32627
32792
|
const shouldResetColumnConfig = shouldPersistIncomingColumnConfig(
|