@lensui/lens-table 0.1.16 → 0.1.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 +1 -1
- package/dist/index.cjs +64 -20
- package/dist/index.css +9 -0
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +64 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -111,7 +111,7 @@ export function Example() {
|
|
|
111
111
|
| `defaultSelectedCell` | `GridSelectionTarget \| null` | `null` | 默认选中单元格。传 `columnKey`,行可使用 `rowKey` 或 `rowIndex` 定位。 |
|
|
112
112
|
| `onSelectedCellChange` | `(selection) => void` | - | 单元格选中变化回调,`selection.value` 为当前单元格的原始值。 |
|
|
113
113
|
| `rangeSelection` | `boolean` | `false` | 是否允许鼠标拖动选择多个单元格。开启后支持范围复制、范围右键菜单和右下角拖拽扩展范围。 |
|
|
114
|
-
| `rowSelection` | `boolean \| RowSelectionConfig` | `false` | 开启行选择。支持 `mode`、`showCheckbox`、`indicator: 'checkbox' \| 'arrow'` 和 `columnWidth
|
|
114
|
+
| `rowSelection` | `boolean \| RowSelectionConfig` | `false` | 开启行选择。支持 `mode`、`showCheckbox`、`indicator: 'checkbox' \| 'arrow' \| 'none'` 和 `columnWidth`;`none` 保留点击区域但不绘制标记。默认自动生成左侧选择列。 |
|
|
115
115
|
| `selectedRowKeys` | `GridKey[]` | 非受控 | 受控行选择 key 列表。 |
|
|
116
116
|
| `defaultSelectedRowKeys` | `GridKey[]` | `[]` | 非受控模式下默认选中的行 key。 |
|
|
117
117
|
| `onSelectedRowChange` | `(keys, rows, indices) => void` | - | 行选择变化回调。 |
|
package/dist/index.cjs
CHANGED
|
@@ -1115,7 +1115,8 @@ function paintGrid(options) {
|
|
|
1115
1115
|
const checked = selectedRowKeys.has(rowKey);
|
|
1116
1116
|
ctx.save();
|
|
1117
1117
|
ctx.lineWidth = 1;
|
|
1118
|
-
if (column.rowSelectionIndicator === "
|
|
1118
|
+
if (column.rowSelectionIndicator === "none") {
|
|
1119
|
+
} else if (column.rowSelectionIndicator === "arrow") {
|
|
1119
1120
|
if (checked) {
|
|
1120
1121
|
ctx.beginPath();
|
|
1121
1122
|
ctx.moveTo(iconLeft + 3.5, iconTop + 8);
|
|
@@ -1201,9 +1202,25 @@ function paintGrid(options) {
|
|
|
1201
1202
|
paintBodyColumns("scroll");
|
|
1202
1203
|
paintBodyColumns("left");
|
|
1203
1204
|
paintBodyColumns("right");
|
|
1204
|
-
if (extendVerticalGridLines
|
|
1205
|
+
if (extendVerticalGridLines) {
|
|
1205
1206
|
const extensionTop = Math.max(bodyTop, Math.min(height, bodyTop + rows.length * rowHeight - scrollTop));
|
|
1206
1207
|
const extensionHeight = Math.max(0, height - extensionTop);
|
|
1208
|
+
const paintExtendedColumnSelection = (layer) => {
|
|
1209
|
+
ctx.save();
|
|
1210
|
+
if (layer === "scroll") {
|
|
1211
|
+
ctx.beginPath();
|
|
1212
|
+
ctx.rect(leftFixedWidth, extensionTop, Math.max(0, rightFixedLeft - leftFixedWidth), extensionHeight);
|
|
1213
|
+
ctx.clip();
|
|
1214
|
+
}
|
|
1215
|
+
ctx.fillStyle = colors.axisSelectionFill;
|
|
1216
|
+
for (let columnIndex = 0; columnIndex < columns.length; columnIndex += 1) {
|
|
1217
|
+
if (!selectedColumnKeys.has(columns[columnIndex].key)) continue;
|
|
1218
|
+
if (layer === "scroll" ? columns[columnIndex].fixed !== void 0 : columns[columnIndex].fixed !== layer) continue;
|
|
1219
|
+
if (layer === "scroll" && (columnIndex < range.columnStart || columnIndex >= range.columnEnd)) continue;
|
|
1220
|
+
ctx.fillRect(getColumnX(columnIndex), extensionTop, metrics[columnIndex].width, extensionHeight);
|
|
1221
|
+
}
|
|
1222
|
+
ctx.restore();
|
|
1223
|
+
};
|
|
1207
1224
|
const paintExtendedColumnLines = (layer) => {
|
|
1208
1225
|
ctx.save();
|
|
1209
1226
|
if (layer === "scroll") {
|
|
@@ -1221,9 +1238,14 @@ function paintGrid(options) {
|
|
|
1221
1238
|
}
|
|
1222
1239
|
ctx.restore();
|
|
1223
1240
|
};
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1241
|
+
paintExtendedColumnSelection("scroll");
|
|
1242
|
+
paintExtendedColumnSelection("left");
|
|
1243
|
+
paintExtendedColumnSelection("right");
|
|
1244
|
+
if (!verticalBorderless) {
|
|
1245
|
+
paintExtendedColumnLines("scroll");
|
|
1246
|
+
paintExtendedColumnLines("left");
|
|
1247
|
+
paintExtendedColumnLines("right");
|
|
1248
|
+
}
|
|
1227
1249
|
}
|
|
1228
1250
|
const headerY = fixedHeader ? 0 : -scrollTop;
|
|
1229
1251
|
ctx.fillStyle = colors.header;
|
|
@@ -1239,8 +1261,9 @@ function paintGrid(options) {
|
|
|
1239
1261
|
ctx.fillStyle = colors.header;
|
|
1240
1262
|
ctx.fillRect(x, headerY, metric.width, headerHeight);
|
|
1241
1263
|
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1264
|
+
const isAxisSelected = selectedColumnKeys.has(columns[columnIndex].key);
|
|
1265
|
+
if (isAxisSelected) {
|
|
1266
|
+
ctx.fillStyle = colors.axisSelectionFill;
|
|
1244
1267
|
ctx.fillRect(x, headerY, metric.width, headerHeight);
|
|
1245
1268
|
}
|
|
1246
1269
|
if (columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex) {
|
|
@@ -1272,7 +1295,7 @@ function paintGrid(options) {
|
|
|
1272
1295
|
ctx.beginPath();
|
|
1273
1296
|
ctx.rect(x + 2, headerY + headerLeafTop + 1, Math.max(0, clipWidth - 4), headerLeafHeight - 2);
|
|
1274
1297
|
ctx.clip();
|
|
1275
|
-
ctx.fillStyle = colors.muted;
|
|
1298
|
+
ctx.fillStyle = isAxisSelected ? colors.axisSelectionText : colors.muted;
|
|
1276
1299
|
ctx.textAlign = titleAlign === "right" ? "right" : titleAlign === "center" ? "center" : "left";
|
|
1277
1300
|
ctx.fillText(title, textX, headerY + headerLeafTop + headerLeafHeight / 2);
|
|
1278
1301
|
ctx.restore();
|
|
@@ -3378,6 +3401,9 @@ function TableInner({
|
|
|
3378
3401
|
}, [setSelection]);
|
|
3379
3402
|
const selectRow = (0, import_react5.useCallback)((rowIndex, event, forceToggle = false) => {
|
|
3380
3403
|
if (!rowSelection) return;
|
|
3404
|
+
clickedCellRef.current = null;
|
|
3405
|
+
setSelectionRange(null);
|
|
3406
|
+
setSelection(null);
|
|
3381
3407
|
const mode = typeof rowSelection === "object" ? rowSelection.mode ?? "multiple" : "multiple";
|
|
3382
3408
|
const key = getRowKey(rows[rowIndex], rowIndex);
|
|
3383
3409
|
let next;
|
|
@@ -3392,9 +3418,12 @@ function TableInner({
|
|
|
3392
3418
|
}
|
|
3393
3419
|
rowAnchorRef.current = rowIndex;
|
|
3394
3420
|
setRowKeys(next);
|
|
3395
|
-
}, [getRowKey, rowKeys, rowSelection, rows, selectedRowKeySet, setRowKeys]);
|
|
3421
|
+
}, [getRowKey, rowKeys, rowSelection, rows, selectedRowKeySet, setRowKeys, setSelection]);
|
|
3396
3422
|
const selectColumn = (0, import_react5.useCallback)((columnIndex, event) => {
|
|
3397
3423
|
if (!columnSelection || columnIndex < 0) return;
|
|
3424
|
+
clickedCellRef.current = null;
|
|
3425
|
+
setSelectionRange(null);
|
|
3426
|
+
setSelection(null);
|
|
3398
3427
|
const mode = typeof columnSelection === "object" ? columnSelection.mode ?? "multiple" : "multiple";
|
|
3399
3428
|
const key = columns[columnIndex].key;
|
|
3400
3429
|
let next;
|
|
@@ -3402,23 +3431,26 @@ function TableInner({
|
|
|
3402
3431
|
const start = Math.min(columnAnchorRef.current, columnIndex);
|
|
3403
3432
|
const end = Math.max(columnAnchorRef.current, columnIndex);
|
|
3404
3433
|
next = columns.slice(start, end + 1).map((column) => column.key);
|
|
3405
|
-
} else if (mode === "multiple") {
|
|
3434
|
+
} else if (mode === "multiple" && (event.ctrlKey || event.metaKey)) {
|
|
3406
3435
|
next = selectedColumnKeySet.has(key) ? columnKeys.filter((item) => item !== key) : [...columnKeys, key];
|
|
3407
3436
|
} else {
|
|
3408
3437
|
next = columnKeys.length === 1 && selectedColumnKeySet.has(key) ? [] : [key];
|
|
3409
3438
|
}
|
|
3410
3439
|
columnAnchorRef.current = columnIndex;
|
|
3411
3440
|
setColumnKeys(next);
|
|
3412
|
-
}, [columnKeys, columnSelection, columns, selectedColumnKeySet, setColumnKeys]);
|
|
3441
|
+
}, [columnKeys, columnSelection, columns, selectedColumnKeySet, setColumnKeys, setSelection]);
|
|
3413
3442
|
const toggleColumnFromMenu = (0, import_react5.useCallback)((columnIndex) => {
|
|
3414
3443
|
if (!columnSelection || columnIndex < 0) return;
|
|
3444
|
+
clickedCellRef.current = null;
|
|
3445
|
+
setSelectionRange(null);
|
|
3446
|
+
setSelection(null);
|
|
3415
3447
|
const key = columns[columnIndex].key;
|
|
3416
3448
|
const mode = typeof columnSelection === "object" ? columnSelection.mode ?? "multiple" : "multiple";
|
|
3417
3449
|
const selected = selectedColumnKeySet.has(key);
|
|
3418
3450
|
const next = selected ? columnKeys.filter((value) => value !== key) : mode === "multiple" ? [...columnKeys, key] : [key];
|
|
3419
3451
|
columnAnchorRef.current = columnIndex;
|
|
3420
3452
|
setColumnKeys(next);
|
|
3421
|
-
}, [columnKeys, columnSelection, columns, selectedColumnKeySet, setColumnKeys]);
|
|
3453
|
+
}, [columnKeys, columnSelection, columns, selectedColumnKeySet, setColumnKeys, setSelection]);
|
|
3422
3454
|
const revealCell = (0, import_react5.useCallback)((cell) => {
|
|
3423
3455
|
const scroller = scrollerRef.current;
|
|
3424
3456
|
const metric = metrics[cell.columnIndex];
|
|
@@ -3770,6 +3802,8 @@ function TableInner({
|
|
|
3770
3802
|
const renderHeaderIcons = (columnIndex, left) => {
|
|
3771
3803
|
const column = columns[columnIndex];
|
|
3772
3804
|
if (column.rowSelection || column.rowDragHandle || column.rowNumber) return null;
|
|
3805
|
+
const isAxisSelected = selectedColumnKeySet.has(column.key);
|
|
3806
|
+
const selectedClassName = isAxisSelected ? " is-axis-selected" : "";
|
|
3773
3807
|
const top = headerLeafTop + (headerLeafHeight - headerActionSize) / 2;
|
|
3774
3808
|
const visibleActions = getVisibleHeaderActions(column, metrics[columnIndex].width, columnDraggable, measureHeaderTitleWidth(columnIndex), headerActionSlotWidth);
|
|
3775
3809
|
let right = left + metrics[columnIndex].width - (visibleActions.drag ? headerActionSlotWidth : 2);
|
|
@@ -3777,21 +3811,21 @@ function TableInner({
|
|
|
3777
3811
|
if (visibleActions.drag) {
|
|
3778
3812
|
const hovered = hoveredHeaderAction?.columnIndex === columnIndex && hoveredHeaderAction.action === "drag";
|
|
3779
3813
|
icons.push(
|
|
3780
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderDragIcon, { className: `rvg-header-icon rvg-header-drag-icon${hovered ? " is-hovered" : ""}`, style: { left: left + metrics[columnIndex].width - headerActionSlotWidth, top } }, "drag")
|
|
3814
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderDragIcon, { className: `rvg-header-icon rvg-header-drag-icon${selectedClassName}${hovered ? " is-hovered" : ""}`, style: { left: left + metrics[columnIndex].width - headerActionSlotWidth, top } }, "drag")
|
|
3781
3815
|
);
|
|
3782
3816
|
}
|
|
3783
3817
|
if (visibleActions.sort) {
|
|
3784
3818
|
const hovered = hoveredHeaderAction?.columnIndex === columnIndex && hoveredHeaderAction.action === "sort";
|
|
3785
3819
|
const direction = sortState?.columnKey === column.key ? sortState.direction : null;
|
|
3786
3820
|
icons.push(
|
|
3787
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderSortIcon, { className: `rvg-header-icon${hovered ? " is-hovered" : ""}`, style: { left: right - headerActionSlotWidth, top }, direction }, "sort")
|
|
3821
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderSortIcon, { className: `rvg-header-icon${selectedClassName}${hovered ? " is-hovered" : ""}`, style: { left: right - headerActionSlotWidth, top }, direction }, "sort")
|
|
3788
3822
|
);
|
|
3789
3823
|
right -= headerActionSlotWidth;
|
|
3790
3824
|
}
|
|
3791
3825
|
if (visibleActions.filter) {
|
|
3792
3826
|
const hovered = hoveredHeaderAction?.columnIndex === columnIndex && hoveredHeaderAction.action === "filter";
|
|
3793
3827
|
icons.push(
|
|
3794
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderSearchIcon, { className: `rvg-header-icon rvg-header-search-icon${hovered ? " is-hovered" : ""}${filterValues[column.key] ? " is-active" : ""}`, style: { left: right - headerActionSlotWidth, top: top + 1 } }, "filter")
|
|
3828
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderSearchIcon, { className: `rvg-header-icon rvg-header-search-icon${selectedClassName}${hovered ? " is-hovered" : ""}${filterValues[column.key] ? " is-active" : ""}`, style: { left: right - headerActionSlotWidth, top: top + 1 } }, "filter")
|
|
3795
3829
|
);
|
|
3796
3830
|
}
|
|
3797
3831
|
return icons;
|
|
@@ -4171,6 +4205,7 @@ function TableInner({
|
|
|
4171
4205
|
};
|
|
4172
4206
|
const renderHeaderTitle = (columnIndex, left) => {
|
|
4173
4207
|
const column = columns[columnIndex];
|
|
4208
|
+
const isAxisSelected = selectedColumnKeySet.has(column.key);
|
|
4174
4209
|
const isDropTarget = Boolean(columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex);
|
|
4175
4210
|
const currentScrollTop = scrollRef.current.top;
|
|
4176
4211
|
const headerTop = fixedHeader ? 0 : -currentScrollTop;
|
|
@@ -4187,7 +4222,7 @@ function TableInner({
|
|
|
4187
4222
|
);
|
|
4188
4223
|
}
|
|
4189
4224
|
if (column.rowSelection) {
|
|
4190
|
-
if (rowSelectionMode === "single" || column.rowSelectionIndicator === "arrow") return null;
|
|
4225
|
+
if (rowSelectionMode === "single" || column.rowSelectionIndicator === "arrow" || column.rowSelectionIndicator === "none") return null;
|
|
4191
4226
|
const allSelected = rows.length > 0 && selectedRowKeySet.size === rows.length;
|
|
4192
4227
|
const indeterminate = selectedRowKeySet.size > 0 && !allSelected;
|
|
4193
4228
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
@@ -4206,7 +4241,7 @@ function TableInner({
|
|
|
4206
4241
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4207
4242
|
"div",
|
|
4208
4243
|
{
|
|
4209
|
-
className: `rvg-header-title is-custom${isDropTarget ? " is-drop-target" : ""}`,
|
|
4244
|
+
className: `rvg-header-title is-custom${isAxisSelected ? " is-axis-selected" : ""}${isDropTarget ? " is-drop-target" : ""}`,
|
|
4210
4245
|
"data-level": headerDepth - 1,
|
|
4211
4246
|
"data-measure-key": column.key,
|
|
4212
4247
|
style: {
|
|
@@ -4249,10 +4284,11 @@ function TableInner({
|
|
|
4249
4284
|
const visibleActions = cell.leaf ? getVisibleHeaderActions(column, startMetric.width, columnDraggable, measureHeaderTitleWidth(cell.startIndex), headerActionSlotWidth) : null;
|
|
4250
4285
|
const actionWidth = visibleActions ? (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) * headerActionSlotWidth : columnDraggable && !cell.leaf ? headerActionSlotWidth : 0;
|
|
4251
4286
|
const isDropTarget = Boolean(columnDropTarget && cell.endIndex >= columnDropTarget.startIndex && cell.startIndex <= columnDropTarget.endIndex);
|
|
4287
|
+
const isAxisSelected = cell.leaf && selectedColumnKeySet.has(column.key);
|
|
4252
4288
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
4253
4289
|
"div",
|
|
4254
4290
|
{
|
|
4255
|
-
className: `rvg-header-title rvg-header-group${column.renderHeader ? " is-custom" : ""}${cell.leaf ? " is-leaf" : ""}${cell.endIndex === columns.length - 1 ? " is-frame-right" : ""}${isDropTarget ? " is-drop-target" : ""}`,
|
|
4291
|
+
className: `rvg-header-title rvg-header-group${column.renderHeader ? " is-custom" : ""}${cell.leaf ? " is-leaf" : ""}${isAxisSelected ? " is-axis-selected" : ""}${cell.endIndex === columns.length - 1 ? " is-frame-right" : ""}${isDropTarget ? " is-drop-target" : ""}`,
|
|
4256
4292
|
"data-level": cell.level,
|
|
4257
4293
|
"data-measure-key": `group:${cell.key}:${cell.level}`,
|
|
4258
4294
|
style: {
|
|
@@ -4516,12 +4552,16 @@ function TableInner({
|
|
|
4516
4552
|
getSelectedRows: () => rows.filter((row, index) => selectedRowKeySet.has(getRowKey(row, index))),
|
|
4517
4553
|
setSelectedRowKeys: (keys) => {
|
|
4518
4554
|
if (!rowSelection) return;
|
|
4555
|
+
setSelectionRange(null);
|
|
4556
|
+
setSelection(null);
|
|
4519
4557
|
const next = [...new Set(keys)];
|
|
4520
4558
|
setRowKeys(rowSelectionMode === "single" ? next.slice(0, 1) : next);
|
|
4521
4559
|
},
|
|
4522
4560
|
getSelectedColumnKeys: () => [...columnKeys],
|
|
4523
4561
|
setSelectedColumnKeys: (keys) => {
|
|
4524
4562
|
if (!columnSelection) return;
|
|
4563
|
+
setSelectionRange(null);
|
|
4564
|
+
setSelection(null);
|
|
4525
4565
|
const next = [...new Set(keys)].filter((key) => columns.some((column) => column.key === key && !column.rowNumber && !column.rowSelection && !column.rowDragHandle));
|
|
4526
4566
|
setColumnKeys(typeof columnSelection === "object" && columnSelection.mode === "single" ? next.slice(0, 1) : next);
|
|
4527
4567
|
},
|
|
@@ -4724,7 +4764,9 @@ function TableInner({
|
|
|
4724
4764
|
}
|
|
4725
4765
|
if (locateHeaderDragHandle(event.clientX, columnIndex)) return;
|
|
4726
4766
|
if (columnIndex >= 0 && columns[columnIndex].rowSelection && rowSelection) {
|
|
4727
|
-
if (columns[columnIndex].rowSelectionIndicator === "arrow") return;
|
|
4767
|
+
if (columns[columnIndex].rowSelectionIndicator === "arrow" || columns[columnIndex].rowSelectionIndicator === "none") return;
|
|
4768
|
+
setSelectionRange(null);
|
|
4769
|
+
setSelection(null);
|
|
4728
4770
|
setRowKeys(rowKeys.length === rows.length ? [] : rows.map(getRowKey));
|
|
4729
4771
|
} else if (columnIndex >= 0 && (columns[columnIndex].rowDragHandle || columns[columnIndex].rowNumber)) {
|
|
4730
4772
|
return;
|
|
@@ -4743,7 +4785,7 @@ function TableInner({
|
|
|
4743
4785
|
const clickedRowSelector = Boolean(columns[cell.columnIndex].rowSelection);
|
|
4744
4786
|
if (clickedRowSelector) {
|
|
4745
4787
|
clickedCellRef.current = null;
|
|
4746
|
-
selectRow(cell.rowIndex, event, columns[cell.columnIndex].rowSelectionIndicator
|
|
4788
|
+
selectRow(cell.rowIndex, event, !["arrow", "none"].includes(columns[cell.columnIndex].rowSelectionIndicator ?? "checkbox"));
|
|
4747
4789
|
return;
|
|
4748
4790
|
}
|
|
4749
4791
|
if (event.detail > 1) return;
|
|
@@ -5042,6 +5084,8 @@ function TableInner({
|
|
|
5042
5084
|
if (item === "select-row") {
|
|
5043
5085
|
if (!rowSelection) return null;
|
|
5044
5086
|
return renderContextMenuButton("cell-select-row", cellContext, selectedRowKeySet.has(cell.rowKey) ? labels.deselectRow : labels.selectRow, () => {
|
|
5087
|
+
setSelectionRange(null);
|
|
5088
|
+
setSelection(null);
|
|
5045
5089
|
if (selectedRowKeySet.has(cell.rowKey)) setRowKeys(rowKeys.filter((key) => key !== cell.rowKey));
|
|
5046
5090
|
else setRowKeys(rowSelectionMode === "single" ? [cell.rowKey] : [...rowKeys, cell.rowKey]);
|
|
5047
5091
|
}, override, { icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ContextMenuIcon, { type: "select-row" }) });
|
package/dist/index.css
CHANGED
|
@@ -773,6 +773,10 @@
|
|
|
773
773
|
.rvg-header-title.is-drop-target {
|
|
774
774
|
background: var(--rvg-color-column-drop-target-fill);
|
|
775
775
|
}
|
|
776
|
+
.rvg-header-title.is-axis-selected {
|
|
777
|
+
background: var(--rvg-color-axis-selection-fill);
|
|
778
|
+
color: var(--rvg-color-axis-selection-text);
|
|
779
|
+
}
|
|
776
780
|
.rvg-text-fixed-shadow {
|
|
777
781
|
position: absolute;
|
|
778
782
|
z-index: 4;
|
|
@@ -854,6 +858,11 @@
|
|
|
854
858
|
.rvg-header-icon.is-hovered {
|
|
855
859
|
color: var(--rvg-color-muted);
|
|
856
860
|
}
|
|
861
|
+
.rvg-header-icon.is-axis-selected,
|
|
862
|
+
.rvg-header-icon.is-axis-selected.is-hovered,
|
|
863
|
+
.rvg-header-icon.is-axis-selected.is-active {
|
|
864
|
+
color: var(--rvg-color-axis-selection-text);
|
|
865
|
+
}
|
|
857
866
|
.rvg-root.is-initial-loading .rvg-header-icon {
|
|
858
867
|
color: #d6dbe0;
|
|
859
868
|
animation: rvg-loading-icon-pulse 1.15s ease-in-out infinite alternate;
|
package/dist/index.d.cts
CHANGED
|
@@ -160,7 +160,7 @@ interface RowSelectionConfig extends AxisSelectionConfig {
|
|
|
160
160
|
/** Show the selection column. Defaults to true; when false, click body cells to select rows. */
|
|
161
161
|
showCheckbox?: boolean;
|
|
162
162
|
/** Selection marker style. Arrow stays blank until selected. Defaults to checkbox. */
|
|
163
|
-
indicator?: 'checkbox' | 'arrow';
|
|
163
|
+
indicator?: 'checkbox' | 'arrow' | 'none';
|
|
164
164
|
/** Width of the generated selection column. Defaults to 44. */
|
|
165
165
|
columnWidth?: number;
|
|
166
166
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -160,7 +160,7 @@ interface RowSelectionConfig extends AxisSelectionConfig {
|
|
|
160
160
|
/** Show the selection column. Defaults to true; when false, click body cells to select rows. */
|
|
161
161
|
showCheckbox?: boolean;
|
|
162
162
|
/** Selection marker style. Arrow stays blank until selected. Defaults to checkbox. */
|
|
163
|
-
indicator?: 'checkbox' | 'arrow';
|
|
163
|
+
indicator?: 'checkbox' | 'arrow' | 'none';
|
|
164
164
|
/** Width of the generated selection column. Defaults to 44. */
|
|
165
165
|
columnWidth?: number;
|
|
166
166
|
}
|
package/dist/index.js
CHANGED
|
@@ -1085,7 +1085,8 @@ function paintGrid(options) {
|
|
|
1085
1085
|
const checked = selectedRowKeys.has(rowKey);
|
|
1086
1086
|
ctx.save();
|
|
1087
1087
|
ctx.lineWidth = 1;
|
|
1088
|
-
if (column.rowSelectionIndicator === "
|
|
1088
|
+
if (column.rowSelectionIndicator === "none") {
|
|
1089
|
+
} else if (column.rowSelectionIndicator === "arrow") {
|
|
1089
1090
|
if (checked) {
|
|
1090
1091
|
ctx.beginPath();
|
|
1091
1092
|
ctx.moveTo(iconLeft + 3.5, iconTop + 8);
|
|
@@ -1171,9 +1172,25 @@ function paintGrid(options) {
|
|
|
1171
1172
|
paintBodyColumns("scroll");
|
|
1172
1173
|
paintBodyColumns("left");
|
|
1173
1174
|
paintBodyColumns("right");
|
|
1174
|
-
if (extendVerticalGridLines
|
|
1175
|
+
if (extendVerticalGridLines) {
|
|
1175
1176
|
const extensionTop = Math.max(bodyTop, Math.min(height, bodyTop + rows.length * rowHeight - scrollTop));
|
|
1176
1177
|
const extensionHeight = Math.max(0, height - extensionTop);
|
|
1178
|
+
const paintExtendedColumnSelection = (layer) => {
|
|
1179
|
+
ctx.save();
|
|
1180
|
+
if (layer === "scroll") {
|
|
1181
|
+
ctx.beginPath();
|
|
1182
|
+
ctx.rect(leftFixedWidth, extensionTop, Math.max(0, rightFixedLeft - leftFixedWidth), extensionHeight);
|
|
1183
|
+
ctx.clip();
|
|
1184
|
+
}
|
|
1185
|
+
ctx.fillStyle = colors.axisSelectionFill;
|
|
1186
|
+
for (let columnIndex = 0; columnIndex < columns.length; columnIndex += 1) {
|
|
1187
|
+
if (!selectedColumnKeys.has(columns[columnIndex].key)) continue;
|
|
1188
|
+
if (layer === "scroll" ? columns[columnIndex].fixed !== void 0 : columns[columnIndex].fixed !== layer) continue;
|
|
1189
|
+
if (layer === "scroll" && (columnIndex < range.columnStart || columnIndex >= range.columnEnd)) continue;
|
|
1190
|
+
ctx.fillRect(getColumnX(columnIndex), extensionTop, metrics[columnIndex].width, extensionHeight);
|
|
1191
|
+
}
|
|
1192
|
+
ctx.restore();
|
|
1193
|
+
};
|
|
1177
1194
|
const paintExtendedColumnLines = (layer) => {
|
|
1178
1195
|
ctx.save();
|
|
1179
1196
|
if (layer === "scroll") {
|
|
@@ -1191,9 +1208,14 @@ function paintGrid(options) {
|
|
|
1191
1208
|
}
|
|
1192
1209
|
ctx.restore();
|
|
1193
1210
|
};
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1211
|
+
paintExtendedColumnSelection("scroll");
|
|
1212
|
+
paintExtendedColumnSelection("left");
|
|
1213
|
+
paintExtendedColumnSelection("right");
|
|
1214
|
+
if (!verticalBorderless) {
|
|
1215
|
+
paintExtendedColumnLines("scroll");
|
|
1216
|
+
paintExtendedColumnLines("left");
|
|
1217
|
+
paintExtendedColumnLines("right");
|
|
1218
|
+
}
|
|
1197
1219
|
}
|
|
1198
1220
|
const headerY = fixedHeader ? 0 : -scrollTop;
|
|
1199
1221
|
ctx.fillStyle = colors.header;
|
|
@@ -1209,8 +1231,9 @@ function paintGrid(options) {
|
|
|
1209
1231
|
ctx.fillStyle = colors.header;
|
|
1210
1232
|
ctx.fillRect(x, headerY, metric.width, headerHeight);
|
|
1211
1233
|
}
|
|
1212
|
-
|
|
1213
|
-
|
|
1234
|
+
const isAxisSelected = selectedColumnKeys.has(columns[columnIndex].key);
|
|
1235
|
+
if (isAxisSelected) {
|
|
1236
|
+
ctx.fillStyle = colors.axisSelectionFill;
|
|
1214
1237
|
ctx.fillRect(x, headerY, metric.width, headerHeight);
|
|
1215
1238
|
}
|
|
1216
1239
|
if (columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex) {
|
|
@@ -1242,7 +1265,7 @@ function paintGrid(options) {
|
|
|
1242
1265
|
ctx.beginPath();
|
|
1243
1266
|
ctx.rect(x + 2, headerY + headerLeafTop + 1, Math.max(0, clipWidth - 4), headerLeafHeight - 2);
|
|
1244
1267
|
ctx.clip();
|
|
1245
|
-
ctx.fillStyle = colors.muted;
|
|
1268
|
+
ctx.fillStyle = isAxisSelected ? colors.axisSelectionText : colors.muted;
|
|
1246
1269
|
ctx.textAlign = titleAlign === "right" ? "right" : titleAlign === "center" ? "center" : "left";
|
|
1247
1270
|
ctx.fillText(title, textX, headerY + headerLeafTop + headerLeafHeight / 2);
|
|
1248
1271
|
ctx.restore();
|
|
@@ -3348,6 +3371,9 @@ function TableInner({
|
|
|
3348
3371
|
}, [setSelection]);
|
|
3349
3372
|
const selectRow = useCallback2((rowIndex, event, forceToggle = false) => {
|
|
3350
3373
|
if (!rowSelection) return;
|
|
3374
|
+
clickedCellRef.current = null;
|
|
3375
|
+
setSelectionRange(null);
|
|
3376
|
+
setSelection(null);
|
|
3351
3377
|
const mode = typeof rowSelection === "object" ? rowSelection.mode ?? "multiple" : "multiple";
|
|
3352
3378
|
const key = getRowKey(rows[rowIndex], rowIndex);
|
|
3353
3379
|
let next;
|
|
@@ -3362,9 +3388,12 @@ function TableInner({
|
|
|
3362
3388
|
}
|
|
3363
3389
|
rowAnchorRef.current = rowIndex;
|
|
3364
3390
|
setRowKeys(next);
|
|
3365
|
-
}, [getRowKey, rowKeys, rowSelection, rows, selectedRowKeySet, setRowKeys]);
|
|
3391
|
+
}, [getRowKey, rowKeys, rowSelection, rows, selectedRowKeySet, setRowKeys, setSelection]);
|
|
3366
3392
|
const selectColumn = useCallback2((columnIndex, event) => {
|
|
3367
3393
|
if (!columnSelection || columnIndex < 0) return;
|
|
3394
|
+
clickedCellRef.current = null;
|
|
3395
|
+
setSelectionRange(null);
|
|
3396
|
+
setSelection(null);
|
|
3368
3397
|
const mode = typeof columnSelection === "object" ? columnSelection.mode ?? "multiple" : "multiple";
|
|
3369
3398
|
const key = columns[columnIndex].key;
|
|
3370
3399
|
let next;
|
|
@@ -3372,23 +3401,26 @@ function TableInner({
|
|
|
3372
3401
|
const start = Math.min(columnAnchorRef.current, columnIndex);
|
|
3373
3402
|
const end = Math.max(columnAnchorRef.current, columnIndex);
|
|
3374
3403
|
next = columns.slice(start, end + 1).map((column) => column.key);
|
|
3375
|
-
} else if (mode === "multiple") {
|
|
3404
|
+
} else if (mode === "multiple" && (event.ctrlKey || event.metaKey)) {
|
|
3376
3405
|
next = selectedColumnKeySet.has(key) ? columnKeys.filter((item) => item !== key) : [...columnKeys, key];
|
|
3377
3406
|
} else {
|
|
3378
3407
|
next = columnKeys.length === 1 && selectedColumnKeySet.has(key) ? [] : [key];
|
|
3379
3408
|
}
|
|
3380
3409
|
columnAnchorRef.current = columnIndex;
|
|
3381
3410
|
setColumnKeys(next);
|
|
3382
|
-
}, [columnKeys, columnSelection, columns, selectedColumnKeySet, setColumnKeys]);
|
|
3411
|
+
}, [columnKeys, columnSelection, columns, selectedColumnKeySet, setColumnKeys, setSelection]);
|
|
3383
3412
|
const toggleColumnFromMenu = useCallback2((columnIndex) => {
|
|
3384
3413
|
if (!columnSelection || columnIndex < 0) return;
|
|
3414
|
+
clickedCellRef.current = null;
|
|
3415
|
+
setSelectionRange(null);
|
|
3416
|
+
setSelection(null);
|
|
3385
3417
|
const key = columns[columnIndex].key;
|
|
3386
3418
|
const mode = typeof columnSelection === "object" ? columnSelection.mode ?? "multiple" : "multiple";
|
|
3387
3419
|
const selected = selectedColumnKeySet.has(key);
|
|
3388
3420
|
const next = selected ? columnKeys.filter((value) => value !== key) : mode === "multiple" ? [...columnKeys, key] : [key];
|
|
3389
3421
|
columnAnchorRef.current = columnIndex;
|
|
3390
3422
|
setColumnKeys(next);
|
|
3391
|
-
}, [columnKeys, columnSelection, columns, selectedColumnKeySet, setColumnKeys]);
|
|
3423
|
+
}, [columnKeys, columnSelection, columns, selectedColumnKeySet, setColumnKeys, setSelection]);
|
|
3392
3424
|
const revealCell = useCallback2((cell) => {
|
|
3393
3425
|
const scroller = scrollerRef.current;
|
|
3394
3426
|
const metric = metrics[cell.columnIndex];
|
|
@@ -3740,6 +3772,8 @@ function TableInner({
|
|
|
3740
3772
|
const renderHeaderIcons = (columnIndex, left) => {
|
|
3741
3773
|
const column = columns[columnIndex];
|
|
3742
3774
|
if (column.rowSelection || column.rowDragHandle || column.rowNumber) return null;
|
|
3775
|
+
const isAxisSelected = selectedColumnKeySet.has(column.key);
|
|
3776
|
+
const selectedClassName = isAxisSelected ? " is-axis-selected" : "";
|
|
3743
3777
|
const top = headerLeafTop + (headerLeafHeight - headerActionSize) / 2;
|
|
3744
3778
|
const visibleActions = getVisibleHeaderActions(column, metrics[columnIndex].width, columnDraggable, measureHeaderTitleWidth(columnIndex), headerActionSlotWidth);
|
|
3745
3779
|
let right = left + metrics[columnIndex].width - (visibleActions.drag ? headerActionSlotWidth : 2);
|
|
@@ -3747,21 +3781,21 @@ function TableInner({
|
|
|
3747
3781
|
if (visibleActions.drag) {
|
|
3748
3782
|
const hovered = hoveredHeaderAction?.columnIndex === columnIndex && hoveredHeaderAction.action === "drag";
|
|
3749
3783
|
icons.push(
|
|
3750
|
-
/* @__PURE__ */ jsx7(HeaderDragIcon, { className: `rvg-header-icon rvg-header-drag-icon${hovered ? " is-hovered" : ""}`, style: { left: left + metrics[columnIndex].width - headerActionSlotWidth, top } }, "drag")
|
|
3784
|
+
/* @__PURE__ */ jsx7(HeaderDragIcon, { className: `rvg-header-icon rvg-header-drag-icon${selectedClassName}${hovered ? " is-hovered" : ""}`, style: { left: left + metrics[columnIndex].width - headerActionSlotWidth, top } }, "drag")
|
|
3751
3785
|
);
|
|
3752
3786
|
}
|
|
3753
3787
|
if (visibleActions.sort) {
|
|
3754
3788
|
const hovered = hoveredHeaderAction?.columnIndex === columnIndex && hoveredHeaderAction.action === "sort";
|
|
3755
3789
|
const direction = sortState?.columnKey === column.key ? sortState.direction : null;
|
|
3756
3790
|
icons.push(
|
|
3757
|
-
/* @__PURE__ */ jsx7(HeaderSortIcon, { className: `rvg-header-icon${hovered ? " is-hovered" : ""}`, style: { left: right - headerActionSlotWidth, top }, direction }, "sort")
|
|
3791
|
+
/* @__PURE__ */ jsx7(HeaderSortIcon, { className: `rvg-header-icon${selectedClassName}${hovered ? " is-hovered" : ""}`, style: { left: right - headerActionSlotWidth, top }, direction }, "sort")
|
|
3758
3792
|
);
|
|
3759
3793
|
right -= headerActionSlotWidth;
|
|
3760
3794
|
}
|
|
3761
3795
|
if (visibleActions.filter) {
|
|
3762
3796
|
const hovered = hoveredHeaderAction?.columnIndex === columnIndex && hoveredHeaderAction.action === "filter";
|
|
3763
3797
|
icons.push(
|
|
3764
|
-
/* @__PURE__ */ jsx7(HeaderSearchIcon, { className: `rvg-header-icon rvg-header-search-icon${hovered ? " is-hovered" : ""}${filterValues[column.key] ? " is-active" : ""}`, style: { left: right - headerActionSlotWidth, top: top + 1 } }, "filter")
|
|
3798
|
+
/* @__PURE__ */ jsx7(HeaderSearchIcon, { className: `rvg-header-icon rvg-header-search-icon${selectedClassName}${hovered ? " is-hovered" : ""}${filterValues[column.key] ? " is-active" : ""}`, style: { left: right - headerActionSlotWidth, top: top + 1 } }, "filter")
|
|
3765
3799
|
);
|
|
3766
3800
|
}
|
|
3767
3801
|
return icons;
|
|
@@ -4141,6 +4175,7 @@ function TableInner({
|
|
|
4141
4175
|
};
|
|
4142
4176
|
const renderHeaderTitle = (columnIndex, left) => {
|
|
4143
4177
|
const column = columns[columnIndex];
|
|
4178
|
+
const isAxisSelected = selectedColumnKeySet.has(column.key);
|
|
4144
4179
|
const isDropTarget = Boolean(columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex);
|
|
4145
4180
|
const currentScrollTop = scrollRef.current.top;
|
|
4146
4181
|
const headerTop = fixedHeader ? 0 : -currentScrollTop;
|
|
@@ -4157,7 +4192,7 @@ function TableInner({
|
|
|
4157
4192
|
);
|
|
4158
4193
|
}
|
|
4159
4194
|
if (column.rowSelection) {
|
|
4160
|
-
if (rowSelectionMode === "single" || column.rowSelectionIndicator === "arrow") return null;
|
|
4195
|
+
if (rowSelectionMode === "single" || column.rowSelectionIndicator === "arrow" || column.rowSelectionIndicator === "none") return null;
|
|
4161
4196
|
const allSelected = rows.length > 0 && selectedRowKeySet.size === rows.length;
|
|
4162
4197
|
const indeterminate = selectedRowKeySet.size > 0 && !allSelected;
|
|
4163
4198
|
return /* @__PURE__ */ jsx7(
|
|
@@ -4176,7 +4211,7 @@ function TableInner({
|
|
|
4176
4211
|
return /* @__PURE__ */ jsx7(
|
|
4177
4212
|
"div",
|
|
4178
4213
|
{
|
|
4179
|
-
className: `rvg-header-title is-custom${isDropTarget ? " is-drop-target" : ""}`,
|
|
4214
|
+
className: `rvg-header-title is-custom${isAxisSelected ? " is-axis-selected" : ""}${isDropTarget ? " is-drop-target" : ""}`,
|
|
4180
4215
|
"data-level": headerDepth - 1,
|
|
4181
4216
|
"data-measure-key": column.key,
|
|
4182
4217
|
style: {
|
|
@@ -4219,10 +4254,11 @@ function TableInner({
|
|
|
4219
4254
|
const visibleActions = cell.leaf ? getVisibleHeaderActions(column, startMetric.width, columnDraggable, measureHeaderTitleWidth(cell.startIndex), headerActionSlotWidth) : null;
|
|
4220
4255
|
const actionWidth = visibleActions ? (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) * headerActionSlotWidth : columnDraggable && !cell.leaf ? headerActionSlotWidth : 0;
|
|
4221
4256
|
const isDropTarget = Boolean(columnDropTarget && cell.endIndex >= columnDropTarget.startIndex && cell.startIndex <= columnDropTarget.endIndex);
|
|
4257
|
+
const isAxisSelected = cell.leaf && selectedColumnKeySet.has(column.key);
|
|
4222
4258
|
return /* @__PURE__ */ jsxs7(
|
|
4223
4259
|
"div",
|
|
4224
4260
|
{
|
|
4225
|
-
className: `rvg-header-title rvg-header-group${column.renderHeader ? " is-custom" : ""}${cell.leaf ? " is-leaf" : ""}${cell.endIndex === columns.length - 1 ? " is-frame-right" : ""}${isDropTarget ? " is-drop-target" : ""}`,
|
|
4261
|
+
className: `rvg-header-title rvg-header-group${column.renderHeader ? " is-custom" : ""}${cell.leaf ? " is-leaf" : ""}${isAxisSelected ? " is-axis-selected" : ""}${cell.endIndex === columns.length - 1 ? " is-frame-right" : ""}${isDropTarget ? " is-drop-target" : ""}`,
|
|
4226
4262
|
"data-level": cell.level,
|
|
4227
4263
|
"data-measure-key": `group:${cell.key}:${cell.level}`,
|
|
4228
4264
|
style: {
|
|
@@ -4486,12 +4522,16 @@ function TableInner({
|
|
|
4486
4522
|
getSelectedRows: () => rows.filter((row, index) => selectedRowKeySet.has(getRowKey(row, index))),
|
|
4487
4523
|
setSelectedRowKeys: (keys) => {
|
|
4488
4524
|
if (!rowSelection) return;
|
|
4525
|
+
setSelectionRange(null);
|
|
4526
|
+
setSelection(null);
|
|
4489
4527
|
const next = [...new Set(keys)];
|
|
4490
4528
|
setRowKeys(rowSelectionMode === "single" ? next.slice(0, 1) : next);
|
|
4491
4529
|
},
|
|
4492
4530
|
getSelectedColumnKeys: () => [...columnKeys],
|
|
4493
4531
|
setSelectedColumnKeys: (keys) => {
|
|
4494
4532
|
if (!columnSelection) return;
|
|
4533
|
+
setSelectionRange(null);
|
|
4534
|
+
setSelection(null);
|
|
4495
4535
|
const next = [...new Set(keys)].filter((key) => columns.some((column) => column.key === key && !column.rowNumber && !column.rowSelection && !column.rowDragHandle));
|
|
4496
4536
|
setColumnKeys(typeof columnSelection === "object" && columnSelection.mode === "single" ? next.slice(0, 1) : next);
|
|
4497
4537
|
},
|
|
@@ -4694,7 +4734,9 @@ function TableInner({
|
|
|
4694
4734
|
}
|
|
4695
4735
|
if (locateHeaderDragHandle(event.clientX, columnIndex)) return;
|
|
4696
4736
|
if (columnIndex >= 0 && columns[columnIndex].rowSelection && rowSelection) {
|
|
4697
|
-
if (columns[columnIndex].rowSelectionIndicator === "arrow") return;
|
|
4737
|
+
if (columns[columnIndex].rowSelectionIndicator === "arrow" || columns[columnIndex].rowSelectionIndicator === "none") return;
|
|
4738
|
+
setSelectionRange(null);
|
|
4739
|
+
setSelection(null);
|
|
4698
4740
|
setRowKeys(rowKeys.length === rows.length ? [] : rows.map(getRowKey));
|
|
4699
4741
|
} else if (columnIndex >= 0 && (columns[columnIndex].rowDragHandle || columns[columnIndex].rowNumber)) {
|
|
4700
4742
|
return;
|
|
@@ -4713,7 +4755,7 @@ function TableInner({
|
|
|
4713
4755
|
const clickedRowSelector = Boolean(columns[cell.columnIndex].rowSelection);
|
|
4714
4756
|
if (clickedRowSelector) {
|
|
4715
4757
|
clickedCellRef.current = null;
|
|
4716
|
-
selectRow(cell.rowIndex, event, columns[cell.columnIndex].rowSelectionIndicator
|
|
4758
|
+
selectRow(cell.rowIndex, event, !["arrow", "none"].includes(columns[cell.columnIndex].rowSelectionIndicator ?? "checkbox"));
|
|
4717
4759
|
return;
|
|
4718
4760
|
}
|
|
4719
4761
|
if (event.detail > 1) return;
|
|
@@ -5012,6 +5054,8 @@ function TableInner({
|
|
|
5012
5054
|
if (item === "select-row") {
|
|
5013
5055
|
if (!rowSelection) return null;
|
|
5014
5056
|
return renderContextMenuButton("cell-select-row", cellContext, selectedRowKeySet.has(cell.rowKey) ? labels.deselectRow : labels.selectRow, () => {
|
|
5057
|
+
setSelectionRange(null);
|
|
5058
|
+
setSelection(null);
|
|
5015
5059
|
if (selectedRowKeySet.has(cell.rowKey)) setRowKeys(rowKeys.filter((key) => key !== cell.rowKey));
|
|
5016
5060
|
else setRowKeys(rowSelectionMode === "single" ? [cell.rowKey] : [...rowKeys, cell.rowKey]);
|
|
5017
5061
|
}, override, { icon: /* @__PURE__ */ jsx7(ContextMenuIcon, { type: "select-row" }) });
|