diff --git a/common/changes/@visactor/vtable-plugins/fix-issue-5235-rotate-wheel_2026-07-25-12-00.json b/common/changes/@visactor/vtable-plugins/fix-issue-5235-rotate-wheel_2026-07-25-12-00.json new file mode 100644 index 0000000000..3096575108 --- /dev/null +++ b/common/changes/@visactor/vtable-plugins/fix-issue-5235-rotate-wheel_2026-07-25-12-00.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@visactor/vtable-plugins", + "comment": "fix: keep wheel events cancelable after restoring a rotated table (GitHub #5235)", + "type": "patch" + } + ], + "packageName": "@visactor/vtable-plugins", + "email": "biukam.w@gmail.com" +} diff --git a/packages/vtable-plugins/__tests__/rotate-table-plugin.test.ts b/packages/vtable-plugins/__tests__/rotate-table-plugin.test.ts new file mode 100644 index 0000000000..3fd7f61bda --- /dev/null +++ b/packages/vtable-plugins/__tests__/rotate-table-plugin.test.ts @@ -0,0 +1,88 @@ +// @ts-nocheck +jest.mock('@visactor/vtable', () => { + const vrender = jest.requireActual('../../vtable/src/vrender'); + + return { + matrixAllocate: vrender.matrixAllocate, + transformPointForCanvas: vrender.transformPointForCanvas, + mapToCanvasPointForCanvas: vrender.mapToCanvasPointForCanvas, + registerGlobalEventTransformer: vrender.registerGlobalEventTransformer, + registerWindowEventTransformer: vrender.registerWindowEventTransformer, + vglobal: { + mapToCanvasPoint: jest.fn(), + setEventListenerTransformer: jest.fn() + }, + TABLE_EVENT_TYPE: { + INITIALIZED: 'initialized' + } + }; +}); + +import { vglobal } from '@visactor/vtable'; +import { cancelTransform } from '../src/rotate-table'; + +global.__VERSION__ = 'none'; + +describe('RotateTablePlugin cancel transform - issue #5235', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + test('keeps wheel preventDefault connected to the native event after canceling rotation', () => { + const tableElement = document.createElement('div'); + jest.spyOn(tableElement, 'getBoundingClientRect').mockReturnValue({ + x: 40, + y: 80, + left: 40, + top: 80, + right: 640, + bottom: 480, + width: 600, + height: 400, + toJSON: () => ({}) + }); + + const originalMapToCanvasPoint = vglobal.mapToCanvasPoint; + const windowSetEventListenerTransformer = jest.fn(); + let globalTransformer; + + jest.spyOn(vglobal, 'setEventListenerTransformer').mockImplementation(transformer => { + globalTransformer = transformer; + }); + + const table = { + rotateDegree: 90, + getElement: () => tableElement, + scenegraph: { + stage: { + window: { + setEventListenerTransformer: windowSetEventListenerTransformer + } + } + }, + pluginManager: { + getPluginByName: () => ({ + vglobal_mapToCanvasPoint: originalMapToCanvasPoint + }) + } + }; + + cancelTransform.call(table, document.createElement('div')); + + const nativeWheelEvent = new WheelEvent('wheel', { + cancelable: true, + clientX: 120, + clientY: 160, + deltaY: 40 + }); + const transformedWheelEvent = globalTransformer(nativeWheelEvent); + + transformedWheelEvent.preventDefault(); + + expect(transformedWheelEvent).toBe(nativeWheelEvent); + expect(nativeWheelEvent.defaultPrevented).toBe(true); + expect(windowSetEventListenerTransformer).toHaveBeenCalledTimes(1); + expect(table.rotateDegree).toBe(0); + expect(vglobal.mapToCanvasPoint).toBe(originalMapToCanvasPoint); + }); +}); diff --git a/packages/vtable-plugins/src/rotate-table.ts b/packages/vtable-plugins/src/rotate-table.ts index 95955bc00d..582c154a2d 100644 --- a/packages/vtable-plugins/src/rotate-table.ts +++ b/packages/vtable-plugins/src/rotate-table.ts @@ -154,7 +154,6 @@ export function cancelTransform(this: ListTable, rotateDom: HTMLElement) { }; const getMatrix = () => { const matrix = matrixAllocate.allocate(1, 0, 0, 1, 0, 0); - matrix.translate(x1, y1); return matrix; }; registerGlobalEventTransformer(vglobal, this.getElement(), getMatrix, getRect as any, transformPointForCanvas);