diff --git a/packages/s2-core/__tests__/spreadsheet/table-sheet-spec.ts b/packages/s2-core/__tests__/spreadsheet/table-sheet-spec.ts index c91a6f1800..4893f84603 100644 --- a/packages/s2-core/__tests__/spreadsheet/table-sheet-spec.ts +++ b/packages/s2-core/__tests__/spreadsheet/table-sheet-spec.ts @@ -78,6 +78,7 @@ const options: S2Options = { interaction: { enableCopy: true, hoverHighlight: false, + selectedCellHighlight: true, linkFields: ['order_id', 'customer_name'], hiddenColumnFields: ['order_date'], resize: { @@ -97,7 +98,6 @@ const options: S2Options = { }; describe('TableSheet normal spec', () => { - test('scrollWithAnimation with duration and callback', async () => { const s2 = new TableSheet(getContainer(), dataCfg, options); s2.render(); @@ -146,11 +146,10 @@ describe('TableSheet normal spec', () => { ); await sleep(30); + const firstColCell = s2.getColumnNodes()[1].belongsCell as any; - const firstColCell = s2.getColumnNodes()[1].belongsCell as any - - expect(firstColCell.shouldAddVerticalResizeArea()).toBe(true) - expect(firstColCell.getVerticalResizeAreaOffset()).toEqual({ x: 80, y: 0 }) + expect(firstColCell.shouldAddVerticalResizeArea()).toBe(true); + expect(firstColCell.getVerticalResizeAreaOffset()).toEqual({ x: 80, y: 0 }); s2.destroy(); }); @@ -161,32 +160,35 @@ describe('TableSheet normal spec', () => { await sleep(30); - const { x, width, top } = s2.getCanvasElement().getBoundingClientRect() - s2.getCanvasElement().dispatchEvent(new MouseEvent('mousedown', { - clientX: x + width - 1, - clientY: top + 25, - })) - - - window.dispatchEvent(new MouseEvent('mousemove', { - clientX: x+ width + 100, - clientY: top + 25, + const { x, width, top } = s2.getCanvasElement().getBoundingClientRect(); + s2.getCanvasElement().dispatchEvent( + new MouseEvent('mousedown', { + clientX: x + width - 1, + clientY: top + 25, + }), + ); - })) + window.dispatchEvent( + new MouseEvent('mousemove', { + clientX: x + width + 100, + clientY: top + 25, + }), + ); await sleep(300); - window.dispatchEvent(new MouseEvent('mouseup', { - clientX: x + width + 100, - clientY: top + 25 - })) + window.dispatchEvent( + new MouseEvent('mouseup', { + clientX: x + width + 100, + clientY: top + 25, + }), + ); await sleep(300); - const columnNodes = s2.getColumnNodes() - const lastColumnCell = columnNodes[columnNodes.length - 1].belongsCell as ColCell - - expect(lastColumnCell.getMeta().width).toBe(199) - }); - + const columnNodes = s2.getColumnNodes(); + const lastColumnCell = columnNodes[columnNodes.length - 1] + .belongsCell as ColCell; + expect(lastColumnCell.getMeta().width).toBe(199); + }); }); diff --git a/packages/s2-core/__tests__/unit/interaction/brush-selection-spec.ts b/packages/s2-core/__tests__/unit/interaction/brush-selection-spec.ts index 2cca251547..ad3d587e3e 100644 --- a/packages/s2-core/__tests__/unit/interaction/brush-selection-spec.ts +++ b/packages/s2-core/__tests__/unit/interaction/brush-selection-spec.ts @@ -154,6 +154,46 @@ describe('Interaction Brush Selection Tests', () => { ).toBeFalsy(); }); + test('should highlight relevant col&row header cell with selectedCellHighlight option toggled on', () => { + mockSpreadSheetInstance.setOptions({ + interaction: { selectedCellHighlight: true }, + }); + + brushSelectionInstance.getBrushRange = () => { + return { + start: { + rowIndex: 0, + colIndex: 0, + x: 0, + y: 0, + }, + end: { + rowIndex: 5, + colIndex: 5, + x: 200, + y: 200, + }, + width: 200, + height: 200, + }; + }; + + (brushSelectionInstance as any).updateSelectedCells(); + + (mockRootInteraction.getAllColHeaderCells() || []) + .filter((cell, i) => i < 5) + .forEach((cell) => { + expect(cell.updateByState).toHaveBeenCalled(); + }); + + mockRootInteraction.getAllCells(); + + (mockRootInteraction.getAllRowHeaderCells() || []) + .filter((cell, i) => i < 5) + .forEach((cell) => { + expect(cell.updateByState).toHaveBeenCalled(); + }); + }); test('should get start brush point when mouse down', () => { emitEvent(S2Event.DATA_CELL_MOUSE_DOWN, { layerX: 10, diff --git a/packages/s2-core/src/interaction/base-interaction/click/data-cell-click.ts b/packages/s2-core/src/interaction/base-interaction/click/data-cell-click.ts index 52dd78f344..253ed06c1d 100644 --- a/packages/s2-core/src/interaction/base-interaction/click/data-cell-click.ts +++ b/packages/s2-core/src/interaction/base-interaction/click/data-cell-click.ts @@ -18,6 +18,7 @@ import type { import { getCellMeta, getRowCellForSelectedCell, + updateRowColCells, } from '../../../utils/interaction/select-event'; import { getTooltipOptions, @@ -67,31 +68,11 @@ export class DataCellClick extends BaseEvent implements BaseEventImplement { this.spreadsheet.emit(S2Event.GLOBAL_SELECTED, [cell]); this.showTooltip(event, meta); if (options.interaction.selectedCellHighlight) { - this.updateRowColCells(meta); + updateRowColCells(meta); } }); } - public updateRowColCells(meta: ViewMeta) { - const { rowId, colId } = meta; - const { interaction } = this.spreadsheet; - updateAllColHeaderCellState( - colId, - interaction.getAllColHeaderCells(), - InteractionStateName.SELECTED, - ); - - if (rowId) { - const allRowHeaderCells = getRowCellForSelectedCell( - meta, - this.spreadsheet, - ); - forEach(allRowHeaderCells, (cell: RowCell) => { - cell.updateByState(InteractionStateName.SELECTED); - }); - } - } - private getTooltipOperator( event: CanvasEvent, meta: ViewMeta, diff --git a/packages/s2-core/src/interaction/brush-selection.ts b/packages/s2-core/src/interaction/brush-selection.ts index 5bd2c1c990..3d6015ce34 100644 --- a/packages/s2-core/src/interaction/brush-selection.ts +++ b/packages/s2-core/src/interaction/brush-selection.ts @@ -30,7 +30,10 @@ import { getScrollOffsetForCol, getScrollOffsetForRow, } from '../utils/interaction/'; -import { getCellMeta } from '../utils/interaction/select-event'; +import { + getCellMeta, + updateRowColCells, +} from '../utils/interaction/select-event'; import { getValidFrozenOptions } from '../utils/layout/frozen'; import { getActiveCellsTooltipData } from '../utils/tooltip'; import type { BaseEventImplement } from './base-event'; @@ -679,16 +682,19 @@ export class BrushSelection extends BaseEvent implements BaseEventImplement { colIndex < range.end.colIndex + 1; colIndex++ ) { - const colId = colLeafNodes[colIndex].id; + const colId = String(colLeafNodes[colIndex].id); let rowId = String(rowIndex); if (rowLeafNodes.length) { - rowId = rowLeafNodes[rowIndex].id; + rowId = String(rowLeafNodes[rowIndex].id); } metas.push({ colIndex, rowIndex, id: `${rowId}-${colId}`, type: 'dataCell', + rowId, + colId, + spreadsheet: this.spreadsheet, }); } } @@ -697,14 +703,22 @@ export class BrushSelection extends BaseEvent implements BaseEventImplement { // 最终刷选的cell private updateSelectedCells() { - const { interaction } = this.spreadsheet; + const { interaction, options } = this.spreadsheet; const range = this.getBrushRange(); + const selectedCellMetas = this.getSelectedCellMetas(range); interaction.changeState({ - cells: this.getSelectedCellMetas(range), + cells: selectedCellMetas, stateName: InteractionStateName.SELECTED, }); + + if (options.interaction.selectedCellHighlight) { + selectedCellMetas.forEach((meta) => { + updateRowColCells(meta); + }); + } + this.spreadsheet.emit( S2Event.DATA_CELL_BRUSH_SELECTION, this.brushRangeDataCells, diff --git a/packages/s2-core/src/utils/interaction/select-event.ts b/packages/s2-core/src/utils/interaction/select-event.ts index 2e064bbb3e..61bbe87a59 100644 --- a/packages/s2-core/src/utils/interaction/select-event.ts +++ b/packages/s2-core/src/utils/interaction/select-event.ts @@ -1,3 +1,4 @@ +import { forEach } from 'lodash'; import { ColCell, RowCell, TableSeriesCell } from '../../cell'; import { getDataCellId } from '../cell/data-cell'; import { @@ -7,7 +8,10 @@ import { } from '../../common/constant'; import type { CellMeta, S2CellType, ViewMeta } from '../../common/interface'; import type { SpreadSheet } from '../../sheet-type'; -import { getActiveHoverRowColCells } from './hover-event'; +import { + getActiveHoverRowColCells, + updateAllColHeaderCellState, +} from './hover-event'; export const isMultiSelectionKey = (e: KeyboardEvent) => { return [InteractionKeyboardKey.META, InteractionKeyboardKey.CONTROL].includes( @@ -81,3 +85,20 @@ export function getRowCellForSelectedCell( spreadsheet.isHierarchyTreeType(), ); } + +export function updateRowColCells(meta: ViewMeta) { + const { rowId, colId, spreadsheet } = meta; + const { interaction } = spreadsheet; + updateAllColHeaderCellState( + colId, + interaction.getAllColHeaderCells(), + InteractionStateName.SELECTED, + ); + + if (rowId) { + const allRowHeaderCells = getRowCellForSelectedCell(meta, spreadsheet); + forEach(allRowHeaderCells, (cell: RowCell) => { + cell.updateByState(InteractionStateName.SELECTED); + }); + } +} diff --git a/packages/s2-react/playground/index.tsx b/packages/s2-react/playground/index.tsx index 6ca4d0ad4c..bdef04169c 100644 --- a/packages/s2-react/playground/index.tsx +++ b/packages/s2-react/playground/index.tsx @@ -812,6 +812,20 @@ function MainLayout() { }} /> + + { + updateOptions({ + interaction: { + selectedCellHighlight: checked, + }, + }); + }} + /> +