@lensui/lens-table 0.1.18 → 0.1.19
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 +1 -0
- package/dist/index.cjs +31 -7
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +31 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -98,6 +98,7 @@ export function Example() {
|
|
|
98
98
|
| `verticalBorderless` | `boolean` | `false` | 已兼容保留,建议改用 `borderless`。 |
|
|
99
99
|
| `horizontalBorderless` | `boolean` | `false` | 是否隐藏横向行分隔线及上下边框,同时保留纵向列分隔线。可与 `striped` 配合使用。 |
|
|
100
100
|
| `frameBorderless` | `boolean` | `false` | 是否隐藏表格四周外框,同时保留内部行列分隔线。 |
|
|
101
|
+
| `rowStyle` | `(row, rowIndex) => { color?: string; backgroundColor?: string }` | - | 自定义整行绘制样式,覆盖数据列及自动生成的选择列、序号列和拖拽列。 |
|
|
101
102
|
| `striped` | `boolean \| string` | `false` | 是否显示斑马纹行背景。传`true` 使用主题变量,传颜色字符串可自定义斑马纹颜色,例如 `'#f6faff'`。 |
|
|
102
103
|
| `highlight` | `{ editedCells?: boolean \| string; insertedRows?: boolean \| string }` | `{}` | 高亮反馈配置。`editedCells` 控制编辑过的单元格底色,`insertedRows` 控制乐观插入行底色;传 `true` 使用默认色,传颜色字符串可自定义。 |
|
|
103
104
|
| `cellSpans` | `TableCellSpan[] \| ((ctx) => TableCellSpan \| { rowSpan?: number; colSpan?: number } \| null)` | `[]` | 合并主体单元格配置。可传数组,也可传函数按单元格生成规则。推荐使用 `rowKey` 定位;横向合并会限制在同一个固定列分区内,工具列不会参与合并。 |
|
package/dist/index.cjs
CHANGED
|
@@ -1007,6 +1007,7 @@ function paintGrid(options) {
|
|
|
1007
1007
|
const y = bodyTop + rowIndex * rowHeight - scrollTop + shift;
|
|
1008
1008
|
const row = rows[rowIndex];
|
|
1009
1009
|
const rowKey = getRowKey(row, rowIndex);
|
|
1010
|
+
const rowStyle = options.rowStyle?.(row, rowIndex);
|
|
1010
1011
|
for (let columnIndex = 0; columnIndex < columns.length; columnIndex += 1) {
|
|
1011
1012
|
if (layer === "scroll" ? columns[columnIndex].fixed !== void 0 : columns[columnIndex].fixed !== layer) continue;
|
|
1012
1013
|
if (layer === "scroll" && (columnIndex < range.columnStart || columnIndex >= range.columnEnd)) continue;
|
|
@@ -1029,6 +1030,10 @@ function paintGrid(options) {
|
|
|
1029
1030
|
ctx.fillStyle = striped && rowIndex % 2 === 1 ? colors.stripe : colors.background;
|
|
1030
1031
|
ctx.fillRect(x, y, cellWidth, cellHeight);
|
|
1031
1032
|
}
|
|
1033
|
+
if (rowStyle?.backgroundColor) {
|
|
1034
|
+
ctx.fillStyle = rowStyle.backgroundColor;
|
|
1035
|
+
ctx.fillRect(x, y, cellWidth, cellHeight);
|
|
1036
|
+
}
|
|
1032
1037
|
if (isAxisSelected) {
|
|
1033
1038
|
ctx.fillStyle = colors.axisSelectionFill;
|
|
1034
1039
|
ctx.fillRect(x, y, cellWidth, cellHeight);
|
|
@@ -1074,14 +1079,14 @@ function paintGrid(options) {
|
|
|
1074
1079
|
ctx.fillRect(x, y + cellHeight - 1, cellWidth, 1);
|
|
1075
1080
|
}
|
|
1076
1081
|
if (rowSpan > 1) {
|
|
1077
|
-
const mergedFill = annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? colors.axisSelectionFill : cellStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
|
|
1082
|
+
const mergedFill = annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? colors.axisSelectionFill : cellStyle?.backgroundColor ?? rowStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
|
|
1078
1083
|
ctx.fillStyle = mergedFill;
|
|
1079
1084
|
for (let offset = 1; offset < rowSpan; offset += 1) {
|
|
1080
1085
|
ctx.fillRect(x, y + offset * rowHeight - 1, cellWidth, 2);
|
|
1081
1086
|
}
|
|
1082
1087
|
}
|
|
1083
1088
|
if (colSpan > 1 && !verticalBorderless) {
|
|
1084
|
-
const mergedFill = annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? colors.axisSelectionFill : cellStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
|
|
1089
|
+
const mergedFill = annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? colors.axisSelectionFill : cellStyle?.backgroundColor ?? rowStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
|
|
1085
1090
|
ctx.fillStyle = mergedFill;
|
|
1086
1091
|
let offsetLeft = 0;
|
|
1087
1092
|
for (let offset = 1; offset < colSpan; offset += 1) {
|
|
@@ -1178,7 +1183,7 @@ function paintGrid(options) {
|
|
|
1178
1183
|
ctx.beginPath();
|
|
1179
1184
|
ctx.rect(x + 2, y + 1, Math.max(0, cellWidth - 4), cellHeight - 2);
|
|
1180
1185
|
ctx.clip();
|
|
1181
|
-
ctx.fillStyle = isAxisSelected && !isSelectedCell && !isRangeCell ? colors.axisSelectionText : cellStyle?.color ?? colors.text;
|
|
1186
|
+
ctx.fillStyle = isAxisSelected && !isSelectedCell && !isRangeCell ? colors.axisSelectionText : cellStyle?.color ?? rowStyle?.color ?? colors.text;
|
|
1182
1187
|
ctx.font = createCellFont(bodyFontSize);
|
|
1183
1188
|
ctx.textBaseline = "alphabetic";
|
|
1184
1189
|
ctx.textAlign = column.align === "right" ? "right" : column.align === "center" ? "center" : "left";
|
|
@@ -1626,6 +1631,7 @@ function TableInner({
|
|
|
1626
1631
|
horizontalBorderless = false,
|
|
1627
1632
|
frameBorderless = false,
|
|
1628
1633
|
striped = false,
|
|
1634
|
+
rowStyle,
|
|
1629
1635
|
highlight,
|
|
1630
1636
|
cellSpans = [],
|
|
1631
1637
|
loading = false,
|
|
@@ -1754,6 +1760,7 @@ function TableInner({
|
|
|
1754
1760
|
}, [columns, headerCells, headerDepth]);
|
|
1755
1761
|
const canvasRef = (0, import_react5.useRef)(null);
|
|
1756
1762
|
const scrollerRef = (0, import_react5.useRef)(null);
|
|
1763
|
+
const rootRef = (0, import_react5.useRef)(null);
|
|
1757
1764
|
const frameRef = (0, import_react5.useRef)(null);
|
|
1758
1765
|
const textFrameRef = (0, import_react5.useRef)(null);
|
|
1759
1766
|
const toastTimerRef = (0, import_react5.useRef)(null);
|
|
@@ -2037,6 +2044,18 @@ function TableInner({
|
|
|
2037
2044
|
const [selection, setSelection] = useControllableValue(resolvedSelectedCell, resolvedDefaultSelectedCell, handleSelectedCellChange);
|
|
2038
2045
|
const [selectionRange, setSelectionRange] = (0, import_react5.useState)(null);
|
|
2039
2046
|
const rangeDragRef = (0, import_react5.useRef)(null);
|
|
2047
|
+
(0, import_react5.useEffect)(() => {
|
|
2048
|
+
if (!selection) return void 0;
|
|
2049
|
+
const handleOutsidePointerDown = (event) => {
|
|
2050
|
+
const target = event.target;
|
|
2051
|
+
if (!(target instanceof Node) || rootRef.current?.contains(target)) return;
|
|
2052
|
+
clickedCellRef.current = null;
|
|
2053
|
+
setSelectionRange(null);
|
|
2054
|
+
setSelection(null);
|
|
2055
|
+
};
|
|
2056
|
+
document.addEventListener("pointerdown", handleOutsidePointerDown);
|
|
2057
|
+
return () => document.removeEventListener("pointerdown", handleOutsidePointerDown);
|
|
2058
|
+
}, [selection, setSelection]);
|
|
2040
2059
|
const applyRowOrder = (0, import_react5.useCallback)((sourceIndex, targetIndex) => {
|
|
2041
2060
|
if (sourceIndex === targetIndex || sourceIndex < 0 || targetIndex < 0 || sourceIndex >= rows.length || targetIndex >= rows.length) return;
|
|
2042
2061
|
const nextEntries = rows.map((row, index) => ({ row, key: getDataRowKey(row, index) }));
|
|
@@ -2312,8 +2331,8 @@ function TableInner({
|
|
|
2312
2331
|
const scroll = scrollRef.current;
|
|
2313
2332
|
const rowScrollTop = fixedHeader ? scroll.top : Math.max(0, scroll.top - bodyTop);
|
|
2314
2333
|
const range = isVirtualized ? getViewportRange(scroll.left, rowScrollTop, viewport.width, bodyViewportHeight, rows.length, rowHeight, metrics, virtualOverscan) : { rowStart: 0, rowEnd: rows.length, columnStart: 0, columnEnd: columns.length };
|
|
2315
|
-
paintGrid({ context, width: viewport.width, height: renderHeight, pixelRatio: ratio, scrollLeft: scroll.left, scrollTop: scroll.top, rowHeight, bodyFontSize, headerActionSlotWidth, headerHeight, headerLeafTop, headerLeafHeight, bodyTop, suppressLastRowBottomBorder: bottomSummaryHeight > 0, suppressFrameBottomBorder: bottomSummaryHeight > 0, fixedHeader, verticalBorderless: !hasVerticalBorders, horizontalBorderless, frameBorderless, extendVerticalGridLines: !autoHeight, striped: hasStripedRows, columnDraggable, sortState, filterValues, hoveredHeaderAction: hoveredHeaderActionRef.current, rows, columns, metrics, range, selection, editing, hoveredRowIndex: hoveredRowIndexRef.current, selectionRange, selectedRowKeys: selectedRowKeySet, rowSelectionMode, selectedColumnKeys: selectedColumnKeySet, cellSpans: cellSpanLookup.covered, maxRowSpan: cellSpanLookup.maxRowSpan, highlightEditedCells: highlightsEditedCells, highlightInsertedRows: highlightsInsertedRows, insertedRowKeys: insertedRowKeySet, editedCellKeys, cellAnnotations, getRowKey, rowDragPreview, columnDropTarget, colors: themeColors });
|
|
2316
|
-
}, [autoHeight, bodyTop, bodyViewportHeight, bottomSummaryHeight, cellAnnotations, cellSpanLookup, columnDraggable, columnDropTarget, columns, editedCellHighlightColor, editedCellKeys, editing, renderHeight, filterValues, fixedHeader, frameBorderless, getRowKey, hasStripedRows, hasVerticalBorders, headerActionSlotWidth, headerDepth, headerHeight, headerLeafHeight, headerLeafTop, horizontalBorderless, highlightsEditedCells, highlightsInsertedRows, insertedRowHighlightColor, insertedRowKeySet, isVirtualized, metrics, rowDragPreview, rowHeight, rowSelectionMode, rows, selectedColumnKeySet, selectedRowKeySet, selection, selectionRange, sortState, stripedColor, viewport.width, virtualOverscan]);
|
|
2334
|
+
paintGrid({ context, width: viewport.width, height: renderHeight, pixelRatio: ratio, scrollLeft: scroll.left, scrollTop: scroll.top, rowHeight, bodyFontSize, headerActionSlotWidth, headerHeight, headerLeafTop, headerLeafHeight, bodyTop, suppressLastRowBottomBorder: bottomSummaryHeight > 0, suppressFrameBottomBorder: bottomSummaryHeight > 0, fixedHeader, verticalBorderless: !hasVerticalBorders, horizontalBorderless, frameBorderless, extendVerticalGridLines: !autoHeight, striped: hasStripedRows, columnDraggable, sortState, filterValues, hoveredHeaderAction: hoveredHeaderActionRef.current, rows, rowStyle, columns, metrics, range, selection, editing, hoveredRowIndex: hoveredRowIndexRef.current, selectionRange, selectedRowKeys: selectedRowKeySet, rowSelectionMode, selectedColumnKeys: selectedColumnKeySet, cellSpans: cellSpanLookup.covered, maxRowSpan: cellSpanLookup.maxRowSpan, highlightEditedCells: highlightsEditedCells, highlightInsertedRows: highlightsInsertedRows, insertedRowKeys: insertedRowKeySet, editedCellKeys, cellAnnotations, getRowKey, rowDragPreview, columnDropTarget, colors: themeColors });
|
|
2335
|
+
}, [autoHeight, bodyTop, bodyViewportHeight, bottomSummaryHeight, cellAnnotations, cellSpanLookup, columnDraggable, columnDropTarget, columns, editedCellHighlightColor, editedCellKeys, editing, renderHeight, filterValues, fixedHeader, frameBorderless, getRowKey, hasStripedRows, hasVerticalBorders, headerActionSlotWidth, headerDepth, headerHeight, headerLeafHeight, headerLeafTop, horizontalBorderless, highlightsEditedCells, highlightsInsertedRows, insertedRowHighlightColor, insertedRowKeySet, isVirtualized, metrics, rowDragPreview, rowHeight, rowSelectionMode, rowStyle, rows, selectedColumnKeySet, selectedRowKeySet, selection, selectionRange, sortState, stripedColor, viewport.width, virtualOverscan]);
|
|
2317
2336
|
const scheduleDraw = (0, import_react5.useCallback)(() => {
|
|
2318
2337
|
if (frameRef.current === null) frameRef.current = requestAnimationFrame(draw);
|
|
2319
2338
|
}, [draw]);
|
|
@@ -4596,7 +4615,7 @@ function TableInner({
|
|
|
4596
4615
|
};
|
|
4597
4616
|
const currentScroll = scrollRef.current;
|
|
4598
4617
|
const scrollerBottom = Math.max(0, bottomSummaryHeight - horizontalScrollbarHeight);
|
|
4599
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `rvg-root${!hasVerticalBorders ? " is-vertical-borderless" : ""}${horizontalBorderless ? " is-horizontal-borderless" : ""}${frameBorderless ? " is-frame-borderless" : ""}${hasStripedRows ? " is-striped" : ""}${insertBusy ? " is-inserting" : ""}${deleteBusy ? " is-deleting" : ""} ${loading && !hasCompletedLoadRef.current && !hasCustomLoading ? "is-initial-loading" : ""} ${className}`, style: rootStyle, children: [
|
|
4618
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { ref: rootRef, className: `rvg-root${!hasVerticalBorders ? " is-vertical-borderless" : ""}${horizontalBorderless ? " is-horizontal-borderless" : ""}${frameBorderless ? " is-frame-borderless" : ""}${hasStripedRows ? " is-striped" : ""}${insertBusy ? " is-inserting" : ""}${deleteBusy ? " is-deleting" : ""} ${loading && !hasCompletedLoadRef.current && !hasCustomLoading ? "is-initial-loading" : ""} ${className}`, style: rootStyle, children: [
|
|
4600
4619
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { ref: scrollerRef, className: `rvg-scroller${contextMenu ? " is-context-menu-open" : ""}`, style: { bottom: scrollerBottom }, onScroll: handleScroll, onCopy: handleCopy, onContextMenu: handleContextMenu, tabIndex: 0, role: "grid", "aria-label": ariaLabel, "aria-rowcount": rows.length, "aria-colcount": columns.length, onKeyDown: handleKeyDown, children: [
|
|
4601
4620
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4602
4621
|
"canvas",
|
|
@@ -4778,7 +4797,12 @@ function TableInner({
|
|
|
4778
4797
|
return;
|
|
4779
4798
|
}
|
|
4780
4799
|
const cell = locateCell(event.clientX, event.clientY);
|
|
4781
|
-
if (!cell)
|
|
4800
|
+
if (!cell) {
|
|
4801
|
+
clickedCellRef.current = null;
|
|
4802
|
+
setSelectionRange(null);
|
|
4803
|
+
setSelection(null);
|
|
4804
|
+
return;
|
|
4805
|
+
}
|
|
4782
4806
|
if (columns[cell.columnIndex].rowDragHandle || columns[cell.columnIndex].rowNumber) {
|
|
4783
4807
|
clickedCellRef.current = null;
|
|
4784
4808
|
return;
|
package/dist/index.d.cts
CHANGED
|
@@ -334,6 +334,11 @@ type TableContextMenu<Row> = boolean | TableContextMenuConfig<Row>;
|
|
|
334
334
|
interface TableProps<Row extends object> {
|
|
335
335
|
columns: GridColumn<Row>[];
|
|
336
336
|
rows: Row[];
|
|
337
|
+
/** Custom row paint style. Applies to data and generated utility columns. */
|
|
338
|
+
rowStyle?: (row: Row, rowIndex: number) => {
|
|
339
|
+
color?: string;
|
|
340
|
+
backgroundColor?: string;
|
|
341
|
+
};
|
|
337
342
|
/** Stable row id. Defaults to the row's `id` field when omitted. */
|
|
338
343
|
rowKey?: keyof Row | ((row: Row, index: number) => GridKey);
|
|
339
344
|
width?: number | string;
|
package/dist/index.d.ts
CHANGED
|
@@ -334,6 +334,11 @@ type TableContextMenu<Row> = boolean | TableContextMenuConfig<Row>;
|
|
|
334
334
|
interface TableProps<Row extends object> {
|
|
335
335
|
columns: GridColumn<Row>[];
|
|
336
336
|
rows: Row[];
|
|
337
|
+
/** Custom row paint style. Applies to data and generated utility columns. */
|
|
338
|
+
rowStyle?: (row: Row, rowIndex: number) => {
|
|
339
|
+
color?: string;
|
|
340
|
+
backgroundColor?: string;
|
|
341
|
+
};
|
|
337
342
|
/** Stable row id. Defaults to the row's `id` field when omitted. */
|
|
338
343
|
rowKey?: keyof Row | ((row: Row, index: number) => GridKey);
|
|
339
344
|
width?: number | string;
|
package/dist/index.js
CHANGED
|
@@ -977,6 +977,7 @@ function paintGrid(options) {
|
|
|
977
977
|
const y = bodyTop + rowIndex * rowHeight - scrollTop + shift;
|
|
978
978
|
const row = rows[rowIndex];
|
|
979
979
|
const rowKey = getRowKey(row, rowIndex);
|
|
980
|
+
const rowStyle = options.rowStyle?.(row, rowIndex);
|
|
980
981
|
for (let columnIndex = 0; columnIndex < columns.length; columnIndex += 1) {
|
|
981
982
|
if (layer === "scroll" ? columns[columnIndex].fixed !== void 0 : columns[columnIndex].fixed !== layer) continue;
|
|
982
983
|
if (layer === "scroll" && (columnIndex < range.columnStart || columnIndex >= range.columnEnd)) continue;
|
|
@@ -999,6 +1000,10 @@ function paintGrid(options) {
|
|
|
999
1000
|
ctx.fillStyle = striped && rowIndex % 2 === 1 ? colors.stripe : colors.background;
|
|
1000
1001
|
ctx.fillRect(x, y, cellWidth, cellHeight);
|
|
1001
1002
|
}
|
|
1003
|
+
if (rowStyle?.backgroundColor) {
|
|
1004
|
+
ctx.fillStyle = rowStyle.backgroundColor;
|
|
1005
|
+
ctx.fillRect(x, y, cellWidth, cellHeight);
|
|
1006
|
+
}
|
|
1002
1007
|
if (isAxisSelected) {
|
|
1003
1008
|
ctx.fillStyle = colors.axisSelectionFill;
|
|
1004
1009
|
ctx.fillRect(x, y, cellWidth, cellHeight);
|
|
@@ -1044,14 +1049,14 @@ function paintGrid(options) {
|
|
|
1044
1049
|
ctx.fillRect(x, y + cellHeight - 1, cellWidth, 1);
|
|
1045
1050
|
}
|
|
1046
1051
|
if (rowSpan > 1) {
|
|
1047
|
-
const mergedFill = annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? colors.axisSelectionFill : cellStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
|
|
1052
|
+
const mergedFill = annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? colors.axisSelectionFill : cellStyle?.backgroundColor ?? rowStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
|
|
1048
1053
|
ctx.fillStyle = mergedFill;
|
|
1049
1054
|
for (let offset = 1; offset < rowSpan; offset += 1) {
|
|
1050
1055
|
ctx.fillRect(x, y + offset * rowHeight - 1, cellWidth, 2);
|
|
1051
1056
|
}
|
|
1052
1057
|
}
|
|
1053
1058
|
if (colSpan > 1 && !verticalBorderless) {
|
|
1054
|
-
const mergedFill = annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? colors.axisSelectionFill : cellStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
|
|
1059
|
+
const mergedFill = annotation?.type === "background" ? annotation.color : isSelectedCell || isRangeCell ? colors.selectionFill : highlightEditedCells && !insertedRowKeys.has(rowKey) && editedCellKeys.has(`${typeof rowKey}:${String(rowKey)}\0${column.key}`) ? colors.editedFill : highlightInsertedRows && insertedRowKeys.has(rowKey) ? colors.insertedFill : hoveredRowIndex === rowIndex ? colors.rowHoverFill : isAxisSelected ? colors.axisSelectionFill : cellStyle?.backgroundColor ?? rowStyle?.backgroundColor ?? (striped && rowIndex % 2 === 1 ? colors.stripe : colors.background);
|
|
1055
1060
|
ctx.fillStyle = mergedFill;
|
|
1056
1061
|
let offsetLeft = 0;
|
|
1057
1062
|
for (let offset = 1; offset < colSpan; offset += 1) {
|
|
@@ -1148,7 +1153,7 @@ function paintGrid(options) {
|
|
|
1148
1153
|
ctx.beginPath();
|
|
1149
1154
|
ctx.rect(x + 2, y + 1, Math.max(0, cellWidth - 4), cellHeight - 2);
|
|
1150
1155
|
ctx.clip();
|
|
1151
|
-
ctx.fillStyle = isAxisSelected && !isSelectedCell && !isRangeCell ? colors.axisSelectionText : cellStyle?.color ?? colors.text;
|
|
1156
|
+
ctx.fillStyle = isAxisSelected && !isSelectedCell && !isRangeCell ? colors.axisSelectionText : cellStyle?.color ?? rowStyle?.color ?? colors.text;
|
|
1152
1157
|
ctx.font = createCellFont(bodyFontSize);
|
|
1153
1158
|
ctx.textBaseline = "alphabetic";
|
|
1154
1159
|
ctx.textAlign = column.align === "right" ? "right" : column.align === "center" ? "center" : "left";
|
|
@@ -1596,6 +1601,7 @@ function TableInner({
|
|
|
1596
1601
|
horizontalBorderless = false,
|
|
1597
1602
|
frameBorderless = false,
|
|
1598
1603
|
striped = false,
|
|
1604
|
+
rowStyle,
|
|
1599
1605
|
highlight,
|
|
1600
1606
|
cellSpans = [],
|
|
1601
1607
|
loading = false,
|
|
@@ -1724,6 +1730,7 @@ function TableInner({
|
|
|
1724
1730
|
}, [columns, headerCells, headerDepth]);
|
|
1725
1731
|
const canvasRef = useRef2(null);
|
|
1726
1732
|
const scrollerRef = useRef2(null);
|
|
1733
|
+
const rootRef = useRef2(null);
|
|
1727
1734
|
const frameRef = useRef2(null);
|
|
1728
1735
|
const textFrameRef = useRef2(null);
|
|
1729
1736
|
const toastTimerRef = useRef2(null);
|
|
@@ -2007,6 +2014,18 @@ function TableInner({
|
|
|
2007
2014
|
const [selection, setSelection] = useControllableValue(resolvedSelectedCell, resolvedDefaultSelectedCell, handleSelectedCellChange);
|
|
2008
2015
|
const [selectionRange, setSelectionRange] = useState4(null);
|
|
2009
2016
|
const rangeDragRef = useRef2(null);
|
|
2017
|
+
useEffect2(() => {
|
|
2018
|
+
if (!selection) return void 0;
|
|
2019
|
+
const handleOutsidePointerDown = (event) => {
|
|
2020
|
+
const target = event.target;
|
|
2021
|
+
if (!(target instanceof Node) || rootRef.current?.contains(target)) return;
|
|
2022
|
+
clickedCellRef.current = null;
|
|
2023
|
+
setSelectionRange(null);
|
|
2024
|
+
setSelection(null);
|
|
2025
|
+
};
|
|
2026
|
+
document.addEventListener("pointerdown", handleOutsidePointerDown);
|
|
2027
|
+
return () => document.removeEventListener("pointerdown", handleOutsidePointerDown);
|
|
2028
|
+
}, [selection, setSelection]);
|
|
2010
2029
|
const applyRowOrder = useCallback2((sourceIndex, targetIndex) => {
|
|
2011
2030
|
if (sourceIndex === targetIndex || sourceIndex < 0 || targetIndex < 0 || sourceIndex >= rows.length || targetIndex >= rows.length) return;
|
|
2012
2031
|
const nextEntries = rows.map((row, index) => ({ row, key: getDataRowKey(row, index) }));
|
|
@@ -2282,8 +2301,8 @@ function TableInner({
|
|
|
2282
2301
|
const scroll = scrollRef.current;
|
|
2283
2302
|
const rowScrollTop = fixedHeader ? scroll.top : Math.max(0, scroll.top - bodyTop);
|
|
2284
2303
|
const range = isVirtualized ? getViewportRange(scroll.left, rowScrollTop, viewport.width, bodyViewportHeight, rows.length, rowHeight, metrics, virtualOverscan) : { rowStart: 0, rowEnd: rows.length, columnStart: 0, columnEnd: columns.length };
|
|
2285
|
-
paintGrid({ context, width: viewport.width, height: renderHeight, pixelRatio: ratio, scrollLeft: scroll.left, scrollTop: scroll.top, rowHeight, bodyFontSize, headerActionSlotWidth, headerHeight, headerLeafTop, headerLeafHeight, bodyTop, suppressLastRowBottomBorder: bottomSummaryHeight > 0, suppressFrameBottomBorder: bottomSummaryHeight > 0, fixedHeader, verticalBorderless: !hasVerticalBorders, horizontalBorderless, frameBorderless, extendVerticalGridLines: !autoHeight, striped: hasStripedRows, columnDraggable, sortState, filterValues, hoveredHeaderAction: hoveredHeaderActionRef.current, rows, columns, metrics, range, selection, editing, hoveredRowIndex: hoveredRowIndexRef.current, selectionRange, selectedRowKeys: selectedRowKeySet, rowSelectionMode, selectedColumnKeys: selectedColumnKeySet, cellSpans: cellSpanLookup.covered, maxRowSpan: cellSpanLookup.maxRowSpan, highlightEditedCells: highlightsEditedCells, highlightInsertedRows: highlightsInsertedRows, insertedRowKeys: insertedRowKeySet, editedCellKeys, cellAnnotations, getRowKey, rowDragPreview, columnDropTarget, colors: themeColors });
|
|
2286
|
-
}, [autoHeight, bodyTop, bodyViewportHeight, bottomSummaryHeight, cellAnnotations, cellSpanLookup, columnDraggable, columnDropTarget, columns, editedCellHighlightColor, editedCellKeys, editing, renderHeight, filterValues, fixedHeader, frameBorderless, getRowKey, hasStripedRows, hasVerticalBorders, headerActionSlotWidth, headerDepth, headerHeight, headerLeafHeight, headerLeafTop, horizontalBorderless, highlightsEditedCells, highlightsInsertedRows, insertedRowHighlightColor, insertedRowKeySet, isVirtualized, metrics, rowDragPreview, rowHeight, rowSelectionMode, rows, selectedColumnKeySet, selectedRowKeySet, selection, selectionRange, sortState, stripedColor, viewport.width, virtualOverscan]);
|
|
2304
|
+
paintGrid({ context, width: viewport.width, height: renderHeight, pixelRatio: ratio, scrollLeft: scroll.left, scrollTop: scroll.top, rowHeight, bodyFontSize, headerActionSlotWidth, headerHeight, headerLeafTop, headerLeafHeight, bodyTop, suppressLastRowBottomBorder: bottomSummaryHeight > 0, suppressFrameBottomBorder: bottomSummaryHeight > 0, fixedHeader, verticalBorderless: !hasVerticalBorders, horizontalBorderless, frameBorderless, extendVerticalGridLines: !autoHeight, striped: hasStripedRows, columnDraggable, sortState, filterValues, hoveredHeaderAction: hoveredHeaderActionRef.current, rows, rowStyle, columns, metrics, range, selection, editing, hoveredRowIndex: hoveredRowIndexRef.current, selectionRange, selectedRowKeys: selectedRowKeySet, rowSelectionMode, selectedColumnKeys: selectedColumnKeySet, cellSpans: cellSpanLookup.covered, maxRowSpan: cellSpanLookup.maxRowSpan, highlightEditedCells: highlightsEditedCells, highlightInsertedRows: highlightsInsertedRows, insertedRowKeys: insertedRowKeySet, editedCellKeys, cellAnnotations, getRowKey, rowDragPreview, columnDropTarget, colors: themeColors });
|
|
2305
|
+
}, [autoHeight, bodyTop, bodyViewportHeight, bottomSummaryHeight, cellAnnotations, cellSpanLookup, columnDraggable, columnDropTarget, columns, editedCellHighlightColor, editedCellKeys, editing, renderHeight, filterValues, fixedHeader, frameBorderless, getRowKey, hasStripedRows, hasVerticalBorders, headerActionSlotWidth, headerDepth, headerHeight, headerLeafHeight, headerLeafTop, horizontalBorderless, highlightsEditedCells, highlightsInsertedRows, insertedRowHighlightColor, insertedRowKeySet, isVirtualized, metrics, rowDragPreview, rowHeight, rowSelectionMode, rowStyle, rows, selectedColumnKeySet, selectedRowKeySet, selection, selectionRange, sortState, stripedColor, viewport.width, virtualOverscan]);
|
|
2287
2306
|
const scheduleDraw = useCallback2(() => {
|
|
2288
2307
|
if (frameRef.current === null) frameRef.current = requestAnimationFrame(draw);
|
|
2289
2308
|
}, [draw]);
|
|
@@ -4566,7 +4585,7 @@ function TableInner({
|
|
|
4566
4585
|
};
|
|
4567
4586
|
const currentScroll = scrollRef.current;
|
|
4568
4587
|
const scrollerBottom = Math.max(0, bottomSummaryHeight - horizontalScrollbarHeight);
|
|
4569
|
-
return /* @__PURE__ */ jsxs7("div", { className: `rvg-root${!hasVerticalBorders ? " is-vertical-borderless" : ""}${horizontalBorderless ? " is-horizontal-borderless" : ""}${frameBorderless ? " is-frame-borderless" : ""}${hasStripedRows ? " is-striped" : ""}${insertBusy ? " is-inserting" : ""}${deleteBusy ? " is-deleting" : ""} ${loading && !hasCompletedLoadRef.current && !hasCustomLoading ? "is-initial-loading" : ""} ${className}`, style: rootStyle, children: [
|
|
4588
|
+
return /* @__PURE__ */ jsxs7("div", { ref: rootRef, className: `rvg-root${!hasVerticalBorders ? " is-vertical-borderless" : ""}${horizontalBorderless ? " is-horizontal-borderless" : ""}${frameBorderless ? " is-frame-borderless" : ""}${hasStripedRows ? " is-striped" : ""}${insertBusy ? " is-inserting" : ""}${deleteBusy ? " is-deleting" : ""} ${loading && !hasCompletedLoadRef.current && !hasCustomLoading ? "is-initial-loading" : ""} ${className}`, style: rootStyle, children: [
|
|
4570
4589
|
/* @__PURE__ */ jsxs7("div", { ref: scrollerRef, className: `rvg-scroller${contextMenu ? " is-context-menu-open" : ""}`, style: { bottom: scrollerBottom }, onScroll: handleScroll, onCopy: handleCopy, onContextMenu: handleContextMenu, tabIndex: 0, role: "grid", "aria-label": ariaLabel, "aria-rowcount": rows.length, "aria-colcount": columns.length, onKeyDown: handleKeyDown, children: [
|
|
4571
4590
|
/* @__PURE__ */ jsx7(
|
|
4572
4591
|
"canvas",
|
|
@@ -4748,7 +4767,12 @@ function TableInner({
|
|
|
4748
4767
|
return;
|
|
4749
4768
|
}
|
|
4750
4769
|
const cell = locateCell(event.clientX, event.clientY);
|
|
4751
|
-
if (!cell)
|
|
4770
|
+
if (!cell) {
|
|
4771
|
+
clickedCellRef.current = null;
|
|
4772
|
+
setSelectionRange(null);
|
|
4773
|
+
setSelection(null);
|
|
4774
|
+
return;
|
|
4775
|
+
}
|
|
4752
4776
|
if (columns[cell.columnIndex].rowDragHandle || columns[cell.columnIndex].rowNumber) {
|
|
4753
4777
|
clickedCellRef.current = null;
|
|
4754
4778
|
return;
|