diff --git a/src/hooks/useFrameWheel.ts b/src/hooks/useFrameWheel.ts index bef5f7bd..7b6d01b2 100644 --- a/src/hooks/useFrameWheel.ts +++ b/src/hooks/useFrameWheel.ts @@ -28,10 +28,9 @@ export default function useFrameWheel( // Scroll status sync const originScroll = useOriginScroll(isScrollAtTop, isScrollAtBottom); - function onWheelY(event: WheelEvent) { + function onWheelY(event: WheelEvent, deltaY: number) { raf.cancel(nextFrameRef.current); - const { deltaY } = event; offsetRef.current += deltaY; wheelValueRef.current = deltaY; @@ -52,9 +51,7 @@ export default function useFrameWheel( }); } - function onWheelX(event: WheelEvent) { - const { deltaX } = event; - + function onWheelX(event: WheelEvent, deltaX: number) { onWheelDelta(deltaX, true); if (!isFF) { @@ -62,8 +59,8 @@ export default function useFrameWheel( } } - // Check for which direction does wheel do - const wheelDirectionRef = useRef<'x' | 'y' | null>(null); + // Check for which direction does wheel do. `sx` means `shift + wheel` + const wheelDirectionRef = useRef<'x' | 'y' | 'sx' | null>(null); const wheelDirectionCleanRef = useRef(null); function onWheel(event: WheelEvent) { @@ -75,18 +72,32 @@ export default function useFrameWheel( wheelDirectionRef.current = null; }, 2); - const { deltaX, deltaY } = event; - const absX = Math.abs(deltaX); - const absY = Math.abs(deltaY); + const { deltaX, deltaY, shiftKey } = event; + + let mergedDeltaX = deltaX; + let mergedDeltaY = deltaY; + + if ( + wheelDirectionRef.current === 'sx' || + (!wheelDirectionRef.current && (shiftKey || false) && deltaY && !deltaX) + ) { + mergedDeltaX = deltaY; + mergedDeltaY = 0; + + wheelDirectionRef.current = 'sx'; + } + + const absX = Math.abs(mergedDeltaX); + const absY = Math.abs(mergedDeltaY); if (wheelDirectionRef.current === null) { wheelDirectionRef.current = horizontalScroll && absX > absY ? 'x' : 'y'; } - if (wheelDirectionRef.current === 'x') { - onWheelX(event); + if (wheelDirectionRef.current === 'y') { + onWheelY(event, mergedDeltaY); } else { - onWheelY(event); + onWheelX(event, mergedDeltaX); } } diff --git a/tests/scrollWidth.test.tsx b/tests/scrollWidth.test.tsx index 0230875f..2ca215f8 100644 --- a/tests/scrollWidth.test.tsx +++ b/tests/scrollWidth.test.tsx @@ -151,6 +151,25 @@ describe('List.scrollWidth', () => { }); expect(onVirtualScroll).toHaveBeenCalledWith({ x: 123, y: 0 }); }); + + it('shift wheel', async () => { + const onVirtualScroll = jest.fn(); + + const { container } = await genList({ + itemHeight: ITEM_HEIGHT, + height: 100, + data: genData(100), + scrollWidth: 1000, + onVirtualScroll, + }); + + // Wheel + fireEvent.wheel(container.querySelector('.rc-virtual-list-holder')!, { + deltaY: 123, + shiftKey: true, + }); + expect(onVirtualScroll).toHaveBeenCalledWith({ x: 123, y: 0 }); + }); }); it('ref scrollTo', async () => {