@canvas-components/list-table 0.3.23 → 0.3.25
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 +3 -0
- package/dist/index.cjs +50 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +50 -15
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -247,6 +247,7 @@ table.mount();
|
|
|
247
247
|
| `theme` | `Partial<ListTableTheme>` | 主题覆盖 |
|
|
248
248
|
| `striped` | `boolean` | 是否开启斑马纹 |
|
|
249
249
|
| `highlightMode` | `"cell" \| "row" \| "column" \| "cross"` | 点击高亮模式 |
|
|
250
|
+
| `keyboardNavigation` | `{ tabWrap?: boolean; verticalWrap?: boolean }` | 键盘边界导航;两项默认均为 `true` |
|
|
250
251
|
| `contextMenu` | `false \| ListTableContextMenuOptions` | 右键菜单配置 |
|
|
251
252
|
| `grouping` | `ListTableGroupingOptions` | 分组栏、初始分组列与变化回调 |
|
|
252
253
|
| `rowHeight` | `number \| "auto"` | 行高 |
|
|
@@ -268,6 +269,8 @@ table.mount();
|
|
|
268
269
|
| `rowDrag` | `ListTableRowDragOptions` | 行拖拽配置 |
|
|
269
270
|
| `debug` | `ListTableDebugOptions` | 调试配置 |
|
|
270
271
|
|
|
272
|
+
`keyboardNavigation.tabWrap` 控制 Tab / Shift+Tab 在行尾 / 行首是否进入相邻行;`verticalWrap` 控制 ↑ / ↓ 在列首 / 列尾是否进入相邻列。设为 `false` 时到对应边界即停止,不改变当前活动单元格。
|
|
273
|
+
|
|
271
274
|
### 分批加载与服务端汇总
|
|
272
275
|
|
|
273
276
|
数据仍在异步生成或分批加载时,设置表格顶层属性 `loading: true`。此时汇总行及标题正常显示,统计结果保持空白,也不会计算首批临时数据。完整数据就绪后,将完整 `dataSource` 与 `loading: false` 一起更新,表格自动计算汇总并在完成后统一显示结果。默认值为 `false`,正常的空数据仍可汇总为零。
|
package/dist/index.cjs
CHANGED
|
@@ -2134,7 +2134,7 @@ function createEmptySelection() {
|
|
|
2134
2134
|
};
|
|
2135
2135
|
}
|
|
2136
2136
|
function resolveAdjacentCellSelection(params) {
|
|
2137
|
-
const { selection, rowCount, columnKeys, direction } = params;
|
|
2137
|
+
const { selection, rowCount, columnKeys, direction, verticalWrap = true } = params;
|
|
2138
2138
|
if (selection.rowIndex == null || selection.columnKey == null || selection.rowIndex < 0 || selection.rowIndex >= rowCount) {
|
|
2139
2139
|
return null;
|
|
2140
2140
|
}
|
|
@@ -2143,6 +2143,10 @@ function resolveAdjacentCellSelection(params) {
|
|
|
2143
2143
|
return null;
|
|
2144
2144
|
}
|
|
2145
2145
|
if (direction === "up" || direction === "down") {
|
|
2146
|
+
const nextRowIndex = selection.rowIndex + (direction === "up" ? -1 : 1);
|
|
2147
|
+
if (!verticalWrap) {
|
|
2148
|
+
return nextRowIndex < 0 || nextRowIndex >= rowCount ? null : { rowIndex: nextRowIndex, columnKey: selection.columnKey };
|
|
2149
|
+
}
|
|
2146
2150
|
const flatIndex = columnIndex * rowCount + selection.rowIndex;
|
|
2147
2151
|
const nextFlatIndex = flatIndex + (direction === "up" ? -1 : 1);
|
|
2148
2152
|
const cellCount = rowCount * columnKeys.length;
|
|
@@ -2165,7 +2169,7 @@ function resolveAdjacentCellSelection(params) {
|
|
|
2165
2169
|
};
|
|
2166
2170
|
}
|
|
2167
2171
|
function resolveTabCellSelection(params) {
|
|
2168
|
-
const { selection, rowCount, columnKeys, reverse = false } = params;
|
|
2172
|
+
const { selection, rowCount, columnKeys, reverse = false, tabWrap = true } = params;
|
|
2169
2173
|
if (selection.rowIndex == null || selection.columnKey == null || selection.rowIndex < 0 || selection.rowIndex >= rowCount || columnKeys.length === 0) {
|
|
2170
2174
|
return null;
|
|
2171
2175
|
}
|
|
@@ -2173,6 +2177,13 @@ function resolveTabCellSelection(params) {
|
|
|
2173
2177
|
if (columnIndex < 0) {
|
|
2174
2178
|
return null;
|
|
2175
2179
|
}
|
|
2180
|
+
if (!tabWrap) {
|
|
2181
|
+
const nextColumnIndex = columnIndex + (reverse ? -1 : 1);
|
|
2182
|
+
return nextColumnIndex < 0 || nextColumnIndex >= columnKeys.length ? null : {
|
|
2183
|
+
rowIndex: selection.rowIndex,
|
|
2184
|
+
columnKey: columnKeys[nextColumnIndex]
|
|
2185
|
+
};
|
|
2186
|
+
}
|
|
2176
2187
|
const flatIndex = selection.rowIndex * columnKeys.length + columnIndex;
|
|
2177
2188
|
const nextFlatIndex = flatIndex + (reverse ? -1 : 1);
|
|
2178
2189
|
const cellCount = rowCount * columnKeys.length;
|
|
@@ -8711,6 +8722,7 @@ function drawHeaderCell(params, cell, clipRect) {
|
|
|
8711
8722
|
rect: getHeaderSelectionRect(rect),
|
|
8712
8723
|
columnKey: cell.node.key,
|
|
8713
8724
|
controlType: params.rowSelection.type,
|
|
8725
|
+
cursor: params.rowSelection.disabled ? "not-allowed" : "pointer",
|
|
8714
8726
|
fixed: cell.node.fixed
|
|
8715
8727
|
});
|
|
8716
8728
|
}
|
|
@@ -8900,6 +8912,7 @@ function drawHeaderActions(params, rect, columnKey, visibilityState, fixed, visi
|
|
|
8900
8912
|
rect: hitRect,
|
|
8901
8913
|
columnKey,
|
|
8902
8914
|
actionType,
|
|
8915
|
+
cursor: "pointer",
|
|
8903
8916
|
visibilityState,
|
|
8904
8917
|
fixed
|
|
8905
8918
|
});
|
|
@@ -11099,7 +11112,7 @@ function drawBodySelectionContent(params) {
|
|
|
11099
11112
|
controlType: content.type,
|
|
11100
11113
|
contentIndex,
|
|
11101
11114
|
contentKey: content.key,
|
|
11102
|
-
cursor: content.disabled === true ? "not-allowed" : content.cursor ?? (content.onClick ? "pointer" : void 0)
|
|
11115
|
+
cursor: content.disabled === true ? "not-allowed" : content.cursor ?? (content.onClick || column.key === ROW_SELECTION_COLUMN_KEY ? "pointer" : void 0)
|
|
11103
11116
|
});
|
|
11104
11117
|
return controlRect.width;
|
|
11105
11118
|
}
|
|
@@ -11115,7 +11128,14 @@ function drawSelectionControl(ctx, rect, type, checked, disabled, indeterminate
|
|
|
11115
11128
|
ctx.fillStyle = fillColor;
|
|
11116
11129
|
ctx.strokeStyle = strokeColor;
|
|
11117
11130
|
ctx.lineWidth = 1.5;
|
|
11118
|
-
roundRectPath2(
|
|
11131
|
+
roundRectPath2(
|
|
11132
|
+
ctx,
|
|
11133
|
+
rect.x + 1,
|
|
11134
|
+
rect.y + 1,
|
|
11135
|
+
Math.max(rect.width - 2, 0),
|
|
11136
|
+
Math.max(rect.height - 2, 0),
|
|
11137
|
+
4
|
|
11138
|
+
);
|
|
11119
11139
|
ctx.fill();
|
|
11120
11140
|
ctx.stroke();
|
|
11121
11141
|
if (indeterminate) {
|
|
@@ -17990,9 +18010,7 @@ async function exportAllRowsTxtContent(params) {
|
|
|
17990
18010
|
});
|
|
17991
18011
|
}
|
|
17992
18012
|
async function exportAllRowsXlsxContent(params) {
|
|
17993
|
-
const columns = params.columns.filter(
|
|
17994
|
-
(column) => column.key !== ROW_SELECTION_COLUMN_KEY && column.key !== ROW_SELECTOR_COLUMN_KEY
|
|
17995
|
-
);
|
|
18013
|
+
const columns = params.columns.filter(isExportableColumn);
|
|
17996
18014
|
const footerRows = [];
|
|
17997
18015
|
if (params.includeSummary) {
|
|
17998
18016
|
const values = await computeSummaryValuesAsync({
|
|
@@ -18091,14 +18109,21 @@ function resolveProgressClipboardPercent(content) {
|
|
|
18091
18109
|
return Math.min(Math.max((content.value - min) / range * 100, 0), 100);
|
|
18092
18110
|
}
|
|
18093
18111
|
function buildExportColumns(columns) {
|
|
18094
|
-
return columns.filter(
|
|
18095
|
-
(column) => column.key !== ROW_SELECTION_COLUMN_KEY && column.key !== ROW_SELECTOR_COLUMN_KEY
|
|
18096
|
-
).map((column) => ({
|
|
18112
|
+
return columns.filter(isExportableColumn).map((column) => ({
|
|
18097
18113
|
key: column.key,
|
|
18098
18114
|
title: column.title ?? column.key,
|
|
18099
18115
|
value: (row, rowIndex) => getCellClipboardText(row, rowIndex, column)
|
|
18100
18116
|
}));
|
|
18101
18117
|
}
|
|
18118
|
+
function isExportableColumn(column) {
|
|
18119
|
+
if (column.key === ROW_SELECTION_COLUMN_KEY || column.key === ROW_SELECTOR_COLUMN_KEY || column.key === EXPAND_COLUMN_KEY) {
|
|
18120
|
+
return false;
|
|
18121
|
+
}
|
|
18122
|
+
if (column.exportable !== void 0) return column.exportable;
|
|
18123
|
+
return !(/^(?:action|actions|operate|operation|operations)$/i.test(column.key) || /^(?:操作|操作列|操作按钮|action|actions|operation|operations)$/i.test(
|
|
18124
|
+
column.title.trim()
|
|
18125
|
+
));
|
|
18126
|
+
}
|
|
18102
18127
|
function buildTableExportFileName(extension) {
|
|
18103
18128
|
const now2 = /* @__PURE__ */ new Date();
|
|
18104
18129
|
const stamp = [
|
|
@@ -18274,13 +18299,14 @@ var ListTableContentActionController = class {
|
|
|
18274
18299
|
* 异步导出全部原始数据为 XLSX。
|
|
18275
18300
|
*/
|
|
18276
18301
|
exportXlsx(options) {
|
|
18302
|
+
const includeSummary = options?.includeSummary ?? this.options.getSummaryVisible?.() ?? false;
|
|
18277
18303
|
options = { ...this.options.getOptions().exportOptions, ...options };
|
|
18278
18304
|
this.startExportTask(
|
|
18279
18305
|
(fileName) => exportAllRowsXlsxContent({
|
|
18280
18306
|
rows: this.options.getOptions().dataSource,
|
|
18281
18307
|
columns: this.options.getLeafColumns(),
|
|
18282
18308
|
...options,
|
|
18283
|
-
includeSummary
|
|
18309
|
+
includeSummary,
|
|
18284
18310
|
fileName: fileName ?? options?.fileName,
|
|
18285
18311
|
onProgress: (progress) => {
|
|
18286
18312
|
const fileLabel = progress.fileCount && progress.fileCount > 1 ? `\uFF08\u7B2C ${progress.fileIndex}/${progress.fileCount} \u4EFD\uFF09` : "";
|
|
@@ -19239,7 +19265,7 @@ function resolveScrollTopToRevealRow(params) {
|
|
|
19239
19265
|
if (frozenRows.top.rowIndexMap?.includes(rowIndex) || frozenRows.bottom.rowIndexMap?.includes(rowIndex)) {
|
|
19240
19266
|
return null;
|
|
19241
19267
|
}
|
|
19242
|
-
const scrollSectionIndex = frozenRows.scroll.rowIndexMap ? frozenRows.scroll.rowIndexMap.indexOf(rowIndex) : rowIndex;
|
|
19268
|
+
const scrollSectionIndex = frozenRows.scroll.dataRowIndexAligned ? rowIndex : frozenRows.scroll.rowIndexMap ? frozenRows.scroll.rowIndexMap.indexOf(rowIndex) : rowIndex;
|
|
19243
19269
|
if (scrollSectionIndex < 0) {
|
|
19244
19270
|
return null;
|
|
19245
19271
|
}
|
|
@@ -19482,7 +19508,7 @@ var ListTableEditingController = class {
|
|
|
19482
19508
|
});
|
|
19483
19509
|
const nextTop = resolveScrollTopToRevealRow({
|
|
19484
19510
|
rowIndex,
|
|
19485
|
-
rowCount: snapshot.visibleRows.length,
|
|
19511
|
+
rowCount: snapshot.frozenRows.scroll.dataRowIndexAligned ? snapshot.dataRowCount : snapshot.visibleRows.length,
|
|
19486
19512
|
rowHeight: snapshot.rowHeight,
|
|
19487
19513
|
bodyHeight: snapshot.bodyLayout.scrollBodyHeight,
|
|
19488
19514
|
scrollTop: scroll.top,
|
|
@@ -20187,6 +20213,7 @@ function drawSegmentRows(params, segment, columns, startRowIndex, endRowIndex, r
|
|
|
20187
20213
|
kind: "body",
|
|
20188
20214
|
rect,
|
|
20189
20215
|
columnKey: cell.column.key,
|
|
20216
|
+
cursor: cell.column.key === ROW_SELECTOR_COLUMN_KEY ? "pointer" : void 0,
|
|
20190
20217
|
rowIndex: cell.sourceRowIndex,
|
|
20191
20218
|
rowSpan: cell.rowSpan,
|
|
20192
20219
|
fixed: cell.column.fixed,
|
|
@@ -28463,11 +28490,19 @@ var ListTableEventController = class {
|
|
|
28463
28490
|
rowCount: this.host.getDisplayData().length,
|
|
28464
28491
|
columnKeys: this.host.leafColumns.filter((column) => !isSystemColumnKey(column.key)).map((column) => column.key)
|
|
28465
28492
|
};
|
|
28466
|
-
const target = direction ? resolveAdjacentCellSelection({
|
|
28493
|
+
const target = direction ? resolveAdjacentCellSelection({
|
|
28467
28494
|
...navigationParams,
|
|
28468
|
-
|
|
28495
|
+
direction,
|
|
28496
|
+
verticalWrap: this.host.options.keyboardNavigation?.verticalWrap
|
|
28497
|
+
}) : resolveTabCellSelection({
|
|
28498
|
+
...navigationParams,
|
|
28499
|
+
reverse: event.shiftKey,
|
|
28500
|
+
tabWrap: this.host.options.keyboardNavigation?.tabWrap
|
|
28469
28501
|
});
|
|
28470
28502
|
if (!target) {
|
|
28503
|
+
if (event.key === "Tab" && this.host.options.keyboardNavigation?.tabWrap === false) {
|
|
28504
|
+
event.preventDefault();
|
|
28505
|
+
}
|
|
28471
28506
|
return;
|
|
28472
28507
|
}
|
|
28473
28508
|
event.preventDefault();
|