Skip to content

Commit 84bffae

Browse files
authored
chore: shift wheel trigger horizontal scroll (#228)
* feat: support shift scroll * test: add test case
1 parent 166aba7 commit 84bffae

File tree

2 files changed

+43
-13
lines changed

2 files changed

+43
-13
lines changed

src/hooks/useFrameWheel.ts

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@ export default function useFrameWheel(
2828
// Scroll status sync
2929
const originScroll = useOriginScroll(isScrollAtTop, isScrollAtBottom);
3030

31-
function onWheelY(event: WheelEvent) {
31+
function onWheelY(event: WheelEvent, deltaY: number) {
3232
raf.cancel(nextFrameRef.current);
3333

34-
const { deltaY } = event;
3534
offsetRef.current += deltaY;
3635
wheelValueRef.current = deltaY;
3736

@@ -52,18 +51,16 @@ export default function useFrameWheel(
5251
});
5352
}
5453

55-
function onWheelX(event: WheelEvent) {
56-
const { deltaX } = event;
57-
54+
function onWheelX(event: WheelEvent, deltaX: number) {
5855
onWheelDelta(deltaX, true);
5956

6057
if (!isFF) {
6158
event.preventDefault();
6259
}
6360
}
6461

65-
// Check for which direction does wheel do
66-
const wheelDirectionRef = useRef<'x' | 'y' | null>(null);
62+
// Check for which direction does wheel do. `sx` means `shift + wheel`
63+
const wheelDirectionRef = useRef<'x' | 'y' | 'sx' | null>(null);
6764
const wheelDirectionCleanRef = useRef<number>(null);
6865

6966
function onWheel(event: WheelEvent) {
@@ -75,18 +72,32 @@ export default function useFrameWheel(
7572
wheelDirectionRef.current = null;
7673
}, 2);
7774

78-
const { deltaX, deltaY } = event;
79-
const absX = Math.abs(deltaX);
80-
const absY = Math.abs(deltaY);
75+
const { deltaX, deltaY, shiftKey } = event;
76+
77+
let mergedDeltaX = deltaX;
78+
let mergedDeltaY = deltaY;
79+
80+
if (
81+
wheelDirectionRef.current === 'sx' ||
82+
(!wheelDirectionRef.current && (shiftKey || false) && deltaY && !deltaX)
83+
) {
84+
mergedDeltaX = deltaY;
85+
mergedDeltaY = 0;
86+
87+
wheelDirectionRef.current = 'sx';
88+
}
89+
90+
const absX = Math.abs(mergedDeltaX);
91+
const absY = Math.abs(mergedDeltaY);
8192

8293
if (wheelDirectionRef.current === null) {
8394
wheelDirectionRef.current = horizontalScroll && absX > absY ? 'x' : 'y';
8495
}
8596

86-
if (wheelDirectionRef.current === 'x') {
87-
onWheelX(event);
97+
if (wheelDirectionRef.current === 'y') {
98+
onWheelY(event, mergedDeltaY);
8899
} else {
89-
onWheelY(event);
100+
onWheelX(event, mergedDeltaX);
90101
}
91102
}
92103

tests/scrollWidth.test.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,25 @@ describe('List.scrollWidth', () => {
151151
});
152152
expect(onVirtualScroll).toHaveBeenCalledWith({ x: 123, y: 0 });
153153
});
154+
155+
it('shift wheel', async () => {
156+
const onVirtualScroll = jest.fn();
157+
158+
const { container } = await genList({
159+
itemHeight: ITEM_HEIGHT,
160+
height: 100,
161+
data: genData(100),
162+
scrollWidth: 1000,
163+
onVirtualScroll,
164+
});
165+
166+
// Wheel
167+
fireEvent.wheel(container.querySelector('.rc-virtual-list-holder')!, {
168+
deltaY: 123,
169+
shiftKey: true,
170+
});
171+
expect(onVirtualScroll).toHaveBeenCalledWith({ x: 123, y: 0 });
172+
});
154173
});
155174

156175
it('ref scrollTo', async () => {

0 commit comments

Comments
 (0)