From ac1a16ca46da8af96d82c376d8862f1e9f10cac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=AB=E5=90=9B?= Date: Sat, 6 May 2023 15:41:55 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E7=B3=BB=E7=BB=9F=E6=8B=A6=E6=88=AA?= =?UTF-8?q?=E5=BF=AB=E6=8D=B7=E9=94=AE=E5=90=8E=E5=A4=9A=E9=80=89=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../click/row-column-click.ts | 23 ++++++++++++++++--- .../interaction/data-cell-multi-selection.ts | 12 +++++++++- .../src/interaction/range-selection.ts | 10 ++++++++ .../src/utils/interaction/select-event.ts | 4 ++++ 4 files changed, 45 insertions(+), 4 deletions(-) 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 1e97344f65..48c518c230 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 @@ -20,7 +20,10 @@ import { hideColumnsByThunkGroup, isEqualDisplaySiblingNodeId, } from '../../../utils/hide-columns'; -import { isMultiSelectionKey } from '../../../utils/interaction/select-event'; +import { + isMouseEventWithMeta, + isMultiSelectionKey, +} from '../../../utils/interaction/select-event'; import { getTooltipOptions, getTooltipVisibleOperator, @@ -36,6 +39,12 @@ export class RowColumnClick extends BaseEvent implements BaseEventImplement { this.bindColCellClick(); this.bindRowCellClick(); this.bindTableColExpand(); + this.bindMouseMove(); + } + + public reset() { + this.isMultiSelection = false; + this.spreadsheet.interaction.removeIntercepts([InterceptType.CLICK]); } private bindKeyboardDown() { @@ -52,8 +61,16 @@ export class RowColumnClick extends BaseEvent implements BaseEventImplement { private bindKeyboardUp() { this.spreadsheet.on(S2Event.GLOBAL_KEYBOARD_UP, (event: KeyboardEvent) => { if (isMultiSelectionKey(event)) { - this.isMultiSelection = false; - this.spreadsheet.interaction.removeIntercepts([InterceptType.CLICK]); + this.reset(); + } + }); + } + + private bindMouseMove() { + this.spreadsheet.on(S2Event.GLOBAL_MOUSE_MOVE, (event) => { + // 当快捷键被系统拦截后,按需补充调用一次 reset + if (this.isMultiSelection && !isMouseEventWithMeta(event)) { + this.reset(); } }); } 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 14ab8afe53..b1ae87c6c7 100644 --- a/packages/s2-core/src/interaction/data-cell-multi-selection.ts +++ b/packages/s2-core/src/interaction/data-cell-multi-selection.ts @@ -11,7 +11,7 @@ import type { CellMeta, S2CellType, ViewMeta } from '../common/interface'; import { getCellMeta, isMultiSelectionKey, - getInteractionCellsBySelectedCells, + isMouseEventWithMeta, } from '../utils/interaction/select-event'; import { getCellsTooltipData } from '../utils/tooltip'; import { afterSelectDataCells } from '../utils/interaction/select-event'; @@ -27,6 +27,7 @@ export class DataCellMultiSelection this.bindKeyboardDown(); this.bindDataCellClick(); this.bindKeyboardUp(); + this.bindMouseMove(); } public reset() { @@ -54,6 +55,15 @@ export class DataCellMultiSelection }); } + private bindMouseMove() { + this.spreadsheet.on(S2Event.GLOBAL_MOUSE_MOVE, (event) => { + // 当快捷键被系统拦截后,按需补充调用一次 reset + if (this.isMultiSelection && !isMouseEventWithMeta(event)) { + this.reset(); + } + }); + } + private getSelectedCells(cell: S2CellType) { const id = cell.getMeta().id; const { interaction } = this.spreadsheet; diff --git a/packages/s2-core/src/interaction/range-selection.ts b/packages/s2-core/src/interaction/range-selection.ts index 45e2f076cc..1d334e410b 100644 --- a/packages/s2-core/src/interaction/range-selection.ts +++ b/packages/s2-core/src/interaction/range-selection.ts @@ -22,6 +22,7 @@ export class RangeSelection extends BaseEvent implements BaseEventImplement { this.bindDataCellClick(); this.bindColCellClick(); this.bindKeyboardUp(); + this.bindMouseMove(); } public reset() { @@ -49,6 +50,15 @@ export class RangeSelection extends BaseEvent implements BaseEventImplement { }); } + private bindMouseMove() { + // 当快捷键被系统拦截后,按需补充调用一次 reset + this.spreadsheet.on(S2Event.GLOBAL_MOUSE_MOVE, (event) => { + if (this.isRangeSelection && !event.shiftKey) { + this.reset(); + } + }); + } + private bindColCellClick() { if (this.spreadsheet.isTableMode()) { // series-number click diff --git a/packages/s2-core/src/utils/interaction/select-event.ts b/packages/s2-core/src/utils/interaction/select-event.ts index c6710840c0..7d9c66cf73 100644 --- a/packages/s2-core/src/utils/interaction/select-event.ts +++ b/packages/s2-core/src/utils/interaction/select-event.ts @@ -25,6 +25,10 @@ export const isMultiSelectionKey = (e: KeyboardEvent) => { ); }; +export const isMouseEventWithMeta = (e: MouseEvent) => { + return e.ctrlKey || e.metaKey; +}; + export const getCellMeta = (cell: S2CellType): CellMeta => { const meta = cell.getMeta(); const { id, colIndex, rowIndex, rowQuery } = meta || {}; From 9c911f216d090775cf186dd43727dafc82371db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=AB=E5=90=9B?= Date: Sat, 6 May 2023 16:17:28 +0800 Subject: [PATCH 2/2] =?UTF-8?q?test:=20=E5=A2=9E=E5=8A=A0=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../click/row-column-click-spec.ts | 43 ++++++++++++++++++- .../data-cell-multi-selection-spec.ts | 18 +++++++- .../unit/interaction/range-selection-spec.ts | 11 +++++ 3 files changed, 69 insertions(+), 3 deletions(-) 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 2b878082bc..4e8046eed1 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 @@ -9,7 +9,12 @@ import type { ViewMeta, } from '@/common/interface'; import type { SpreadSheet } from '@/sheet-type'; -import { InteractionStateName, S2Event } from '@/common/constant'; +import { + InteractionKeyboardKey, + InteractionStateName, + InterceptType, + S2Event, +} from '@/common/constant'; import type { Node } from '@/facet/layout/node'; jest.mock('@/interaction/event-controller'); @@ -84,6 +89,42 @@ describe('Interaction Row & Column Cell Click Tests', () => { expect(rowColumnClick.bindEvents).toBeDefined(); }); + test.each([InteractionKeyboardKey.META, InteractionKeyboardKey.CONTROL])( + 'should add click intercept when %s keydown', + (key) => { + s2.emit(S2Event.GLOBAL_KEYBOARD_DOWN, { + key, + } as KeyboardEvent); + + expect(s2.interaction.hasIntercepts([InterceptType.CLICK])).toBeTruthy(); + }, + ); + + test.each([InteractionKeyboardKey.META, InteractionKeyboardKey.CONTROL])( + 'should remove click intercept when %s keyup', + (key) => { + s2.interaction.addIntercepts([InterceptType.CLICK]); + s2.emit(S2Event.GLOBAL_KEYBOARD_UP, { + key, + } as KeyboardEvent); + + expect(s2.interaction.hasIntercepts([InterceptType.CLICK])).toBeFalsy(); + }, + ); + + test.each([InteractionKeyboardKey.META, InteractionKeyboardKey.CONTROL])( + 'should remove click intercept when %s released', + () => { + Object.defineProperty(rowColumnClick, 'isMultiSelection', { + value: true, + }); + s2.interaction.addIntercepts([InterceptType.CLICK]); + s2.emit(S2Event.GLOBAL_MOUSE_MOVE, {} as MouseEvent); + + expect(s2.interaction.hasIntercepts([InterceptType.CLICK])).toBeFalsy(); + }, + ); + // https://github.com/antvis/S2/issues/1243 test.each([S2Event.ROW_CELL_CLICK, S2Event.COL_CELL_CLICK])( 'should selected cell when %s cell clicked', 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 6420f5fdd3..28887017ae 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 @@ -47,7 +47,7 @@ describe('Interaction Data Cell Multi Selection Tests', () => { }); test.each([InteractionKeyboardKey.META, InteractionKeyboardKey.CONTROL])( - 'should add click intercept when keydown', + 'should add click intercept when %s keydown', (key) => { s2.emit(S2Event.GLOBAL_KEYBOARD_DOWN, { key, @@ -58,8 +58,9 @@ describe('Interaction Data Cell Multi Selection Tests', () => { ); test.each([InteractionKeyboardKey.META, InteractionKeyboardKey.CONTROL])( - 'should remove click intercept when keyup', + 'should remove click intercept when %s keyup', (key) => { + s2.interaction.addIntercepts([InterceptType.CLICK]); s2.emit(S2Event.GLOBAL_KEYBOARD_UP, { key, } as KeyboardEvent); @@ -68,6 +69,19 @@ describe('Interaction Data Cell Multi Selection Tests', () => { }, ); + test.each([InteractionKeyboardKey.META, InteractionKeyboardKey.CONTROL])( + 'should remove click intercept when %s released', + () => { + Object.defineProperty(dataCellMultiSelection, 'isMultiSelection', { + value: true, + }); + s2.interaction.addIntercepts([InterceptType.CLICK]); + s2.emit(S2Event.GLOBAL_MOUSE_MOVE, {} as MouseEvent); + + expect(s2.interaction.hasIntercepts([InterceptType.CLICK])).toBeFalsy(); + }, + ); + test.each([InteractionKeyboardKey.META, InteractionKeyboardKey.CONTROL])( 'should select multiple data cell', (key) => { 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 f6fb75b9ef..165ccc2cdb 100644 --- a/packages/s2-core/__tests__/unit/interaction/range-selection-spec.ts +++ b/packages/s2-core/__tests__/unit/interaction/range-selection-spec.ts @@ -54,6 +54,7 @@ describe('Interaction Range Selection Tests', () => { }); test('should remove click intercept when shift keyup', () => { + s2.interaction.addIntercepts([InterceptType.CLICK]); s2.emit(S2Event.GLOBAL_KEYBOARD_UP, { key: InteractionKeyboardKey.SHIFT, } as KeyboardEvent); @@ -61,6 +62,16 @@ describe('Interaction Range Selection Tests', () => { expect(s2.interaction.hasIntercepts([InterceptType.CLICK])).toBeFalsy(); }); + test('should remove click intercept when shift released', () => { + Object.defineProperty(rangeSelection, 'isRangeSelection', { + value: true, + }); + s2.interaction.addIntercepts([InterceptType.CLICK]); + s2.emit(S2Event.GLOBAL_MOUSE_MOVE, {} as MouseEvent); + + expect(s2.interaction.hasIntercepts([InterceptType.CLICK])).toBeFalsy(); + }); + test('should set last clicked cell', () => { s2.interaction.changeState({ cells: [],