diff --git a/packages/s2-core/__tests__/unit/interaction/base-interaction/click/data-cell-click-spec.ts b/packages/s2-core/__tests__/unit/interaction/base-interaction/click/data-cell-click-spec.ts index 65827b8434..4572641696 100644 --- a/packages/s2-core/__tests__/unit/interaction/base-interaction/click/data-cell-click-spec.ts +++ b/packages/s2-core/__tests__/unit/interaction/base-interaction/click/data-cell-click-spec.ts @@ -49,6 +49,7 @@ describe('Interaction Data Cell Click Tests', () => { s2.emit(S2Event.DATA_CELL_CLICK, { stopPropagation() {}, } as unknown as GEvent); + expect(s2.interaction.getState()).toEqual({ cells: [mockCellInfo.mockCellMeta], stateName: InteractionStateName.SELECTED, @@ -82,9 +83,29 @@ describe('Interaction Data Cell Click Tests', () => { s2.emit(S2Event.DATA_CELL_CLICK, { stopPropagation() {}, } as unknown as GEvent); + expect(selected).toHaveBeenCalledWith([mockCellInfo.mockCell]); }); + // https://github.com/antvis/S2/issues/2447 + test('should emit cell selected event when cell unselected', () => { + jest + .spyOn(s2.interaction, 'isSelectedCell') + .mockImplementationOnce(() => true); + + const selected = jest.fn(); + s2.on(S2Event.GLOBAL_SELECTED, selected); + + s2.emit(S2Event.DATA_CELL_CLICK, { + stopPropagation() {}, + originalEvent: { + detail: 1, + }, + } as unknown as GEvent); + + expect(selected).toHaveBeenCalledWith([]); + }); + test('should emit link field jump event when link field text click and not show tooltip', () => { const linkFieldJump = jest.fn(); diff --git a/packages/s2-core/__tests__/unit/interaction/event-controller-spec.ts b/packages/s2-core/__tests__/unit/interaction/event-controller-spec.ts index 0659ebe1ee..31b382b261 100644 --- a/packages/s2-core/__tests__/unit/interaction/event-controller-spec.ts +++ b/packages/s2-core/__tests__/unit/interaction/event-controller-spec.ts @@ -506,8 +506,11 @@ describe('Interaction Event Controller Tests', () => { maxY: 100, } as BBox, } as BaseFacet; + + const selected = jest.fn(); const reset = jest.fn(); spreadsheet.on(S2Event.GLOBAL_RESET, reset); + spreadsheet.on(S2Event.GLOBAL_SELECTED, selected); window.dispatchEvent( new MouseEvent('click', { @@ -516,6 +519,7 @@ describe('Interaction Event Controller Tests', () => { } as MouseEventInit), ); + expect(selected).toHaveBeenCalledWith([]); expect(reset).toHaveBeenCalled(); expect(spreadsheet.interaction.reset).toHaveBeenCalled(); }); @@ -527,13 +531,17 @@ describe('Interaction Event Controller Tests', () => { maxY: 100, } as BBox, } as BaseFacet; + + const selected = jest.fn(); const reset = jest.fn(); spreadsheet.on(S2Event.GLOBAL_RESET, reset); + spreadsheet.on(S2Event.GLOBAL_SELECTED, selected); window.dispatchEvent( new KeyboardEvent('keydown', { key: InteractionKeyboardKey.ESC }), ); + expect(selected).toHaveBeenCalledWith([]); expect(reset).toHaveBeenCalled(); expect(spreadsheet.interaction.reset).toHaveBeenCalled(); }); diff --git a/packages/s2-core/__tests__/unit/interaction/root-spec.ts b/packages/s2-core/__tests__/unit/interaction/root-spec.ts index 047935b86d..8869724d41 100644 --- a/packages/s2-core/__tests__/unit/interaction/root-spec.ts +++ b/packages/s2-core/__tests__/unit/interaction/root-spec.ts @@ -26,6 +26,7 @@ import { DataCellBrushSelection, ColBrushSelection, RowBrushSelection, + S2Event, } from '@/index'; import { RootInteraction } from '@/interaction/root'; import { mergeCell, unmergeCell } from '@/utils/interaction/merge-cell'; @@ -170,9 +171,9 @@ describe('RootInteraction Tests', () => { // https://github.com/antvis/S2/issues/1243 test('should multi selected header cells', () => { - const isEqualStateNameSpy = jest + jest .spyOn(rootInteraction, 'isEqualStateName') - .mockImplementation(() => false); + .mockImplementationOnce(() => false); const mockCellA = createMockCellInfo('test-A').mockCell; const mockCellB = createMockCellInfo('test-B').mockCell; @@ -204,8 +205,6 @@ describe('RootInteraction Tests', () => { // 取消选中 expect(rootInteraction.getState().cells).toEqual([getCellMeta(mockCellA)]); - - isEqualStateNameSpy.mockRestore(); }); test('should call merge cells', () => { diff --git a/packages/s2-core/src/facet/header/pivot-row.ts b/packages/s2-core/src/facet/header/pivot-row.ts index 493bd13772..ea8a23463b 100644 --- a/packages/s2-core/src/facet/header/pivot-row.ts +++ b/packages/s2-core/src/facet/header/pivot-row.ts @@ -6,6 +6,7 @@ export class PivotRowHeader extends BaseFrozenRowHeader { protected createCellInstance(item: Node): RowCell { const { spreadsheet, scrollY } = this.headerConfig; const frozenRow = this.isFrozenRow(item); + return new FrozenRowCell( item, spreadsheet, 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 f1b351d15c..e74115150c 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 @@ -56,9 +56,15 @@ export class DataCellClick extends BaseEvent implements BaseEventImplement { interaction.addIntercepts([InterceptType.HOVER]); if (interaction.isSelectedCell(cell)) { - // https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail,使用 detail属性来判断是否是双击,双击时不触发选择态reset + // https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail,使用 detail 属性来判断是否是双击,双击时不触发选择态 reset if ((event.originalEvent as UIEvent)?.detail === 1) { interaction.reset(); + + // https://github.com/antvis/S2/issues/2447 + this.spreadsheet.emit( + S2Event.GLOBAL_SELECTED, + interaction.getActiveCells(), + ); } return; } @@ -87,8 +93,8 @@ export class DataCellClick extends BaseEvent implements BaseEventImplement { meta, spreadsheet, ); - forEach(allRowHeaderCells, (cell: RowCell) => { - cell.updateByState(InteractionStateName.SELECTED); + forEach(allRowHeaderCells, (rowCell) => { + rowCell.updateByState(InteractionStateName.SELECTED); }); } } diff --git a/packages/s2-core/src/interaction/data-cell-multi-selection.ts b/packages/s2-core/src/interaction/data-cell-multi-selection.ts index b1ae87c6c7..5b2249209a 100644 --- a/packages/s2-core/src/interaction/data-cell-multi-selection.ts +++ b/packages/s2-core/src/interaction/data-cell-multi-selection.ts @@ -86,7 +86,7 @@ export class DataCellMultiSelection event.stopPropagation(); const cell: DataCell = this.spreadsheet.getCell(event.target); const meta = cell.getMeta(); - const { interaction, options } = this.spreadsheet; + const { interaction } = this.spreadsheet; if (this.isMultiSelection && meta) { const selectedCells = this.getSelectedCells(cell); @@ -94,6 +94,10 @@ export class DataCellMultiSelection if (isEmpty(selectedCells)) { interaction.clearState(); this.spreadsheet.hideTooltip(); + this.spreadsheet.emit( + S2Event.GLOBAL_SELECTED, + interaction.getActiveCells(), + ); return; } diff --git a/packages/s2-core/src/interaction/event-controller.ts b/packages/s2-core/src/interaction/event-controller.ts index a1258710b1..1632255142 100644 --- a/packages/s2-core/src/interaction/event-controller.ts +++ b/packages/s2-core/src/interaction/event-controller.ts @@ -186,8 +186,12 @@ export class EventController { return; } - this.spreadsheet.emit(S2Event.GLOBAL_RESET, event); interaction.reset(); + this.spreadsheet.emit(S2Event.GLOBAL_RESET, event); + this.spreadsheet.emit( + S2Event.GLOBAL_SELECTED, + interaction.getActiveCells(), + ); } private isMouseEvent(event: Event): event is MouseEvent { @@ -299,7 +303,7 @@ export class EventController { if (this.isResizeArea(event)) { this.spreadsheet.emit(S2Event.LAYOUT_RESIZE_MOUSE_DOWN, event); - // 仅捕获在canvas之外触发的事件 https://github.com/antvis/S2/issues/1592 + // 仅捕获在 canvas 之外触发的事件 https://github.com/antvis/S2/issues/1592 const resizeMouseMoveCapture = (mouseEvent: MouseEvent) => { if (!this.spreadsheet.getCanvasElement()) { return false;