From 69f6479b43055c12d0295a7c77709b990a069ee3 Mon Sep 17 00:00:00 2001 From: Jinke Li Date: Fri, 1 Nov 2024 18:24:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E4=B8=8D=E5=90=8C?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=8D=95=E5=85=83=E6=A0=BC=E7=9A=84=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E4=BA=8B=E4=BB=B6=20&=20=E6=94=AF=E6=8C=81=E8=AF=86?= =?UTF-8?q?=E5=88=AB=E4=BA=8B=E4=BB=B6=E6=9D=A5=E6=BA=90=20(#2956)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 增加不同类型单元格的选中事件 & 支持识别事件来源 * test: 修复单测 --- .../__tests__/spreadsheet/corner-spec.ts | 13 ++- .../interaction-cell-selected-event-spec.ts | 57 ++++++++++++ .../interaction-multi-selection-spec.ts | 40 ++++++++- .../__tests__/unit/cell/data-cell-spec.ts | 2 +- .../__snapshots__/root-spec.ts.snap | 2 + .../click/corner-cell-click-spec.ts | 2 + .../click/data-cell-click-spec.ts | 15 +++- .../click/row-column-click-spec.ts | 28 +++--- .../data-cell-multi-selection-spec.ts | 18 ++-- .../unit/interaction/event-controller-spec.ts | 10 ++- .../unit/interaction/range-selection-spec.ts | 61 ++++++++++--- .../__tests__/unit/interaction/root-spec.ts | 24 ++--- .../utils/interaction/select-event-spec.ts | 15 +--- packages/s2-core/__tests__/util/helpers.ts | 2 +- .../src/common/constant/events/basic.ts | 4 + .../src/common/constant/interaction.ts | 5 ++ .../s2-core/src/common/interface/emitter.ts | 25 +++++- .../src/common/interface/interaction.ts | 6 ++ .../s2-core/src/interaction/base-event.ts | 2 +- .../click/corner-cell-click.ts | 19 ++-- .../base-interaction/click/data-cell-click.ts | 15 ++-- .../click/row-column-click.ts | 13 +++ .../brush-selection/base-brush-selection.ts | 10 ++- .../brush-selection/col-brush-selection.ts | 14 +-- .../data-cell-brush-selection.ts | 5 ++ .../brush-selection/row-brush-selection.ts | 5 ++ .../interaction/data-cell-multi-selection.ts | 19 ++-- .../src/interaction/event-controller.ts | 6 +- .../src/interaction/range-selection.ts | 45 ++++------ packages/s2-core/src/interaction/root.ts | 44 ++++++++- .../src/interaction/selected-cell-move.ts | 17 +++- .../src/utils/interaction/select-event.ts | 23 ++--- .../__tests__/unit/hooks/useEvents-spec.ts | 16 ++++ packages/s2-react/playground/index.tsx | 9 ++ packages/s2-react/src/hooks/useEvents.ts | 4 + packages/s2-shared/src/interface.ts | 10 ++- packages/s2-vue/src/hooks/useEvents.ts | 22 ++++- .../docs/api/basic-class/interaction.zh.md | 50 ++--------- .../docs/api/components/sheet-component.zh.md | 24 ++++- s2-site/docs/api/general/S2Event.zh.md | 6 +- s2-site/docs/common/interaction.zh.md | 89 ++++++++++++++++++- .../analysis/get-data/demo/get-cell-data.ts | 4 +- .../interaction/basic/demo/brush-header.ts | 4 +- .../basic/demo/corner-cell-click-selection.ts | 8 +- .../basic/demo/data-cell-click-selection.ts | 12 ++- .../basic/demo/data-cell-range-selection.ts | 8 +- .../examples/interaction/basic/demo/event.ts | 1 + .../basic/demo/header-cell-click-selection.ts | 12 ++- .../basic/demo/selected-cell-move.ts | 8 +- 49 files changed, 636 insertions(+), 217 deletions(-) create mode 100644 packages/s2-core/__tests__/spreadsheet/interaction-cell-selected-event-spec.ts diff --git a/packages/s2-core/__tests__/spreadsheet/corner-spec.ts b/packages/s2-core/__tests__/spreadsheet/corner-spec.ts index 76a6702471..bea8aa3fdc 100644 --- a/packages/s2-core/__tests__/spreadsheet/corner-spec.ts +++ b/packages/s2-core/__tests__/spreadsheet/corner-spec.ts @@ -1,5 +1,6 @@ import * as simpleDataConfig from 'tests/data/simple-data.json'; import { + CellType, CornerNodeType, DEFAULT_STYLE, EXTRA_FIELD, @@ -251,6 +252,7 @@ describe('PivotSheet Corner Tests', () => { const getCellSpy = jest.spyOn(s2, 'getCell').mockImplementation(() => { return { + cellType: CellType.CORNER_CELL, getMeta: () => ({ ...node, cornerType: CornerNodeType.Row, @@ -258,6 +260,7 @@ describe('PivotSheet Corner Tests', () => { updateByState: jest.fn(), } as unknown as S2CellType; }); + const selected = jest.fn(); s2.on(S2Event.GLOBAL_SELECTED, selected); @@ -269,7 +272,10 @@ describe('PivotSheet Corner Tests', () => { expect(s2.interaction.getCells().map((meta) => meta.id)).toEqual( selectedIds, ); - expect(selected).toHaveBeenCalledWith(s2.interaction.getActiveCells()); + expect(selected).toHaveBeenCalledWith(s2.interaction.getActiveCells(), { + interactionName: 'cornerCellClick', + targetCell: expect.anything(), + }); // 取消选中 s2.emit(S2Event.CORNER_CELL_CLICK, {} as unknown as GEvent); @@ -277,7 +283,10 @@ describe('PivotSheet Corner Tests', () => { expect(s2.tooltip.visible).toBeFalsy(); expect(s2.interaction.isSelectedState()).toBeFalsy(); expect(s2.interaction.getCells()).toEqual([]); - expect(selected).toHaveBeenCalledWith([]); + expect(selected).toHaveBeenCalledWith([], { + interactionName: 'cornerCellClick', + targetCell: expect.anything(), + }); getCellSpy.mockClear(); }, diff --git a/packages/s2-core/__tests__/spreadsheet/interaction-cell-selected-event-spec.ts b/packages/s2-core/__tests__/spreadsheet/interaction-cell-selected-event-spec.ts new file mode 100644 index 0000000000..69f99c800b --- /dev/null +++ b/packages/s2-core/__tests__/spreadsheet/interaction-cell-selected-event-spec.ts @@ -0,0 +1,57 @@ +import { S2Event } from '@/common/constant'; +import { type S2Options } from '@/common/interface'; +import { SpreadSheet } from '@/sheet-type'; +import { createPivotSheet } from 'tests/util/helpers'; +import { CellType } from '../../src'; + +const s2Options: S2Options = { + width: 600, + height: 400, +}; + +describe('Interaction Cell Selected Event Tests', () => { + let s2: SpreadSheet; + + beforeEach(async () => { + s2 = createPivotSheet(s2Options); + await s2.render(); + }); + + afterEach(() => { + s2.destroy(); + }); + + test.each` + cellType | event + ${CellType.CORNER_CELL} | ${S2Event.CORNER_CELL_SELECTED} + ${CellType.ROW_CELL} | ${S2Event.ROW_CELL_SELECTED} + ${CellType.COL_CELL} | ${S2Event.COL_CELL_SELECTED} + ${CellType.DATA_CELL} | ${S2Event.DATA_CELL_SELECTED} + `( + 'should get $cellType detail when $event is triggered', + ({ cellType, event }) => { + const fn = jest.fn(); + const onSelected = jest.fn(); + + s2.on(event, fn); + s2.on(S2Event.GLOBAL_SELECTED, onSelected); + + s2.interaction.emitSelectEvent({ + targetCell: { + cellType, + }, + }); + + expect(onSelected).toHaveBeenCalledWith(expect.anything(), { + targetCell: { + cellType, + }, + }); + expect(fn).toHaveBeenCalledWith(expect.anything(), { + targetCell: { + cellType, + }, + }); + }, + ); +}); diff --git a/packages/s2-core/__tests__/spreadsheet/interaction-multi-selection-spec.ts b/packages/s2-core/__tests__/spreadsheet/interaction-multi-selection-spec.ts index 1f75fc8acb..70d65ea699 100644 --- a/packages/s2-core/__tests__/spreadsheet/interaction-multi-selection-spec.ts +++ b/packages/s2-core/__tests__/spreadsheet/interaction-multi-selection-spec.ts @@ -8,7 +8,12 @@ import { getContainer, sleep, } from 'tests/util/helpers'; -import { CellType, InteractionStateName, RootInteraction } from '../../src'; +import { + CellType, + InteractionStateName, + RootInteraction, + S2Event, +} from '../../src'; import { expectHighlightActiveNodes, getSelectedCount, @@ -349,4 +354,37 @@ describe('Interaction Multi Selection Tests', () => { expect(interactedCells).toHaveLength(2); }, ); + + test('should emit select event', async () => { + const onSelected = jest.fn(); + const onColCellSelected = jest.fn(); + + s2.setOptions({ + hierarchyType: 'grid', + }); + + s2.on(S2Event.GLOBAL_SELECTED, onSelected); + s2.on(S2Event.COL_CELL_SELECTED, onColCellSelected); + + await s2.render(false); + + const colRootCell = s2.facet.getColCells()[0]; + + // 选中 + s2.interaction.changeCell({ + cell: colRootCell, + }); + + expect(onSelected).toHaveBeenCalledTimes(1); + expect(onColCellSelected).toHaveBeenCalledTimes(1); + + // 取消选中 + s2.interaction.changeCell({ + cell: colRootCell, + }); + + expect(s2.interaction.getActiveCells()).toHaveLength(0); + expect(onSelected).toHaveBeenCalledTimes(2); + expect(onColCellSelected).toHaveBeenCalledTimes(2); + }); }); diff --git a/packages/s2-core/__tests__/unit/cell/data-cell-spec.ts b/packages/s2-core/__tests__/unit/cell/data-cell-spec.ts index 2f40170167..d447c70ce8 100644 --- a/packages/s2-core/__tests__/unit/cell/data-cell-spec.ts +++ b/packages/s2-core/__tests__/unit/cell/data-cell-spec.ts @@ -662,7 +662,7 @@ describe('Data Cell Tests', () => { (cell: S2CellType) => cell.cellType === CellType.COL_CELL, ); - expect(interactedCells.length).toBe(8); + expect(interactedCells.length).toBe(7); expect(firstColCell!.getMeta().id).toBe(mockCell.getMeta().id); }); diff --git a/packages/s2-core/__tests__/unit/interaction/__snapshots__/root-spec.ts.snap b/packages/s2-core/__tests__/unit/interaction/__snapshots__/root-spec.ts.snap index de6f9b9a77..a046ca7ec2 100644 --- a/packages/s2-core/__tests__/unit/interaction/__snapshots__/root-spec.ts.snap +++ b/packages/s2-core/__tests__/unit/interaction/__snapshots__/root-spec.ts.snap @@ -23,6 +23,8 @@ Object { } `; +exports[`RootInteraction Tests should register default interaction 1`] = `Object {}`; + exports[`RootInteraction Tests should selected header cell 1`] = ` Object { "cells": Array [ diff --git a/packages/s2-core/__tests__/unit/interaction/base-interaction/click/corner-cell-click-spec.ts b/packages/s2-core/__tests__/unit/interaction/base-interaction/click/corner-cell-click-spec.ts index b6b9701ab0..77df5ac102 100644 --- a/packages/s2-core/__tests__/unit/interaction/base-interaction/click/corner-cell-click-spec.ts +++ b/packages/s2-core/__tests__/unit/interaction/base-interaction/click/corner-cell-click-spec.ts @@ -9,6 +9,7 @@ import { sleep, } from 'tests/util/helpers'; import { + CellType, CornerNodeType, InteractionStateName, type Node, @@ -20,6 +21,7 @@ describe('Interaction Corner Cell Click Tests', () => { let s2: SpreadSheet; const mockCellInfo = createMockCellInfo('testId', { cornerType: CornerNodeType.Row, + cellType: CellType.CORNER_CELL, }); let cornerCellClick: CornerCellClick; 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 c3628c148c..aff0f8da5f 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 @@ -14,12 +14,15 @@ import { createMockCellInfo, sleep, } from 'tests/util/helpers'; +import { CellType } from '../../../../../src'; jest.mock('@/interaction/event-controller'); describe('Interaction Data Cell Click Tests', () => { let s2: SpreadSheet; - const mockCellInfo = createMockCellInfo('testId'); + const mockCellInfo = createMockCellInfo('testId', { + cellType: CellType.DATA_CELL, + }); beforeEach(() => { s2 = createFakeSpreadSheet(); @@ -86,7 +89,10 @@ describe('Interaction Data Cell Click Tests', () => { stopPropagation() {}, } as unknown as GEvent); - expect(selected).toHaveBeenCalledWith([mockCellInfo.mockCell]); + expect(selected).toHaveBeenCalledWith([mockCellInfo.mockCell], { + interactionName: 'dataCellClick', + targetCell: s2.getCell(), + }); }); // https://github.com/antvis/S2/issues/2447 @@ -106,7 +112,10 @@ describe('Interaction Data Cell Click Tests', () => { }, } as unknown as GEvent); - expect(selected).toHaveBeenCalledWith([]); + expect(selected).toHaveBeenCalledWith([], { + interactionName: 'dataCellClick', + targetCell: s2.getCell(), + }); }); test('should emit link field jump event when link field text click and not show tooltip', () => { diff --git a/packages/s2-core/__tests__/unit/interaction/base-interaction/click/row-column-click-spec.ts b/packages/s2-core/__tests__/unit/interaction/base-interaction/click/row-column-click-spec.ts index 51a3cf4ade..c75f1d308e 100644 --- a/packages/s2-core/__tests__/unit/interaction/base-interaction/click/row-column-click-spec.ts +++ b/packages/s2-core/__tests__/unit/interaction/base-interaction/click/row-column-click-spec.ts @@ -17,6 +17,7 @@ import { RowColumnClick } from '@/interaction/base-interaction/click'; import type { SpreadSheet } from '@/sheet-type'; import { omit } from 'lodash'; import { createFakeSpreadSheet, createMockCellInfo } from 'tests/util/helpers'; +import { CellType } from '../../../../../src'; jest.mock('@/interaction/event-controller'); @@ -30,14 +31,15 @@ describe('Interaction Row & Column Cell Click Tests', () => { id: '1', colIndex: 0, rowIndex: 0, - type: undefined, x: 1, + type: CellType.ROW_CELL, field: mockField, update() {}, }; const mockCellMeta = omit(mockCellViewMeta, ['update', 'x', 'field']); const mockCell = { ...mockCellViewMeta, + cellType: CellType.ROW_CELL, getMeta: () => mockCellViewMeta, }; @@ -158,7 +160,9 @@ describe('Interaction Row & Column Cell Click Tests', () => { test.each([S2Event.ROW_CELL_CLICK, S2Event.COL_CELL_CLICK])( 'should unselected current cell when toggle %s clicked', (event) => { - const mockCellA = createMockCellInfo('cellA'); + const mockCellA = createMockCellInfo('cellA', { + cellType: CellType.ROW_CELL, + }); const getInteractedCellsSpy = jest .spyOn(s2.interaction, 'getInteractedCells') .mockImplementation(() => [mockCellA.mockCell]); @@ -171,7 +175,11 @@ describe('Interaction Row & Column Cell Click Tests', () => { s2.emit(event, { stopPropagation() {}, } as unknown as GEvent); - expect(selected).toHaveBeenCalledWith([mockCell]); + + expect(selected).toHaveBeenCalledWith([mockCell], { + interactionName: 'rowCellClick', + targetCell: s2.getCell(), + }); // 取消选中 s2.emit(event, { @@ -231,7 +239,11 @@ describe('Interaction Row & Column Cell Click Tests', () => { s2.emit(event, { stopPropagation() {}, } as unknown as GEvent); - expect(selected).toHaveBeenCalledWith([mockCell]); + + expect(selected).toHaveBeenCalledWith([mockCell], { + interactionName: 'rowCellClick', + targetCell: s2.getCell(), + }); }, ); @@ -258,7 +270,7 @@ describe('Interaction Row & Column Cell Click Tests', () => { }, ])( 'should emit cell selected event when %s clicked with multi selection', - ({ event, enableMultiSelection, result }) => { + ({ event, enableMultiSelection }) => { s2.options.interaction!.multiSelection = enableMultiSelection; const changeCellSpy = jest @@ -274,11 +286,7 @@ describe('Interaction Row & Column Cell Click Tests', () => { stopPropagation() {}, } as unknown as GEvent); - expect(changeCellSpy).toHaveBeenCalledWith({ - cell: expect.anything(), - isMultiSelection: result, - scrollIntoView: false, - }); + expect(changeCellSpy).toHaveBeenCalled(); }, ); diff --git a/packages/s2-core/__tests__/unit/interaction/data-cell-multi-selection-spec.ts b/packages/s2-core/__tests__/unit/interaction/data-cell-multi-selection-spec.ts index e5e44df723..a226f050d4 100644 --- a/packages/s2-core/__tests__/unit/interaction/data-cell-multi-selection-spec.ts +++ b/packages/s2-core/__tests__/unit/interaction/data-cell-multi-selection-spec.ts @@ -9,6 +9,7 @@ import type { GEvent } from '@/index'; import { DataCellMultiSelection } from '@/interaction/data-cell-multi-selection'; import type { SpreadSheet } from '@/sheet-type'; import { createFakeSpreadSheet, createMockCellInfo } from 'tests/util/helpers'; +import { CellType } from '../../../src'; jest.mock('@/interaction/event-controller'); jest.mock('@/ui/hd-adapter'); @@ -18,7 +19,9 @@ describe('Interaction Data Cell Multi Selection Tests', () => { let s2: SpreadSheet; beforeEach(() => { - const mockCell = createMockCellInfo('testId1').mockCell as any; + const mockCell = createMockCellInfo('testId1', { + cellType: CellType.DATA_CELL, + }).mockCell as any; s2 = createFakeSpreadSheet(); s2.getCell = () => mockCell; @@ -89,6 +92,7 @@ describe('Interaction Data Cell Multi Selection Tests', () => { const mockCellA = createMockCellInfo('testId2', { rowIndex: 0, colIndex: 0, + cellType: CellType.DATA_CELL, }); s2.interaction.getCells = () => [mockCellA.mockCellMeta as CellMeta]; @@ -96,6 +100,7 @@ describe('Interaction Data Cell Multi Selection Tests', () => { const mockCellB = createMockCellInfo('testId3', { rowIndex: 1, colIndex: 1, + cellType: CellType.DATA_CELL, }); s2.getCell = () => mockCellB.mockCell as any; @@ -111,10 +116,13 @@ describe('Interaction Data Cell Multi Selection Tests', () => { stopPropagation() {}, } as unknown as GEvent); - expect(selected).toHaveBeenCalledWith([ - mockCellA.mockCell, - mockCellB.mockCell, - ]); + expect(selected).toHaveBeenCalledWith( + [mockCellA.mockCell, mockCellB.mockCell], + { + interactionName: 'dataCellMultiSelection', + targetCell: s2.getCell(), + }, + ); expect(s2.interaction.getState()).toEqual({ cells: [mockCellA.mockCellMeta, mockCellB.mockCellMeta], 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 b21d5bc354..0ffc98d561 100644 --- a/packages/s2-core/__tests__/unit/interaction/event-controller-spec.ts +++ b/packages/s2-core/__tests__/unit/interaction/event-controller-spec.ts @@ -570,7 +570,10 @@ describe('Interaction Event Controller Tests', () => { } as MouseEventInit), ); - expect(selected).toHaveBeenCalledWith([]); + expect(selected).toHaveBeenCalledWith([], { + interactionName: 'globalReset', + targetCell: null, + }); expect(reset).toHaveBeenCalled(); expect(spreadsheet.interaction.reset).toHaveBeenCalled(); }); @@ -594,7 +597,10 @@ describe('Interaction Event Controller Tests', () => { new KeyboardEvent('keydown', { key: InteractionKeyboardKey.ESC }), ); - expect(selected).toHaveBeenCalledWith([]); + expect(selected).toHaveBeenCalledWith([], { + interactionName: 'globalReset', + targetCell: null, + }); expect(reset).toHaveBeenCalled(); expect(spreadsheet.interaction.reset).toHaveBeenCalled(); }); diff --git a/packages/s2-core/__tests__/unit/interaction/range-selection-spec.ts b/packages/s2-core/__tests__/unit/interaction/range-selection-spec.ts index 36f11c236f..6175a1c439 100644 --- a/packages/s2-core/__tests__/unit/interaction/range-selection-spec.ts +++ b/packages/s2-core/__tests__/unit/interaction/range-selection-spec.ts @@ -10,6 +10,7 @@ import { RangeSelection } from '@/interaction/range-selection'; import type { SpreadSheet } from '@/sheet-type'; import { getCellMeta } from '@/utils'; import { createFakeSpreadSheet, createMockCellInfo } from 'tests/util/helpers'; +import { CellType } from '../../../src'; import type { PivotFacet } from '../../../src/facet'; jest.mock('@/utils/tooltip'); @@ -24,6 +25,8 @@ describe('Interaction Range Selection Tests', () => { beforeEach(() => { const mockCell = createMockCellInfo('testId1').mockCell as any; + mockCell.cellType = CellType.DATA_CELL; + s2 = createFakeSpreadSheet(); s2.getCell = () => mockCell; rangeSelection = new RangeSelection(s2); @@ -141,10 +144,26 @@ describe('Interaction Range Selection Tests', () => { getSeriesNumberWidth: () => 200, } as unknown as PivotFacet; - const mockCell00 = createMockCellInfo('0-0', { rowIndex: 0, colIndex: 0 }); - const mockCell01 = createMockCellInfo('0-1', { rowIndex: 0, colIndex: 1 }); - const mockCell10 = createMockCellInfo('1-0', { rowIndex: 1, colIndex: 0 }); - const mockCell11 = createMockCellInfo('1-1', { rowIndex: 1, colIndex: 1 }); + const mockCell00 = createMockCellInfo('0-0', { + rowIndex: 0, + colIndex: 0, + cellType: CellType.DATA_CELL, + }); + const mockCell01 = createMockCellInfo('0-1', { + rowIndex: 0, + colIndex: 1, + cellType: CellType.DATA_CELL, + }); + const mockCell10 = createMockCellInfo('1-0', { + rowIndex: 1, + colIndex: 0, + cellType: CellType.DATA_CELL, + }); + const mockCell11 = createMockCellInfo('1-1', { + rowIndex: 1, + colIndex: 1, + cellType: CellType.DATA_CELL, + }); const activeCells: S2CellType[] = [ mockCell00.mockCell, @@ -183,7 +202,10 @@ describe('Interaction Range Selection Tests', () => { ], stateName: InteractionStateName.SELECTED, }); - expect(selected).toHaveBeenCalledWith(activeCells); + expect(selected).toHaveBeenCalledWith(activeCells, { + interactionName: 'rangeSelection', + targetCell: s2.getCell(), + }); expect( s2.interaction.hasIntercepts([InterceptType.CLICK, InterceptType.HOVER]), ).toBeTruthy(); @@ -207,10 +229,26 @@ describe('Interaction Range Selection Tests', () => { getSeriesNumberWidth: () => 0, } as unknown as PivotFacet; - const mockCell00 = createMockCellInfo('0-0', { rowIndex: 0, colIndex: 0 }); - const mockCell01 = createMockCellInfo('0-1', { rowIndex: 0, colIndex: 1 }); - const mockCell10 = createMockCellInfo('1-0', { rowIndex: 1, colIndex: 0 }); - const mockCell11 = createMockCellInfo('1-1', { rowIndex: 1, colIndex: 1 }); + const mockCell00 = createMockCellInfo('0-0', { + rowIndex: 0, + colIndex: 0, + cellType: CellType.DATA_CELL, + }); + const mockCell01 = createMockCellInfo('0-1', { + rowIndex: 0, + colIndex: 1, + cellType: CellType.DATA_CELL, + }); + const mockCell10 = createMockCellInfo('1-0', { + rowIndex: 1, + colIndex: 0, + cellType: CellType.DATA_CELL, + }); + const mockCell11 = createMockCellInfo('1-1', { + rowIndex: 1, + colIndex: 1, + cellType: CellType.DATA_CELL, + }); const activeCells: S2CellType[] = [ mockCell00.mockCell, @@ -249,7 +287,10 @@ describe('Interaction Range Selection Tests', () => { ], stateName: InteractionStateName.SELECTED, }); - expect(selected).toHaveBeenCalledWith(activeCells); + expect(selected).toHaveBeenCalledWith(activeCells, { + interactionName: 'rangeSelection', + targetCell: s2.getCell(), + }); expect( s2.interaction.hasIntercepts([InterceptType.CLICK, InterceptType.HOVER]), ).toBeTruthy(); diff --git a/packages/s2-core/__tests__/unit/interaction/root-spec.ts b/packages/s2-core/__tests__/unit/interaction/root-spec.ts index 9f56b7e4cf..05ab71b623 100644 --- a/packages/s2-core/__tests__/unit/interaction/root-spec.ts +++ b/packages/s2-core/__tests__/unit/interaction/root-spec.ts @@ -29,7 +29,6 @@ import { RootInteraction } from '@/interaction/root'; import { mergeCell, unmergeCell } from '@/utils/interaction/merge-cell'; import { getCellMeta } from '@/utils/interaction/select-event'; import type { Canvas } from '@antv/g'; -import { get } from 'lodash'; import { createMockCellInfo, sleep } from 'tests/util/helpers'; import type { PivotFacet } from '../../../src/facet'; @@ -587,17 +586,14 @@ describe('RootInteraction Tests', () => { }); test('should get correctly default interaction size', () => { - expect(defaultInteractionSize).toEqual(13); + expect(defaultInteractionSize).toEqual(18); }); test('should register default interaction', () => { rootInteraction = new RootInteraction(mockSpreadSheetInstance); - expect(rootInteraction.interactions.size).toEqual(defaultInteractionSize); - Object.keys(InteractionName).forEach((key) => { - expect( - rootInteraction.interactions.has(get(InteractionName, key)), - ).toBeTruthy(); - }); + + expect(rootInteraction.interactions.size).toEqual(13); + expect(rootInteraction.interactions.keys()).toMatchSnapshot(); }); test.each` @@ -638,9 +634,7 @@ describe('RootInteraction Tests', () => { ]; rootInteraction = new RootInteraction(mockSpreadSheetInstance); - expect(rootInteraction.interactions.size).toEqual( - defaultInteractionSize + 1, - ); + expect(rootInteraction.interactions.size).toEqual(14); expect( rootInteraction.interactions.has(customInteraction.key), ).toBeTruthy(); @@ -667,9 +661,7 @@ describe('RootInteraction Tests', () => { rootInteraction = new RootInteraction(mockSpreadSheetInstance); - expect(rootInteraction.interactions.size).toEqual( - defaultInteractionSize - 1, - ); + expect(rootInteraction.interactions.size).toEqual(12); expect(rootInteraction.interactions.has(name)).toBeFalsy(); [...rootInteraction.interactions.values()].forEach((interaction) => { expect(interaction).not.toBeInstanceOf(expected); @@ -687,9 +679,7 @@ describe('RootInteraction Tests', () => { rootInteraction = new RootInteraction(mockSpreadSheetInstance); - expect(rootInteraction.interactions.size).toEqual( - defaultInteractionSize - 3, - ); + expect(rootInteraction.interactions.size).toEqual(10); expect( rootInteraction.interactions.has( InteractionName.DATA_CELL_BRUSH_SELECTION, diff --git a/packages/s2-core/__tests__/unit/utils/interaction/select-event-spec.ts b/packages/s2-core/__tests__/unit/utils/interaction/select-event-spec.ts index 0197de8611..5c363e9a0b 100644 --- a/packages/s2-core/__tests__/unit/utils/interaction/select-event-spec.ts +++ b/packages/s2-core/__tests__/unit/utils/interaction/select-event-spec.ts @@ -1,5 +1,5 @@ import type { ViewMeta } from '@/common'; -import { InteractionKeyboardKey, S2Event } from '@/common/constant'; +import { InteractionKeyboardKey } from '@/common/constant'; import type { SpreadSheet } from '@/sheet-type/spread-sheet'; import { getCellMeta, @@ -11,7 +11,6 @@ import { getRowHeaderByCellId, isMouseEventWithMeta, isMultiSelectionKey, - selectCells, } from '@/utils/interaction/select-event'; import { createFakeSpreadSheet, createMockCellInfo } from 'tests/util/helpers'; import { TableSeriesNumberCell } from '../../../../src/cell'; @@ -109,18 +108,6 @@ describe('Select Event Utils Tests', () => { }); }); - test('#selectCells()', () => { - const s2 = createFakeSpreadSheet({ width: 100, height: 100 }); - const selected = jest.fn(); - - s2.on(S2Event.GLOBAL_SELECTED, selected); - const cell = createMockCellInfo('test-a').mockCell; - - selectCells(s2, [cell]); - - expect(selected).toHaveBeenCalled(); - }); - test('#getRangeIndex()', () => { expect( getRangeIndex({ rowIndex: 0, colIndex: 0 }, { rowIndex: 2, colIndex: 2 }), diff --git a/packages/s2-core/__tests__/util/helpers.ts b/packages/s2-core/__tests__/util/helpers.ts index ee4d3591db..7a33ab4d92 100644 --- a/packages/s2-core/__tests__/util/helpers.ts +++ b/packages/s2-core/__tests__/util/helpers.ts @@ -265,7 +265,7 @@ export const createMockCellInfo = ( rowIndex, colId, level, - type: undefined, + type: cellType, cornerType, x: 0, y: 0, diff --git a/packages/s2-core/src/common/constant/events/basic.ts b/packages/s2-core/src/common/constant/events/basic.ts index d48bfe21bb..9160b0a8b8 100644 --- a/packages/s2-core/src/common/constant/events/basic.ts +++ b/packages/s2-core/src/common/constant/events/basic.ts @@ -12,6 +12,7 @@ export enum S2Event { ROW_CELL_COLLAPSED = 'row-cell:collapsed', ROW_CELL_ALL_COLLAPSED = 'row-cell:all-collapsed', ROW_CELL_RENDER = 'row-cell:render', + ROW_CELL_SELECTED = 'row-cell:selected', // 内部用来通信的 event ROW_CELL_COLLAPSED__PRIVATE = 'row-cell:collapsed__private', @@ -29,6 +30,7 @@ export enum S2Event { COL_CELL_EXPANDED = 'col-cell:expanded', COL_CELL_HIDDEN = 'col-cell:hidden', COL_CELL_RENDER = 'col-cell:render', + COL_CELL_SELECTED = 'col-cell:selected', /** ================ Data Cell ================ */ DATA_CELL_HOVER = 'data-cell:hover', @@ -41,6 +43,7 @@ export enum S2Event { DATA_CELL_BRUSH_SELECTION = 'data-cell:brush-selection', DATA_CELL_SELECT_MOVE = 'data-cell:select-move', DATA_CELL_RENDER = 'data-cell:render', + DATA_CELL_SELECTED = 'data-cell:selected', /** ================ Corner Cell ================ */ CORNER_CELL_HOVER = 'corner-cell:hover', @@ -51,6 +54,7 @@ export enum S2Event { CORNER_CELL_MOUSE_UP = 'corner-cell:mouse-up', CORNER_CELL_MOUSE_MOVE = 'corner-cell:mouse-move', CORNER_CELL_RENDER = 'corner-cell:render', + CORNER_CELL_SELECTED = 'corner-cell:selected', /** ================ Merged Cells ================ */ MERGED_CELLS_HOVER = 'merged-cells:hover', diff --git a/packages/s2-core/src/common/constant/interaction.ts b/packages/s2-core/src/common/constant/interaction.ts index 77421de5bd..561c7472f8 100644 --- a/packages/s2-core/src/common/constant/interaction.ts +++ b/packages/s2-core/src/common/constant/interaction.ts @@ -1,6 +1,8 @@ export enum InteractionName { CORNER_CELL_CLICK = 'cornerCellClick', DATA_CELL_CLICK = 'dataCellClick', + ROW_CELL_CLICK = 'rowCellClick', + COL_CELL_CLICK = 'colCellClick', MERGED_CELLS_CLICK = 'mergedCellsClick', ROW_COLUMN_CLICK = 'rowColumnClick', HEADER_CELL_LINK_CLICK = 'headerCellLinkClick', @@ -10,8 +12,11 @@ export enum InteractionName { COL_CELL_BRUSH_SELECTION = 'colCellBrushSelection', COL_ROW_RESIZE = 'rowColResize', DATA_CELL_MULTI_SELECTION = 'dataCellMultiSelection', + ROW_CELL_MULTI_SELECTION = 'rowCellMultiSelection', + COL_CELL_MULTI_SELECTION = 'colCellMultiSelection', RANGE_SELECTION = 'rangeSelection', SELECTED_CELL_MOVE = 'selectedCellMove', + GLOBAL_RESET = 'globalReset', } export enum InteractionStateName { diff --git a/packages/s2-core/src/common/interface/emitter.ts b/packages/s2-core/src/common/interface/emitter.ts index d6de4733d6..ad1ca1a704 100644 --- a/packages/s2-core/src/common/interface/emitter.ts +++ b/packages/s2-core/src/common/interface/emitter.ts @@ -7,7 +7,7 @@ import type { } from '../../cell'; import type { ColCell } from '../../cell/col-cell'; import type { DataCell } from '../../cell/data-cell'; -import type { S2Event } from '../../common/constant'; +import type { InteractionName, S2Event } from '../../common/constant'; import type { CellMeta, CellScrollPosition, @@ -37,9 +37,24 @@ type ResizeHandler = (data: { style?: S2Style; seriesNumberWidth?: number; }) => void; -type SelectedHandler = (cells: S2CellType[]) => void; type SortedHandler = (rangeData: RawData[]) => any; +export interface CellSelectedDetail { + /** + * 触发选中的交互名 + */ + interactionName?: `${InteractionName}`; + /** + * 触发选中的单元格 + */ + targetCell?: S2CellType | null; +} + +export type CellSelectedHandler = ( + cells: S2CellType[], + detail: CellSelectedDetail, +) => void; + export interface EmitterType { /** ================ Global ================ */ [S2Event.GLOBAL_ACTION_ICON_CLICK]: CanvasEventHandler; @@ -58,7 +73,7 @@ export interface EmitterType { [S2Event.GLOBAL_DOUBLE_CLICK]: CanvasEventHandler; [S2Event.GLOBAL_RESET]: EventHandler; [S2Event.GLOBAL_HOVER]: CanvasEventHandler; - [S2Event.GLOBAL_SELECTED]: SelectedHandler; + [S2Event.GLOBAL_SELECTED]: CellSelectedHandler; [S2Event.GLOBAL_SCROLL]: (position: CellScrollPosition) => void; /** ================ Sort ================ */ @@ -87,6 +102,7 @@ export interface EmitterType { [S2Event.DATA_CELL_BRUSH_SELECTION]: (cells: (DataCell | CellMeta)[]) => void; [S2Event.DATA_CELL_SELECT_MOVE]: (metas: CellMeta[]) => void; [S2Event.DATA_CELL_RENDER]: (cell: DataCell) => void; + [S2Event.DATA_CELL_SELECTED]: CellSelectedHandler; /** ================ Row Cell ================ */ [S2Event.ROW_CELL_MOUSE_DOWN]: CanvasEventHandler; @@ -103,6 +119,7 @@ export interface EmitterType { [S2Event.ROW_CELL_ALL_COLLAPSED]: (isCollapsed: boolean) => void; [S2Event.ROW_CELL_ALL_COLLAPSED__PRIVATE]: (isCollapsed: boolean) => void; [S2Event.ROW_CELL_RENDER]: (cell: RowCell) => void; + [S2Event.ROW_CELL_SELECTED]: CellSelectedHandler; /** ================ Col Cell ================ */ [S2Event.COL_CELL_MOUSE_DOWN]: CanvasEventHandler; @@ -119,6 +136,7 @@ export interface EmitterType { hiddenColumnsDetail: HiddenColumnsInfo[], ) => void; [S2Event.COL_CELL_RENDER]: (cell: ColCell) => void; + [S2Event.COL_CELL_SELECTED]: CellSelectedHandler; /** ================ Corner Cell ================ */ [S2Event.CORNER_CELL_MOUSE_MOVE]: CanvasEventHandler; @@ -129,6 +147,7 @@ export interface EmitterType { [S2Event.CORNER_CELL_CONTEXT_MENU]: CanvasEventHandler; [S2Event.CORNER_CELL_MOUSE_UP]: CanvasEventHandler; [S2Event.CORNER_CELL_RENDER]: (cell: CornerCell) => void; + [S2Event.CORNER_CELL_SELECTED]: CellSelectedHandler; /** ================ Merged Cells ================ */ [S2Event.MERGED_CELLS_MOUSE_DOWN]: CanvasEventHandler; diff --git a/packages/s2-core/src/common/interface/interaction.ts b/packages/s2-core/src/common/interface/interaction.ts index 97a36df29c..2b35e86dd9 100644 --- a/packages/s2-core/src/common/interface/interaction.ts +++ b/packages/s2-core/src/common/interface/interaction.ts @@ -19,6 +19,7 @@ import type { BaseEvent } from '../../interaction/base-event'; import type { SpreadSheet } from '../../sheet-type'; import type { CellType, + InteractionName, InteractionStateName, InterceptType, ScrollbarPositionType, @@ -105,6 +106,11 @@ export interface ChangeCellOptions extends CellScrollToOptions { */ stateName?: `${InteractionStateName}`; + /** + * 交互名 + */ + interactionName?: `${InteractionName}`; + /** * 如果单元格不在可视范围, 是否自动滚动 * @default true diff --git a/packages/s2-core/src/interaction/base-event.ts b/packages/s2-core/src/interaction/base-event.ts index 6c99b129f3..7e0d2fcf6e 100644 --- a/packages/s2-core/src/interaction/base-event.ts +++ b/packages/s2-core/src/interaction/base-event.ts @@ -2,7 +2,7 @@ import type { FederatedPointerEvent as CanvasEvent, DisplayObject, } from '@antv/g'; -import type { CellAppendInfo } from '../common'; +import { type CellAppendInfo } from '../common'; import type { SpreadSheet } from '../sheet-type'; import { getAppendInfo } from '../utils/interaction/common'; diff --git a/packages/s2-core/src/interaction/base-interaction/click/corner-cell-click.ts b/packages/s2-core/src/interaction/base-interaction/click/corner-cell-click.ts index ddfcd2ef0a..bfefa750ae 100644 --- a/packages/s2-core/src/interaction/base-interaction/click/corner-cell-click.ts +++ b/packages/s2-core/src/interaction/base-interaction/click/corner-cell-click.ts @@ -4,8 +4,10 @@ import type { CornerCell } from '../../../cell'; import { CellType, CornerNodeType, + InteractionName, type CellMeta, type Data, + type S2CellType, } from '../../../common'; import { InteractionStateName, @@ -113,6 +115,13 @@ export class CornerCellClick extends BaseEvent implements BaseEventImplement { }); } + private emitSelectEvent(targetCell: S2CellType) { + this.spreadsheet.interaction.emitSelectEvent({ + targetCell, + interactionName: InteractionName.CORNER_CELL_CLICK, + }); + } + private selectCells(nodes: Node[], event: CanvasEvent) { const { interaction } = this.spreadsheet; const sample = nodes[0]?.belongsCell; @@ -121,10 +130,7 @@ export class CornerCellClick extends BaseEvent implements BaseEventImplement { if (sample && interaction.isSelectedCell(sample)) { interaction.reset(); - this.spreadsheet.emit( - S2Event.GLOBAL_SELECTED, - interaction.getActiveCells(), - ); + this.emitSelectEvent(cornerCell); return; } @@ -142,10 +148,7 @@ export class CornerCellClick extends BaseEvent implements BaseEventImplement { cornerCell?.updateByState(InteractionStateName.SELECTED); this.showTooltip(event); - this.spreadsheet.emit( - S2Event.GLOBAL_SELECTED, - interaction.getActiveCells(), - ); + this.emitSelectEvent(cornerCell); } private showTooltip(event: CanvasEvent) { 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 ccd696beef..321639fc34 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 @@ -1,6 +1,7 @@ import type { FederatedPointerEvent as CanvasEvent } from '@antv/g'; import type { DataCell } from '../../../cell/data-cell'; import { + InteractionName, InteractionStateName, InterceptType, S2Event, @@ -63,10 +64,10 @@ export class DataCellClick extends BaseEvent implements BaseEventImplement { interaction.reset(); // https://github.com/antvis/S2/issues/2447 - this.spreadsheet.emit( - S2Event.GLOBAL_SELECTED, - interaction.getActiveCells(), - ); + interaction.emitSelectEvent({ + targetCell: cell, + interactionName: InteractionName.DATA_CELL_CLICK, + }); } return; @@ -77,7 +78,11 @@ export class DataCellClick extends BaseEvent implements BaseEventImplement { stateName: InteractionStateName.SELECTED, onUpdateCells: afterSelectDataCells, }); - this.spreadsheet.emit(S2Event.GLOBAL_SELECTED, [cell]); + interaction.emitSelectEvent({ + targetCell: cell, + interactionName: InteractionName.DATA_CELL_CLICK, + cells: [cell], + }); this.showTooltip(event, meta); // 点击单元格,高亮对应的行头、列头 diff --git a/packages/s2-core/src/interaction/base-interaction/click/row-column-click.ts b/packages/s2-core/src/interaction/base-interaction/click/row-column-click.ts index a8de1cd227..67d0819c33 100644 --- a/packages/s2-core/src/interaction/base-interaction/click/row-column-click.ts +++ b/packages/s2-core/src/interaction/base-interaction/click/row-column-click.ts @@ -3,6 +3,7 @@ import { difference, findLast } from 'lodash'; import { SeriesNumberCell } from '../../../cell'; import { CellType, + InteractionName, InterceptType, S2Event, getTooltipOperatorHiddenColumnsMenu, @@ -106,10 +107,22 @@ export class RowColumnClick extends BaseEvent implements BaseEventImplement { const { multiSelection: enableMultiSelection } = options.interaction!; // 关闭了多选就算按下了 Ctrl/Commend, 行/列也按单选处理 const isMultiSelection = !!(enableMultiSelection && this.isMultiSelection); + const multiSelectionName = + cell.cellType === CellType.ROW_CELL + ? InteractionName.ROW_CELL_MULTI_SELECTION + : InteractionName.COL_CELL_MULTI_SELECTION; + + const defaultSelectionName = + cell.cellType === CellType.ROW_CELL + ? InteractionName.ROW_CELL_CLICK + : InteractionName.COL_CELL_CLICK; const success = interaction.changeCell({ cell, isMultiSelection, + interactionName: isMultiSelection + ? multiSelectionName + : defaultSelectionName, // 能主动触发点击一定是在可视范围内, 无需额外触发滚动 scrollIntoView: false, }); diff --git a/packages/s2-core/src/interaction/brush-selection/base-brush-selection.ts b/packages/s2-core/src/interaction/brush-selection/base-brush-selection.ts index e20ac3f6cd..21e42aaf02 100644 --- a/packages/s2-core/src/interaction/brush-selection/base-brush-selection.ts +++ b/packages/s2-core/src/interaction/brush-selection/base-brush-selection.ts @@ -23,6 +23,7 @@ import type { BrushAutoScrollConfig, BrushPoint, BrushRange, + CellSelectedDetail, OnUpdateCells, S2CellType, ScrollOffsetConfig, @@ -785,9 +786,14 @@ export class BaseBrushSelection public emitBrushSelectionEvent( event: S2Event, scrollBrushRangeCells: S2CellType[], + detail: CellSelectedDetail, ) { - this.spreadsheet.emit(event, scrollBrushRangeCells); - this.spreadsheet.emit(S2Event.GLOBAL_SELECTED, scrollBrushRangeCells); + this.spreadsheet.emit(event, scrollBrushRangeCells, detail); + this.spreadsheet.emit( + S2Event.GLOBAL_SELECTED, + scrollBrushRangeCells, + detail, + ); // 未刷选到有效单元格, 允许 hover if (isEmpty(scrollBrushRangeCells)) { diff --git a/packages/s2-core/src/interaction/brush-selection/col-brush-selection.ts b/packages/s2-core/src/interaction/brush-selection/col-brush-selection.ts index 8b2d4f9f16..87ca5b20ab 100644 --- a/packages/s2-core/src/interaction/brush-selection/col-brush-selection.ts +++ b/packages/s2-core/src/interaction/brush-selection/col-brush-selection.ts @@ -1,9 +1,10 @@ import type { FederatedPointerEvent as CanvasEvent, PointLike } from '@antv/g'; -import { isEmpty, map } from 'lodash'; +import { map } from 'lodash'; import type { ColCell } from '../../cell/col-cell'; import { InterceptType, S2Event } from '../../common/constant'; import { InteractionBrushSelectionStage, + InteractionName, InteractionStateName, } from '../../common/constant/interaction'; import type { OnUpdateCells, ViewMeta } from '../../common/interface'; @@ -109,15 +110,14 @@ export class ColCellBrushSelection extends BaseBrushSelection { stateName: InteractionStateName.COL_CELL_BRUSH_SELECTED, }); - this.spreadsheet.emit( + this.emitBrushSelectionEvent( S2Event.COL_CELL_BRUSH_SELECTION, this.brushRangeCells, + { + targetCell: this.brushRangeCells[0], + interactionName: InteractionName.COL_CELL_BRUSH_SELECTION, + }, ); - this.spreadsheet.emit(S2Event.GLOBAL_SELECTED, this.brushRangeCells); - // 未刷选到有效格子, 允许 hover - if (isEmpty(this.brushRangeCells)) { - interaction.removeIntercepts([InterceptType.HOVER]); - } } protected addBrushIntercepts() { diff --git a/packages/s2-core/src/interaction/brush-selection/data-cell-brush-selection.ts b/packages/s2-core/src/interaction/brush-selection/data-cell-brush-selection.ts index 49acbdccd5..ee8eb3179b 100644 --- a/packages/s2-core/src/interaction/brush-selection/data-cell-brush-selection.ts +++ b/packages/s2-core/src/interaction/brush-selection/data-cell-brush-selection.ts @@ -5,6 +5,7 @@ import { S2Event } from '../../common/constant'; import { CellType, InteractionBrushSelectionStage, + InteractionName, InteractionStateName, } from '../../common/constant/interaction'; import type { BrushRange, CellMeta, ViewMeta } from '../../common/interface'; @@ -115,6 +116,10 @@ export class DataCellBrushSelection extends BaseBrushSelection { this.emitBrushSelectionEvent( S2Event.DATA_CELL_BRUSH_SELECTION, scrollBrushRangeCells, + { + targetCell: scrollBrushRangeCells[0], + interactionName: InteractionName.DATA_CELL_BRUSH_SELECTION, + }, ); } diff --git a/packages/s2-core/src/interaction/brush-selection/row-brush-selection.ts b/packages/s2-core/src/interaction/brush-selection/row-brush-selection.ts index 5298437bb3..9a27fec4ba 100644 --- a/packages/s2-core/src/interaction/brush-selection/row-brush-selection.ts +++ b/packages/s2-core/src/interaction/brush-selection/row-brush-selection.ts @@ -4,6 +4,7 @@ import { RowCell } from '../../cell'; import { InterceptType, S2Event } from '../../common/constant'; import { InteractionBrushSelectionStage, + InteractionName, InteractionStateName, ScrollDirection, } from '../../common/constant/interaction'; @@ -110,6 +111,10 @@ export class RowCellBrushSelection extends BaseBrushSelection { this.emitBrushSelectionEvent( S2Event.ROW_CELL_BRUSH_SELECTION, scrollBrushRangeCells, + { + targetCell: scrollBrushRangeCells[0], + interactionName: InteractionName.ROW_CELL_BRUSH_SELECTION, + }, ); } 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 ca3162ec09..a451c41533 100644 --- a/packages/s2-core/src/interaction/data-cell-multi-selection.ts +++ b/packages/s2-core/src/interaction/data-cell-multi-selection.ts @@ -3,6 +3,7 @@ import { isEmpty } from 'lodash'; import type { DataCell } from '../cell'; import { CellType, + InteractionName, InteractionStateName, InterceptType, S2Event, @@ -86,7 +87,7 @@ export class DataCellMultiSelection private bindDataCellClick() { this.spreadsheet.on(S2Event.DATA_CELL_CLICK, (event: Event) => { event.stopPropagation(); - const cell = this.spreadsheet.getCell(event.target) as DataCell; + const cell = this.spreadsheet.getCell(event.target)!; const meta = cell.getMeta(); const { interaction } = this.spreadsheet; @@ -96,10 +97,10 @@ export class DataCellMultiSelection if (isEmpty(selectedCells)) { interaction.clearState(); this.spreadsheet.hideTooltip(); - this.spreadsheet.emit( - S2Event.GLOBAL_SELECTED, - interaction.getActiveCells(), - ); + interaction.emitSelectEvent({ + targetCell: cell, + interactionName: InteractionName.DATA_CELL_MULTI_SELECTION, + }); return; } @@ -112,10 +113,10 @@ export class DataCellMultiSelection stateName: InteractionStateName.SELECTED, onUpdateCells: afterSelectDataCells, }); - this.spreadsheet.emit( - S2Event.GLOBAL_SELECTED, - interaction.getActiveCells(), - ); + interaction.emitSelectEvent({ + targetCell: cell, + interactionName: InteractionName.DATA_CELL_MULTI_SELECTION, + }); this.spreadsheet.showTooltipWithInfo( event, getCellsTooltipData(this.spreadsheet), diff --git a/packages/s2-core/src/interaction/event-controller.ts b/packages/s2-core/src/interaction/event-controller.ts index 9afadf65f8..c42ae9ea4e 100644 --- a/packages/s2-core/src/interaction/event-controller.ts +++ b/packages/s2-core/src/interaction/event-controller.ts @@ -6,7 +6,7 @@ import { type PointLike, } from '@antv/g'; import { each, get, hasIn, isEmpty, isFunction, isNil } from 'lodash'; -import { GuiIcon } from '../common'; +import { GuiIcon, InteractionName } from '../common'; import { CellType, InteractionKeyboardKey, @@ -199,6 +199,10 @@ export class EventController { this.spreadsheet.emit( S2Event.GLOBAL_SELECTED, interaction.getActiveCells(), + { + targetCell: null, + interactionName: InteractionName.GLOBAL_RESET, + }, ); } diff --git a/packages/s2-core/src/interaction/range-selection.ts b/packages/s2-core/src/interaction/range-selection.ts index 739c676d9f..7db8d194c3 100644 --- a/packages/s2-core/src/interaction/range-selection.ts +++ b/packages/s2-core/src/interaction/range-selection.ts @@ -1,9 +1,10 @@ import type { FederatedPointerEvent } from '@antv/g'; import { inRange, isEmpty, isNil, range } from 'lodash'; -import { DataCell } from '../cell'; +import { DataCell, type ColCell } from '../cell'; import { CellType, InteractionKeyboardKey, + InteractionName, InteractionStateName, InterceptType, S2Event, @@ -60,13 +61,6 @@ export class RangeSelection extends BaseEvent implements BaseEventImplement { } private bindColCellClick() { - if (this.spreadsheet.isTableMode()) { - // series-number click - this.spreadsheet.on(S2Event.ROW_CELL_CLICK, (event) => { - this.handleColClick(event); - }); - } - this.spreadsheet.on(S2Event.COL_CELL_CLICK, (event) => { this.handleColClick(event); }); @@ -75,7 +69,7 @@ export class RangeSelection extends BaseEvent implements BaseEventImplement { private bindDataCellClick() { this.spreadsheet.on(S2Event.DATA_CELL_CLICK, (event) => { event.stopPropagation(); - const cell = this.spreadsheet.getCell(event.target) as DataCell; + const cell = this.spreadsheet.getCell(event.target)!; const meta = cell.getMeta(); const { interaction } = this.spreadsheet; @@ -126,17 +120,17 @@ export class RangeSelection extends BaseEvent implements BaseEventImplement { event, getCellsTooltipData(this.spreadsheet), ); - this.spreadsheet.emit( - S2Event.GLOBAL_SELECTED, - interaction.getActiveCells(), - ); + interaction.emitSelectEvent({ + targetCell: cell, + interactionName: InteractionName.RANGE_SELECTION, + }); }); } private handleColClick = (event: FederatedPointerEvent) => { event.stopPropagation(); const { interaction, facet } = this.spreadsheet; - const cell = this.spreadsheet.getCell(event.target); + const cell = this.spreadsheet.getCell(event.target)!; const meta = cell?.getMeta() as Node; if (!isNil(meta?.x)) { @@ -184,31 +178,24 @@ export class RangeSelection extends BaseEvent implements BaseEventImplement { ); } - /* - * 兼容行列多选 - * Set the header cells (colCell or RowCell) selected information and update the dataCell state. - */ interaction.changeState({ cells: selectedCells, stateName: InteractionStateName.SELECTED, }); + const selectedCellIds = selectedCells.map(({ id }) => id); + + interaction.updateCells(facet.getHeaderCells(selectedCellIds)); + interaction.emitSelectEvent({ + targetCell: cell, + interactionName: InteractionName.RANGE_SELECTION, + }); } else { if (isEmpty(interaction.getCells())) { - interaction.removeIntercepts([InterceptType.HOVER]); + interaction.reset(); } this.spreadsheet.store.set('lastClickedCell', cell); } - - const selectedCellIds = selectedCells.map(({ id }) => id); - - // Update the interaction state of all the selected cells: header cells(colCell or RowCell) and dataCells belong to them. - interaction.updateCells(facet.getHeaderCells(selectedCellIds)); - - this.spreadsheet.emit( - S2Event.GLOBAL_SELECTED, - interaction.getActiveCells(), - ); } }; diff --git a/packages/s2-core/src/interaction/root.ts b/packages/s2-core/src/interaction/root.ts index 5d018fc7f5..0d8c6a62ba 100644 --- a/packages/s2-core/src/interaction/root.ts +++ b/packages/s2-core/src/interaction/root.ts @@ -22,6 +22,7 @@ import type { BrushSelectionOptions, CellMeta, CellScrollToOptions, + CellSelectedDetail, ChangeCellOptions, CustomInteraction, InteractionCellHighlightOptions, @@ -574,6 +575,7 @@ export class RootInteraction { const { cell, stateName = InteractionStateName.SELECTED, + interactionName, scrollIntoView = true, animate = true, skipScrollEvent = true, @@ -617,7 +619,10 @@ export class RootInteraction { if (isEmpty(selectedCells)) { this.reset(); - this.spreadsheet.emit(S2Event.GLOBAL_SELECTED, this.getActiveCells()); + this.emitSelectEvent({ + targetCell: cell, + interactionName, + }); return; } @@ -657,7 +662,10 @@ export class RootInteraction { // 由于绘制的顺序问题, 交互背景图层展示后, 会遮挡边框, 需要让边框展示在前面. this.spreadsheet.facet.centerFrame?.toFront(); - this.spreadsheet.emit(S2Event.GLOBAL_SELECTED, this.getActiveCells()); + this.emitSelectEvent({ + targetCell: cell, + interactionName, + }); return true; } @@ -1094,4 +1102,36 @@ export class RootInteraction { updateAllColHeaderCellState(colId, facet.getColCells(), stateName); } } + + public emitSelectEvent( + options: CellSelectedDetail & { cells?: S2CellType[] }, + ) { + const { interaction } = this.spreadsheet; + const { cells, ...defaultCellSelectedDetail } = options; + const activeCells = cells || interaction.getActiveCells(); + const targetCell = defaultCellSelectedDetail?.targetCell || activeCells[0]; + const cellSelectedDetail = { + ...defaultCellSelectedDetail, + targetCell, + }; + const cellType = targetCell?.cellType as string; + + const eventName = { + [CellType.CORNER_CELL]: S2Event.CORNER_CELL_SELECTED, + [CellType.ROW_CELL]: S2Event.ROW_CELL_SELECTED, + [CellType.COL_CELL]: S2Event.COL_CELL_SELECTED, + [CellType.DATA_CELL]: S2Event.DATA_CELL_SELECTED, + }[cellType]; + + if (!eventName) { + return; + } + + this.spreadsheet.emit(eventName, activeCells, cellSelectedDetail); + this.spreadsheet.emit( + S2Event.GLOBAL_SELECTED, + activeCells, + cellSelectedDetail, + ); + } } diff --git a/packages/s2-core/src/interaction/selected-cell-move.ts b/packages/s2-core/src/interaction/selected-cell-move.ts index 2c1acefbc6..c9d912737f 100644 --- a/packages/s2-core/src/interaction/selected-cell-move.ts +++ b/packages/s2-core/src/interaction/selected-cell-move.ts @@ -2,6 +2,8 @@ import type { FederatedPointerEvent as Event } from '@antv/g'; import { CellType, FrozenGroupArea, + InteractionName, + InteractionStateName, type CellMeta, type ViewMeta, } from '../common'; @@ -9,7 +11,7 @@ import { InteractionKeyboardKey, S2Event } from '../common/constant'; import type { FrozenFacet } from '../facet'; import type { SpreadSheet } from '../sheet-type'; import { getDataCellId } from '../utils'; -import { getRangeIndex, selectCells } from '../utils/interaction/select-event'; +import { getRangeIndex } from '../utils/interaction/select-event'; import { BaseEvent, type BaseEventImplement } from './base-interaction'; const SelectedCellMoveMap = [ @@ -82,6 +84,7 @@ export class SelectedCellMove extends BaseEvent implements BaseEventImplement { } }, ); + this.spreadsheet.on(S2Event.DATA_CELL_CLICK, (event: Event) => { const cell = this.spreadsheet.getCell(event.target); const cellMeta = cell?.getMeta() as ViewMeta; @@ -109,7 +112,7 @@ export class SelectedCellMove extends BaseEvent implements BaseEventImplement { isJumpMode, isSingleSelection, }: { - event: any; + event: KeyboardEvent; changeStartCell: boolean; isJumpMode: boolean; isSingleSelection: boolean; @@ -125,17 +128,25 @@ export class SelectedCellMove extends BaseEvent implements BaseEventImplement { const [rowIndex, colIndex] = [rowCol.row, rowCol.col]; this.scrollToActiveCell(spreadsheet, rowIndex, colIndex); + const movedCell = this.generateCellMeta(spreadsheet, rowIndex, colIndex); const selectedCells = isSingleSelection ? [movedCell] : this.getRangeCells(spreadsheet, startCell!, movedCell); - selectCells(spreadsheet, selectedCells); if (changeStartCell) { this.startCell = movedCell; } this.endCell = movedCell; + + spreadsheet.interaction.changeState({ + stateName: InteractionStateName.SELECTED, + cells: selectedCells, + }); + spreadsheet.interaction.emitSelectEvent({ + interactionName: InteractionName.SELECTED_CELL_MOVE, + }); this.spreadsheet.emit(S2Event.DATA_CELL_SELECT_MOVE, selectedCells); } diff --git a/packages/s2-core/src/utils/interaction/select-event.ts b/packages/s2-core/src/utils/interaction/select-event.ts index b88ab0f515..d88c50b3d4 100644 --- a/packages/s2-core/src/utils/interaction/select-event.ts +++ b/packages/s2-core/src/utils/interaction/select-event.ts @@ -1,11 +1,6 @@ import { reduce, uniqBy } from 'lodash'; import { HeaderCell, TableSeriesNumberCell } from '../../cell'; -import { - CellType, - InteractionKeyboardKey, - InteractionStateName, - S2Event, -} from '../../common/constant'; +import { CellType, InteractionKeyboardKey } from '../../common/constant'; import type { CellMeta, OnUpdateCells, @@ -45,15 +40,15 @@ export const getCellMeta = (cell: S2CellType): CellMeta => { }; }; -export const selectCells = (spreadsheet: SpreadSheet, cells: CellMeta[]) => { - const { interaction } = spreadsheet; +// export const selectCells = (spreadsheet: SpreadSheet, cells: CellMeta[]) => { +// const { interaction } = spreadsheet; - interaction.changeState({ - stateName: InteractionStateName.SELECTED, - cells, - }); - spreadsheet.emit(S2Event.GLOBAL_SELECTED, interaction.getActiveCells()); -}; +// interaction.changeState({ +// stateName: InteractionStateName.SELECTED, +// cells, +// }); +// spreadsheet.emit(S2Event.GLOBAL_SELECTED, interaction.getActiveCells()); +// }; export function getRangeIndex( start: T, diff --git a/packages/s2-react/__tests__/unit/hooks/useEvents-spec.ts b/packages/s2-react/__tests__/unit/hooks/useEvents-spec.ts index aba23cf42c..f79816bcc2 100644 --- a/packages/s2-react/__tests__/unit/hooks/useEvents-spec.ts +++ b/packages/s2-react/__tests__/unit/hooks/useEvents-spec.ts @@ -190,6 +190,10 @@ const cellEventCases = [ event: S2Event.ROW_CELL_RENDER, name: 'onRowCellRender', }, + { + event: S2Event.ROW_CELL_SELECTED, + name: 'onRowCellSelected', + }, // ============== Col Cell ==================== { @@ -228,6 +232,10 @@ const cellEventCases = [ event: S2Event.COL_CELL_RENDER, name: 'onColCellRender', }, + { + event: S2Event.COL_CELL_SELECTED, + name: 'onColCellSelected', + }, // ============== Data Cell ==================== { @@ -266,6 +274,10 @@ const cellEventCases = [ event: S2Event.DATA_CELL_RENDER, name: 'onDataCellRender', }, + { + event: S2Event.DATA_CELL_SELECTED, + name: 'onDataCellSelected', + }, // ============== Corner Cell ==================== { @@ -296,6 +308,10 @@ const cellEventCases = [ event: S2Event.CORNER_CELL_RENDER, name: 'onCornerCellRender', }, + { + event: S2Event.CORNER_CELL_SELECTED, + name: 'onCornerCellSelected', + }, // ============== Merged Cells ==================== { diff --git a/packages/s2-react/playground/index.tsx b/packages/s2-react/playground/index.tsx index a9d677d6eb..cd297d382d 100644 --- a/packages/s2-react/playground/index.tsx +++ b/packages/s2-react/playground/index.tsx @@ -1642,6 +1642,15 @@ function MainLayout() { onColCellHidden={logHandler('onColCellHidden')} onColCellExpanded={logHandler('onColCellExpanded')} onSelected={logHandler('onSelected')} + onCornerCellSelected={logHandler( + 'onCornerCellSelected', + )} + onRowCellSelected={logHandler('onRowCellSelected')} + onColCellSelected={logHandler('onColCellSelected')} + onDataCellSelected={logHandler('onDataCellSelected')} + onDataCellSelectMove={logHandler( + 'onDataCellSelectMove', + )} onScroll={logHandler('onScroll')} onRowCellScroll={logHandler('onRowCellScroll')} onLinkFieldJump={logHandler('onLinkFieldJump', () => { diff --git a/packages/s2-react/src/hooks/useEvents.ts b/packages/s2-react/src/hooks/useEvents.ts index 776e7afa5c..1469c68b4a 100644 --- a/packages/s2-react/src/hooks/useEvents.ts +++ b/packages/s2-react/src/hooks/useEvents.ts @@ -64,6 +64,7 @@ export function useEvents(props: SheetComponentProps, s2: SpreadSheet) { useS2Event(S2Event.ROW_CELL_COLLAPSED, props.onRowCellCollapsed, s2); useS2Event(S2Event.ROW_CELL_ALL_COLLAPSED, props.onRowCellAllCollapsed, s2); useS2Event(S2Event.ROW_CELL_RENDER, props.onRowCellRender, s2); + useS2Event(S2Event.ROW_CELL_SELECTED, props.onRowCellSelected, s2); // ============== Col Cell ==================== useCellEvent(S2Event.COL_CELL_HOVER, props.onColCellHover, s2); @@ -76,6 +77,7 @@ export function useEvents(props: SheetComponentProps, s2: SpreadSheet) { useS2Event(S2Event.COL_CELL_EXPANDED, props.onColCellExpanded, s2); useS2Event(S2Event.COL_CELL_HIDDEN, props.onColCellHidden, s2); useS2Event(S2Event.COL_CELL_RENDER, props.onColCellRender, s2); + useS2Event(S2Event.COL_CELL_SELECTED, props.onColCellSelected, s2); // ============== Data Cell ==================== useCellEvent(S2Event.DATA_CELL_HOVER, props.onDataCellHover, s2); @@ -92,6 +94,7 @@ export function useEvents(props: SheetComponentProps, s2: SpreadSheet) { ); useS2Event(S2Event.DATA_CELL_SELECT_MOVE, props.onDataCellSelectMove, s2); useS2Event(S2Event.DATA_CELL_RENDER, props.onDataCellRender, s2); + useS2Event(S2Event.DATA_CELL_SELECTED, props.onDataCellSelected, s2); // ============== Corner Cell ==================== useCellEvent(S2Event.CORNER_CELL_HOVER, props.onCornerCellHover, s2); @@ -110,6 +113,7 @@ export function useEvents(props: SheetComponentProps, s2: SpreadSheet) { useCellEvent(S2Event.CORNER_CELL_MOUSE_UP, props.onCornerCellMouseUp, s2); useCellEvent(S2Event.CORNER_CELL_MOUSE_MOVE, props.onCornerCellMouseMove, s2); useS2Event(S2Event.CORNER_CELL_RENDER, props.onCornerCellRender, s2); + useS2Event(S2Event.CORNER_CELL_SELECTED, props.onCornerCellSelected, s2); // ============== Merged Cells ==================== useCellEvent(S2Event.MERGED_CELLS_HOVER, props.onMergedCellsHover, s2); diff --git a/packages/s2-shared/src/interface.ts b/packages/s2-shared/src/interface.ts index 6e7d5c4fd2..89a9d57527 100644 --- a/packages/s2-shared/src/interface.ts +++ b/packages/s2-shared/src/interface.ts @@ -1,6 +1,7 @@ import type { BaseTooltipOperatorMenuOptions, CellScrollPosition, + CellSelectedHandler, ColCell, CopyableList, CornerCell, @@ -15,6 +16,7 @@ import type { RawData, ResizeInfo, ResizeParams, + RowCell, RowCellCollapsedParams, S2CellType, S2DataConfig, @@ -107,7 +109,8 @@ export interface BaseSheetComponentProps< onRowCellCollapsed?: (params: RowCellCollapsedParams) => void; onRowCellAllCollapsed?: (isCollapsed: boolean) => void; onRowCellScroll?: (position: CellScrollPosition) => void; - onRowCellRender?: (cell: ColCell) => void; + onRowCellRender?: (cell: RowCell) => void; + onRowCellSelected?: CellSelectedHandler; // ============== Col Cell ==================== onColCellHover?: (data: TargetCellInfo) => void; @@ -123,6 +126,7 @@ export interface BaseSheetComponentProps< hiddenColumnsDetail: HiddenColumnsInfo[]; }) => void; onColCellRender?: (cell: ColCell) => void; + onColCellSelected?: CellSelectedHandler; // ============== Data Cell ==================== onDataCellHover?: (data: TargetCellInfo) => void; @@ -137,6 +141,7 @@ export interface BaseSheetComponentProps< onDataCellRender?: (cell: DataCell) => void; onDataCellEditStart?: (meta: ViewMeta, cell: TableDataCell) => void; onDataCellEditEnd?: (meta: ViewMeta, cell: TableDataCell) => void; + onDataCellSelected?: CellSelectedHandler; // ============== Corner Cell ==================== onCornerCellHover?: (data: TargetCellInfo) => void; @@ -147,6 +152,7 @@ export interface BaseSheetComponentProps< onCornerCellMouseUp?: (data: TargetCellInfo) => void; onCornerCellMouseMove?: (data: TargetCellInfo) => void; onCornerCellRender?: (cell: CornerCell) => void; + onCornerCellSelected?: CellSelectedHandler; // ============== Merged Cells ==================== onMergedCellsHover?: (data: TargetCellInfo) => void; @@ -219,7 +225,7 @@ export interface BaseSheetComponentProps< onMouseUp?: (event: MouseEvent) => void; onMouseDown?: (event: MouseEvent) => void; onMouseMove?: (event: MouseEvent) => void; - onSelected?: (cells: S2CellType[]) => void; + onSelected?: CellSelectedHandler; onReset?: (event: KeyboardEvent) => void; onLinkFieldJump?: (data: { field: string; record: RawData }) => void; onScroll?: (position: CellScrollPosition) => void; diff --git a/packages/s2-vue/src/hooks/useEvents.ts b/packages/s2-vue/src/hooks/useEvents.ts index 586d237bd5..8821559596 100644 --- a/packages/s2-vue/src/hooks/useEvents.ts +++ b/packages/s2-vue/src/hooks/useEvents.ts @@ -24,8 +24,9 @@ const useS2Event = ( eventName: S2Event, emitName: keyof BaseSheetInitEmits, ) => { - const handler = (params: any) => { - emit(emitName as any, params); + const handler = (...params: any[]) => { + // @ts-ignore + emit(emitName, ...params); }; s2Ref.value?.on(eventName, handler); @@ -66,6 +67,8 @@ export const useEvents = ( 'rowCellAllCollapsed', ); useS2Event(s2Ref, emit, S2Event.ROW_CELL_SCROLL, 'rowCellScroll'); + useS2Event(s2Ref, emit, S2Event.ROW_CELL_RENDER, 'rowCellRender'); + useS2Event(s2Ref, emit, S2Event.ROW_CELL_SELECTED, 'rowCellSelected'); // ============== Col Cell ==================== useCellEvent(s2Ref, emit, S2Event.COL_CELL_HOVER, 'colCellHover'); @@ -87,6 +90,8 @@ export const useEvents = ( useCellEvent(s2Ref, emit, S2Event.COL_CELL_MOUSE_MOVE, 'colCellMouseMove'); useS2Event(s2Ref, emit, S2Event.COL_CELL_EXPANDED, 'colCellExpanded'); useS2Event(s2Ref, emit, S2Event.COL_CELL_HIDDEN, 'colCellHidden'); + useS2Event(s2Ref, emit, S2Event.COL_CELL_RENDER, 'colCellRender'); + useS2Event(s2Ref, emit, S2Event.COL_CELL_SELECTED, 'colCellSelected'); // ============== Data Cell ==================== useCellEvent(s2Ref, emit, S2Event.DATA_CELL_HOVER, 'dataCellHover'); @@ -128,6 +133,8 @@ export const useEvents = ( S2Event.DATA_CELL_SELECT_MOVE, 'dataCellSelectMove', ); + useS2Event(s2Ref, emit, S2Event.DATA_CELL_RENDER, 'dataCellRender'); + useS2Event(s2Ref, emit, S2Event.DATA_CELL_SELECTED, 'dataCellSelected'); // ============== Corner Cell ==================== useCellEvent(s2Ref, emit, S2Event.CORNER_CELL_HOVER, 'cornerCellHover'); @@ -162,6 +169,8 @@ export const useEvents = ( S2Event.CORNER_CELL_MOUSE_MOVE, 'cornerCellMouseMove', ); + useS2Event(s2Ref, emit, S2Event.CORNER_CELL_RENDER, 'cornerCellRender'); + useS2Event(s2Ref, emit, S2Event.CORNER_CELL_SELECTED, 'cornerCellSelected'); // ============== Merged Cells ==================== useCellEvent(s2Ref, emit, S2Event.MERGED_CELLS_HOVER, 'mergedCellsHover'); @@ -196,6 +205,15 @@ export const useEvents = ( S2Event.MERGED_CELLS_MOUSE_MOVE, 'mergedCellsMouseMove', ); + useS2Event(s2Ref, emit, S2Event.MERGED_CELLS_RENDER, 'mergedCellsRender'); + + /** ================ SeriesNumber Cell ================ */ + useS2Event( + s2Ref, + emit, + S2Event.SERIES_NUMBER_CELL_RENDER, + 'seriesNumberCellRender', + ); // ============== Sort ==================== useS2Event(s2Ref, emit, S2Event.RANGE_SORT, 'rangeSort'); diff --git a/s2-site/docs/api/basic-class/interaction.zh.md b/s2-site/docs/api/basic-class/interaction.zh.md index a1c1e8dca8..82b4bd1c47 100644 --- a/s2-site/docs/api/basic-class/interaction.zh.md +++ b/s2-site/docs/api/basic-class/interaction.zh.md @@ -166,20 +166,6 @@ export abstract class BaseEvent { } ``` -### InterceptType - -```ts -enum InterceptType { - HOVER = 'hover', - CLICK = 'click', - DATA_CELL_BRUSH_SELECTION = 'dataCellBrushSelection', - ROW_CELL_BRUSH_SELECTION = 'rowCellBrushSelection', - COL_CELL_BRUSH_SELECTION = 'colCellBrushSelection', - MULTI_SELECTION = 'multiSelection', - RESIZE = 'resize', -} -``` - ### S2CellType ```ts @@ -216,6 +202,11 @@ interface ChangeCellOptions { */ stateName?: InteractionStateName; + /** + * 交互名 + */ + interactionName?: `${InteractionName}`; + /** * 如果单元格不在可视范围,是否自动滚动 */ @@ -233,19 +224,6 @@ interface MergedCellInfo { } ``` -### CellType - -```ts -enum CellType { - DATA_CELL = 'dataCell', - ROW_CELL = 'rowCell', - COL_CELL = 'colCell', - SERIES_NUMBER_CELL = 'seriesNumberCell', - CORNER_CELL = 'cornerCell', - MERGED_CELL = 'mergedCell', -} -``` - ### CellMeta ```ts @@ -259,24 +237,6 @@ interface CellMeta { } ``` -### InteractionStateName - -```ts -enum InteractionStateName { - ALL_SELECTED = 'allSelected', - SELECTED = 'selected', - ROW_CELL_BRUSH_SELECTED = 'rowCellBrushSelected', - COL_CELL_BRUSH_SELECTED = 'colCellBrushSelected', - DATA_CELL_BRUSH_SELECTED = 'dataCellBrushSelected', - UNSELECTED = 'unselected', - HOVER = 'hover', - HOVER_FOCUS = 'hoverFocus', - HIGHLIGHT = 'highlight', - SEARCH_RESULT = 'searchResult', - PREPARE_SELECT = 'prepareSelect', -} -``` - ### InteractionStateInfo ```ts diff --git a/s2-site/docs/api/components/sheet-component.zh.md b/s2-site/docs/api/components/sheet-component.zh.md index c502f572d6..5a236bd93a 100644 --- a/s2-site/docs/api/components/sheet-component.zh.md +++ b/s2-site/docs/api/components/sheet-component.zh.md @@ -35,6 +35,8 @@ tag: Updated | onRowCellCollapsed | 节点展开/收起事件回调 | ({ isCollapsed: `boolean`, collapseFields: `Record`, node: [Node](/docs/api/basic-class/node) }) => void; | | | | onRowCellAllCollapsed | 节点全部展开/收起的事件回调 | (isCollapsed: boolean ) => void; | | | | onRowCellScroll | 行头单元格滚动事件 | ({position: [CellScrollPosition](#cellscrollposition)} ) => void; | | | +| onRowCellRender | 行头单元格渲染事件 | ( cell: [Cell](/docs/api/basic-class/base-cell) ) => void | | | +| onRowCellSelected | 行头单元格选中事件 | ( cells: [Cell](/docs/api/basic-class/base-cell)[], detail: [CellSelectedDetail](#cellselecteddetail) ) => void | | | | onColCellHover | 列头鼠标悬停事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | onColCellClick | 列头鼠标单击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | onColCellDoubleClick | 列头鼠标双击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | @@ -44,6 +46,8 @@ tag: Updated | onColCellMouseMove | 列头鼠标移动事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | onColCellExpanded | 开启隐藏列头(tooltip.operation.hiddenColumns = true)后,列头展开的事件回调 | (expandedNode: [Node](/docs/api/basic-class/node)) => void; | | | | onColCellHidden | 开启隐藏列头(tooltip.operation.hiddenColumns = true)后,列头隐藏的事件回调 | ( data: { currentHiddenColumnsInfo:[HiddenColumnsInfo](#hiddencolumnsinfo); hiddenColumnsDetail:[HiddenColumnsInfo](#hiddencolumnsinfo)[]} ) => void; | | | +| onColCellRender | 列头单元格渲染事件 | ( cell: [Cell](/docs/api/basic-class/base-cell) ) => void | | | +| onColCellSelected | 列头单元格选中事件 | ( cells: [Cell](/docs/api/basic-class/base-cell)[], detail: [CellSelectedDetail](#cellselecteddetail) ) => void | | | | onDataCellHover | 数值单元格鼠标悬停事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | onDataCellClick | 数值单元格鼠标点击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | onDataCellDoubleClick | 数值单元格双击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | @@ -55,6 +59,8 @@ tag: Updated | onDataCellSelectMove | 数值单元格键盘方向键移动事件 | (metas: CellMeta[]) => void | | | | onDataCellEditStart | 数值单元格编辑开始(暂只支持编辑表) | (meta: [ViewMeta](/docs/api/basic-class/node), cell: [S2CellType](/docs/api/basic-class/base-cell)) => void | | | | onDataCellEditEnd | 数值单元格编辑完成(暂只支持编辑表) | (meta: [ViewMeta](/docs/api/basic-class/node), cell: [S2CellType](/docs/api/basic-class/base-cell)) => void | | | +| onDataCellRender | 数值单元格渲染事件 | ( cell: [Cell](/docs/api/basic-class/base-cell) ) => void | | | +| onDataCellSelected | 数值单元格选中事件 | ( cells: [Cell](/docs/api/basic-class/base-cell)[], detail: [CellSelectedDetail](#cellselecteddetail) ) => void | | | | onCornerCellHover | 角头鼠标悬停事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | onCornerCellClick | 角头鼠标单击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | onCornerCellDoubleClick | 角头鼠标双击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | @@ -62,6 +68,8 @@ tag: Updated | onCornerCellMouseUp | 角头鼠标按下事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | onCornerCellMouseUp | 角头鼠标松开事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | onCornerCellMouseMove | 角头鼠标移动事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | +| onCornerCellRender | 角头单元格渲染事件 | ( cell: [Cell](/docs/api/basic-class/base-cell) ) => void | | | +| onCornerCellSelected | 角头单元格选中事件 | ( cells: [Cell](/docs/api/basic-class/base-cell)[], detail: [CellSelectedDetail](#cellselecteddetail) ) => void | | | | onMergedCellsHover | 合并单元格鼠标悬停事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | onMergedCellsClick | 合并单元格鼠标点击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | onMergedCellsDoubleClick | 合并单元格鼠标双击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | @@ -69,6 +77,8 @@ tag: Updated | onMergedCellsMouseDown | 合并单元格按下事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | onMergedCellsMouseUp | 合并单元格松开事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | onMergedCellsMouseMove | 合并单元格移动事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | +| onMergedCellsRender | 合并单元格渲染事件 | ( cell: [Cell](/docs/api/basic-class/base-cell) ) => void | | | +| onSeriesNumberCellRender | 序号单元格渲染事件 | ( cell: [Cell](/docs/api/basic-class/base-cell) ) => void | | | | onRangeSort | 组内排序时触发回调事件(暂只支持透视表) | (params: [SortParam[]](#sortparam) ) => void; | | | | onRangeSorted | 组内排序结束触发回调事件(暂只支持透视表) | (event: [FederatedPointerEvent](https://g.antv.antgroup.com/api/event/event-object) ) => void; | | | | onRangeFilter | 筛选时触发回调事件 | (data: { filterKey: string; filteredValues: string[] } ) => void; | | | @@ -102,7 +112,7 @@ tag: Updated | onContextMenu | 右键单元格单击事件 ([禁用右键菜单不生效?](/manual/faq#%E7%A6%81%E7%94%A8%E5%8F%B3%E9%94%AE%E8%8F%9C%E5%8D%95%E4%B8%8D%E7%94%9F%E6%95%88)) | (event: [FederatedPointerEvent](https://g.antv.antgroup.com/api/event/event-object)) => void | | | | onMouseHover | 表格鼠标悬停事件 | (event: [FederatedPointerEvent](https://g.antv.antgroup.com/api/event/event-object)) => void | | | | onMouseUp | 表格鼠标松开事件 | (event: [FederatedPointerEvent](https://g.antv.antgroup.com/api/event/event-object)) => void | | | -| onSelected | 单元格选中事件 | (cells: [Cell](/docs/api/basic-class/base-cell)[] ) => void | | | +| onSelected | 单元格选中事件 | (cells: [Cell](/docs/api/basic-class/base-cell)[], detail: [CellSelectedDetail](#cellselecteddetail) ) => void | | | | onReset | 交互状态重置事件 | (event: KeyboardEvent) => void | | | | onLinkFieldJump | 链接字段跳转事件 | (data: { field: string; meta: [Node](/docs/api/basic-class/node) \| [ViewMeta](#viewmeta); record: [Data](/docs/api/general/S2DataConfig#data) }) => void | | | | onScroll | 单元格滚动事件 (含行头和数值单元格) | ({position: [CellScrollPosition](#cellscrollposition)} ) => void | | | @@ -170,6 +180,8 @@ type SheetComponentOptions = S2Options< | rowCellScroll | 行头单元格滚动事件 | ({position: [CellScrollPosition](#cellscrollposition)} ) => void; | | | | rowCellCollapsed | 节点展开/收起事件回调 | ({ isCollapsed: `boolean`, collapseFields: `Record`, node: [Node](/docs/api/basic-class/node) }) => void; | | | | rowCellAllCollapsed | 节点全部展开/收起的事件回调 | (isCollapsed: boolean ) => void; | | | +| rowCellRender | 行头单元格渲染事件 | ( cell: [Cell](/docs/api/basic-class/base-cell) ) => void | | | +| rowCellSelected | 行头单元格选中事件 | ( cells: [Cell](/docs/api/basic-class/base-cell)[], detail: [CellSelectedDetail](#cellselecteddetail) ) => void | | | | colCellHover | 列头鼠标悬停事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | colCellClick | 列头鼠标单击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | colCellDoubleClick | 列头鼠标双击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | @@ -179,6 +191,8 @@ type SheetComponentOptions = S2Options< | colCellMouseMove | 列头鼠标移动事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | colCellExpanded | 开启隐藏列头(tooltip.operation.hiddenColumns = true)后,列头展开的事件回调 | (expandedNode: [Node](/docs/api/basic-class/node)) => void | | | | colCellHidden | 开启隐藏列头(tooltip.operation.hiddenColumns = true)后,列头隐藏的事件回调 | (data: { currentHiddenColumnsInfo:[HiddenColumnsInfo](#hiddencolumnsinfo); hiddenColumnsDetail:[HiddenColumnsInfo](#hiddencolumnsinfo)[] } ) => void; | | | +| colCellRender | 列头单元格渲染事件 | ( cell: [Cell](/docs/api/basic-class/base-cell) ) => void | | | +| colCellSelected | 列头单元格选中事件 | ( cells: [Cell](/docs/api/basic-class/base-cell)[], detail: [CellSelectedDetail](#cellselecteddetail) ) => void | | | | dataCellHover | 数值单元格鼠标悬停事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | dataCellClick | 数值单元格鼠标点击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | dataCellDoubleClick | 数值单元格双击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | @@ -188,6 +202,7 @@ type SheetComponentOptions = S2Options< | dataCellMouseMove | 数值单元格鼠标移动事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | dataCellBrushSelection | 数值单元格刷选事件 | (brushRangeDataCells: [DataCell](/docs/api/basic-class/base-cell)[] ) => void | | | | dataCellScroll | 数值单元格滚动事件 | ({position: [CellScrollPosition](#cellscrollposition)} ) => void; | | | +| dataCellSelected | 数值单元格选中事件 | ( cells: [Cell](/docs/api/basic-class/base-cell)[], detail: [CellSelectedDetail](#cellselecteddetail) ) => void | | | | cornerCellHover | 角头鼠标悬停事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | cornerCellClick | 角头鼠标单击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | cornerCellDoubleClick | 角头鼠标双击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | @@ -195,6 +210,8 @@ type SheetComponentOptions = S2Options< | cornerCellMouseUp | 角头鼠标按下事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | cornerCellMouseUp | 角头鼠标松开事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | cornerCellMouseMove | 角头鼠标移动事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | +| cornerCellRender | 角头单元格渲染事件 | ( cell: [Cell](/docs/api/basic-class/base-cell) ) => void | | | +| cornerCellSelected | 角头单元格选中事件 | ( cells: [Cell](/docs/api/basic-class/base-cell)[], detail: [CellSelectedDetail](#cellselecteddetail) ) => void | | | | mergedCellsHover | 合并单元格鼠标悬停事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | mergedCellsClick | 合并单元格鼠标点击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | mergedCellsDoubleClick | 合并单元格鼠标双击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | @@ -202,6 +219,8 @@ type SheetComponentOptions = S2Options< | mergedCellsMouseDown | 合并单元格按下事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | mergedCellsMouseUp | 合并单元格松开事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | | mergedCellsMouseMove | 合并单元格移动事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | | +| mergedCellsRender | 合并单元格渲染事件 | ( cell: [Cell](/docs/api/basic-class/base-cell) ) => void | | | +| seriesNumberCellRender | 序号单元格渲染事件 | ( cell: [Cell](/docs/api/basic-class/base-cell) ) => void | | | | rangeSort | 组内排序时触发回调事件(暂只支持透视表) | (params: [SortParam[]](#sortparam) ) => void; | | | | rangeSorted | 组内排序结束触发回调事件(暂只支持透视表) | (event: [FederatedPointerEvent](https://g.antv.antgroup.com/api/event/event-object) ) => void; | | | | rangeFilter | 筛选时触发回调事件 | (data: { filterKey: string; filteredValues: string[] } ) => void; | | | @@ -233,7 +252,7 @@ type SheetComponentOptions = S2Options< | contextMenu | 右键单元格单击事件 ([禁用右键菜单不生效?](/manual/faq#%E7%A6%81%E7%94%A8%E5%8F%B3%E9%94%AE%E8%8F%9C%E5%8D%95%E4%B8%8D%E7%94%9F%E6%95%88)) | (event: [FederatedPointerEvent](https://g.antv.antgroup.com/api/event/event-object)) => void | | | | mouseHover | 表格鼠标悬停事件 | (event: [FederatedPointerEvent](https://g.antv.antgroup.com/api/event/event-object)) => void | | | | mouseUp | 表格鼠标松开事件 | (event: [FederatedPointerEvent](https://g.antv.antgroup.com/api/event/event-object)) => void | | | -| selected | 单元格选中事件 | ( cells: [Cell](/docs/api/basic-class/base-cell)[] ) => void | | | +| selected | 单元格选中事件 | (cells: [Cell](/docs/api/basic-class/base-cell)[], detail: [CellSelectedDetail](#cellselecteddetail) ) => void | | | | reset | 交互状态重置事件 | (event: KeyboardEvent) => void | | | | linkFieldJump | 链接字段跳转事件 | (data: { field: string; meta: [Node](/docs/api/basic-class/node) \| [ViewMeta](#viewmeta); record: [Data](/docs/api/general/S2DataConfig#data) }) => void | | | | scroll | 单元格滚动事件 (含行头和数值单元格) | ({position: [CellScrollPosition](#cellscrollposition)} ) => void; | | | @@ -338,3 +357,4 @@ type SheetComponentOptions = S2Options< | reBuildHiddenColumnsDetail | 是否重新生成列头隐藏信息 | `boolean` | | | + diff --git a/s2-site/docs/api/general/S2Event.zh.md b/s2-site/docs/api/general/S2Event.zh.md index bbfac830c1..29edfc6a00 100644 --- a/s2-site/docs/api/general/S2Event.zh.md +++ b/s2-site/docs/api/general/S2Event.zh.md @@ -40,6 +40,7 @@ s2.on(S2Event.ROW_CELL_CLICK, (event) => { | 滚动 | `S2Event.ROW_CELL_SCROLL` | 行头单元格滚动 | | 行头刷选 | `S2Event.ROW_CELL_BRUSH_SELECTION` | 批量选中刷选范围内的行头单元格,刷选过程中,显示刷选范围提示蒙层,刷选完成后,弹出 tooltip, 展示被刷选单元格信息(仅支持透视表) | | 单元格渲染 | `S2Event.ROW_CELL_RENDER` | 行头单元格布局渲染完成事件 | +| 单元格选中 | `S2Event.ROW_CELL_SELECTED` | 行头单元格选中,可以获取到选中的单元格,交互名,和触发单元格等信息 | ### 列头单元格 (ColCell) @@ -54,6 +55,7 @@ s2.on(S2Event.ROW_CELL_CLICK, (event) => { | 鼠标松开 | `S2Event.COL_CELL_MOUSE_UP` | 列头单元格鼠标松开 | | 列头刷选 | `S2Event.COL_CELL_BRUSH_SELECTION` | 批量选中刷选范围内的列头单元格,刷选过程中,显示刷选范围提示蒙层,刷选完成后,弹出 tooltip, 展示被刷选单元格信息(仅支持透视表) | | 单元格渲染 | `S2Event.COL_CELL_RENDER` | 列头单元格布局渲染完成事件 | +| 单元格选中 | `S2Event.COL_CELL_SELECTED` | 列头单元格选中,可以获取到选中的单元格,交互名,和触发单元格等信息 | ### 数值单元格 (DataCell) @@ -69,6 +71,7 @@ s2.on(S2Event.ROW_CELL_CLICK, (event) => { | 刷选 | `S2Event.DATA_CELL_BRUSH_SELECTION` | 数值单元格刷选 | | 键盘方向键移动 | `S2Event.DATA_CELL_SELECT_MOVE` | 数值单元格键盘方向键移动 | | 单元格渲染 | `S2Event.DATA_CELL_RENDER` | 数值单元格布局渲染完成事件 | +| 单元格选中 | `S2Event.DATA_CELL_SELECTED` | 数值单元格选中,可以获取到选中的单元格,交互名,和触发单元格等信息 | ### 角头单元格 (CornerCell) @@ -82,6 +85,7 @@ s2.on(S2Event.ROW_CELL_CLICK, (event) => { | 鼠标移动 | `S2Event.CORNER_CELL_MOUSE_MOVE` | 角头单元格鼠标移动 | | 鼠标松开 | `S2Event.CORNER_CELL_MOUSE_UP` | 角头单元格鼠标松开 | | 单元格渲染 | `S2Event.CORNER_CELL_RENDER` | 角头单元格布局渲染完成事件 | +| 单元格选中 | `S2Event.CORNER_CELL_SELECTED` | 角头单元格选中,可以获取到选中的单元格,交互名,和触发单元格等信息 | ### 合并单元格 (MergedCells) @@ -141,7 +145,7 @@ s2.on(S2Event.ROW_CELL_CLICK, (event) => { | 鼠标松开 | `S2Event.GLOBAL_MOUSE_UP` | 图表区域鼠标松开 | | 点击 | `S2Event.GLOBAL_CLICK` | 图表区域点击 | | 右键 | `S2Event.GLOBAL_CONTEXT_MENU` | 图表区域按下右键 ([禁用右键菜单不生效?](/manual/faq#%E7%A6%81%E7%94%A8%E5%8F%B3%E9%94%AE%E8%8F%9C%E5%8D%95%E4%B8%8D%E7%94%9F%E6%95%88)) | -| 选中 | `S2Event.GLOBAL_SELECTED` | 选中单元格时,如:刷选,多选,单选 | +| 选中 | `S2Event.GLOBAL_SELECTED` | 选中单元格时,如:刷选,多选,单选 (可以获取到选中的单元格,交互名,和触发单元格等信息) | | 悬停 | `S2Event.GLOBAL_HOVER` | 鼠标悬停在单元格 | | 重置 | `S2Event.GLOBAL_RESET` | 点击空白处,按下 Esc 键 重置交互样式时 | | 链接跳转 | `S2Event.GLOBAL_LINK_FIELD_JUMP` | 点击(行头/列头/数值)为链接字段的文本时 | diff --git a/s2-site/docs/common/interaction.zh.md b/s2-site/docs/common/interaction.zh.md index 209fbac516..3c0d2dd2f3 100644 --- a/s2-site/docs/common/interaction.zh.md +++ b/s2-site/docs/common/interaction.zh.md @@ -75,7 +75,7 @@ interface ScrollSpeedRatio { | minCellWidth | 单元格可拖拽最小宽度 | `number`| 20 | | | minCellHeight | 单元格可拖拽最小高度 | `number` | 20 | | -### brushSelection +### BrushSelection 功能描述:单元格刷选配置。[查看示例](/examples/interaction/basic/#brush-selection) @@ -84,3 +84,90 @@ interface ScrollSpeedRatio { | dataCell | 是否允许数值单元格刷选 | `boolean` | true | | | rowCell | 是否允许行头单元格刷选(仅支持透视表) | `boolean` | false | | | colCell | 是否允许列头单元格刷选 | `boolean` | false | | + +### CellSelectedDetail + +功能描述:单元格选中信息明细。 + +| 参数 | 说明 | 类型 | 默认值 | 必选 | +| -- | -- | -- | -- | --- | +| interactionName | 触发选中的交互名 | [InteractionName](#interactionname) | | | +| targetCell | 触发选中的单元格 | [S2CellType](/docs/api/basic-class/base-cell) | | | + +### InterceptType + +功能描述:交互拦截类型。 + +```ts +enum InterceptType { + HOVER = 'hover', + CLICK = 'click', + DATA_CELL_BRUSH_SELECTION = 'dataCellBrushSelection', + ROW_CELL_BRUSH_SELECTION = 'rowCellBrushSelection', + COL_CELL_BRUSH_SELECTION = 'colCellBrushSelection', + MULTI_SELECTION = 'multiSelection', + RESIZE = 'resize', +} +``` + +### InteractionName + +功能描述:交互名称。 + +```ts +enum InteractionName { + CORNER_CELL_CLICK = 'cornerCellClick', + DATA_CELL_CLICK = 'dataCellClick', + ROW_CELL_CLICK = 'rowCellClick', + COL_CELL_CLICK = 'colCellClick', + MERGED_CELLS_CLICK = 'mergedCellsClick', + ROW_COLUMN_CLICK = 'rowColumnClick', + HEADER_CELL_LINK_CLICK = 'headerCellLinkClick', + HOVER = 'hover', + DATA_CELL_BRUSH_SELECTION = 'dataCellBrushSelection', + ROW_CELL_BRUSH_SELECTION = 'rowCellBrushSelection', + COL_CELL_BRUSH_SELECTION = 'colCellBrushSelection', + COL_ROW_RESIZE = 'rowColResize', + DATA_CELL_MULTI_SELECTION = 'dataCellMultiSelection', + ROW_CELL_MULTI_SELECTION = 'rowCellMultiSelection', + COL_CELL_MULTI_SELECTION = 'colCellMultiSelection', + RANGE_SELECTION = 'rangeSelection', + SELECTED_CELL_MOVE = 'selectedCellMove', + GLOBAL_RESET = 'globalReset', +} +``` + +### InteractionStateName + +功能描述:交互状态名称。 + +```ts +enum InteractionStateName { + ALL_SELECTED = 'allSelected', + SELECTED = 'selected', + ROW_CELL_BRUSH_SELECTED = 'rowCellBrushSelected', + COL_CELL_BRUSH_SELECTED = 'colCellBrushSelected', + DATA_CELL_BRUSH_SELECTED = 'dataCellBrushSelected', + UNSELECTED = 'unselected', + HOVER = 'hover', + HOVER_FOCUS = 'hoverFocus', + HIGHLIGHT = 'highlight', + SEARCH_RESULT = 'searchResult', + PREPARE_SELECT = 'prepareSelect', +} +``` + +### CellType + +功能描述:单元格类型。 + +```ts +enum CellType { + DATA_CELL = 'dataCell', + ROW_CELL = 'rowCell', + COL_CELL = 'colCell', + SERIES_NUMBER_CELL = 'seriesNumberCell', + CORNER_CELL = 'cornerCell', + MERGED_CELL = 'mergedCell', +} +``` diff --git a/s2-site/examples/analysis/get-data/demo/get-cell-data.ts b/s2-site/examples/analysis/get-data/demo/get-cell-data.ts index dbbaa7ea54..181b98c4fb 100644 --- a/s2-site/examples/analysis/get-data/demo/get-cell-data.ts +++ b/s2-site/examples/analysis/get-data/demo/get-cell-data.ts @@ -102,8 +102,8 @@ function logEvent(s2: SpreadSheet) { console.log('当前数值单元格信息:', cell, meta); }); - s2.on(S2Event.GLOBAL_SELECTED, (cells) => { - console.log('选中的单元格', cells); + s2.on(S2Event.GLOBAL_SELECTED, (cells, detail) => { + console.log('选中的单元格', cells, detail); }); } diff --git a/s2-site/examples/interaction/basic/demo/brush-header.ts b/s2-site/examples/interaction/basic/demo/brush-header.ts index 473bfa8948..786ade73aa 100644 --- a/s2-site/examples/interaction/basic/demo/brush-header.ts +++ b/s2-site/examples/interaction/basic/demo/brush-header.ts @@ -42,8 +42,8 @@ fetch( }); // 也可以监听全局的选中事件 - s2.on(S2Event.GLOBAL_SELECTED, (cells) => { - console.log('selected', cells); + s2.on(S2Event.GLOBAL_SELECTED, (cells, detail) => { + console.log('selected', cells, detail); }); await s2.render(); diff --git a/s2-site/examples/interaction/basic/demo/corner-cell-click-selection.ts b/s2-site/examples/interaction/basic/demo/corner-cell-click-selection.ts index c270f79ac4..aad7b6ab98 100644 --- a/s2-site/examples/interaction/basic/demo/corner-cell-click-selection.ts +++ b/s2-site/examples/interaction/basic/demo/corner-cell-click-selection.ts @@ -30,8 +30,12 @@ fetch( console.log('corner cell click:', event); }); - s2.on(S2Event.GLOBAL_SELECTED, (cells) => { - console.log('selected', cells); + s2.on(S2Event.CORNER_CELL_SELECTED, (cells, detail) => { + console.log('corner cell selected:', cells, detail); + }); + + s2.on(S2Event.GLOBAL_SELECTED, (cells, detail) => { + console.log('selected', cells, detail); }); await s2.render(); diff --git a/s2-site/examples/interaction/basic/demo/data-cell-click-selection.ts b/s2-site/examples/interaction/basic/demo/data-cell-click-selection.ts index aab22d9ed4..ba08c3e9c3 100644 --- a/s2-site/examples/interaction/basic/demo/data-cell-click-selection.ts +++ b/s2-site/examples/interaction/basic/demo/data-cell-click-selection.ts @@ -21,8 +21,16 @@ fetch( const s2 = new PivotSheet(container, dataCfg, s2Options); - s2.on(S2Event.GLOBAL_SELECTED, (cells) => { - console.log('selected', cells); + s2.on(S2Event.DATA_CELL_CLICK, (event) => { + console.log('data cell click:', event); + }); + + s2.on(S2Event.DATA_CELL_SELECTED, (cells, detail) => { + console.log('data cell selected:', cells, detail); + }); + + s2.on(S2Event.GLOBAL_SELECTED, (cells, detail) => { + console.log('selected', cells, detail); }); await s2.render(); diff --git a/s2-site/examples/interaction/basic/demo/data-cell-range-selection.ts b/s2-site/examples/interaction/basic/demo/data-cell-range-selection.ts index ed38d95876..e83dbbe9c1 100644 --- a/s2-site/examples/interaction/basic/demo/data-cell-range-selection.ts +++ b/s2-site/examples/interaction/basic/demo/data-cell-range-selection.ts @@ -21,9 +21,13 @@ fetch( const s2 = new PivotSheet(container, dataCfg, s2Options); + s2.on(S2Event.DATA_CELL_CLICK, (event) => { + console.log('data cell click:', event); + }); + // 也可以监听全局的选中事件 - s2.on(S2Event.GLOBAL_SELECTED, (cells) => { - console.log('selected', cells); + s2.on(S2Event.GLOBAL_SELECTED, (cells, detail) => { + console.log('selected', cells, detail); }); await s2.render(); diff --git a/s2-site/examples/interaction/basic/demo/event.ts b/s2-site/examples/interaction/basic/demo/event.ts index 98fb3dfd88..ad3c7b7812 100644 --- a/s2-site/examples/interaction/basic/demo/event.ts +++ b/s2-site/examples/interaction/basic/demo/event.ts @@ -222,6 +222,7 @@ fetch( S2Event.COL_CELL_CLICK, S2Event.CORNER_CELL_CLICK, S2Event.DATA_CELL_CLICK, + S2Event.DATA_CELL_SELECTED, S2Event.GLOBAL_SELECTED, S2Event.DATA_CELL_BRUSH_SELECTION, S2Event.LAYOUT_RESIZE, diff --git a/s2-site/examples/interaction/basic/demo/header-cell-click-selection.ts b/s2-site/examples/interaction/basic/demo/header-cell-click-selection.ts index 914c709cca..1041c1d70c 100644 --- a/s2-site/examples/interaction/basic/demo/header-cell-click-selection.ts +++ b/s2-site/examples/interaction/basic/demo/header-cell-click-selection.ts @@ -21,9 +21,17 @@ fetch( }; const s2 = new PivotSheet(container, dataCfg, s2Options); + s2.on(S2Event.ROW_CELL_SELECTED, (cells, detail) => { + console.log('row cell selected:', cells, detail); + }); + + s2.on(S2Event.COL_CELL_SELECTED, (cells, detail) => { + console.log('col cell selected:', cells, detail); + }); + // 也可以监听全局的选中事件 - s2.on(S2Event.GLOBAL_SELECTED, (cells) => { - console.log('selected', cells); + s2.on(S2Event.GLOBAL_SELECTED, (cells, detail) => { + console.log('selected', cells, detail); }); await s2.render(); diff --git a/s2-site/examples/interaction/basic/demo/selected-cell-move.ts b/s2-site/examples/interaction/basic/demo/selected-cell-move.ts index 7886c1f974..fe6741cf46 100644 --- a/s2-site/examples/interaction/basic/demo/selected-cell-move.ts +++ b/s2-site/examples/interaction/basic/demo/selected-cell-move.ts @@ -23,9 +23,13 @@ fetch( const s2 = new PivotSheet(container, dataCfg, s2Options); + s2.on(S2Event.DATA_CELL_SELECT_MOVE, (cells) => { + console.log('data cell select move:', cells); + }); + // 也可以监听全局的选中事件 - s2.on(S2Event.GLOBAL_SELECTED, (cells) => { - console.log('selected', cells); + s2.on(S2Event.GLOBAL_SELECTED, (cells, detail) => { + console.log('selected', cells, detail); }); await s2.render();