Skip to content

Commit 4679e50

Browse files
EmilyyyLiu刘欢zombieJ
authored
feat: add wheel prop to control mouse wheel zoom (#521)
* feat: add wheel prop to control mouse wheel zoom - Add wheel prop to InternalPreviewConfig interface - Modify useMouseEvent hook to accept wheel parameter - Add test case for wheel: false - Update README documentation BREAKING CHANGE: N 🤖 Generated with [Claude Code](https://claude.com/claude-code) * feat: add wheel prop to description * feat: add wheel zoom functionality when wheel prop is true * ci: run React Doctor with Node 22 * ci: pin React Doctor before JSON report regression * ci: use stable React Doctor release --------- Co-authored-by: 刘欢 <lh01217311@antgroup.com> Co-authored-by: 二货机器人 <smith3816@gmail.com>
1 parent 4852851 commit 4679e50

6 files changed

Lines changed: 84 additions & 1 deletion

File tree

‎.github/workflows/react-doctor.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ jobs:
2525
fetch-depth: 0
2626
persist-credentials: false
2727
- uses: millionco/react-doctor@0b4f4f4bd248a154e64eb508a48347f71154b3f3
28+
with:
29+
version: 0.7.4

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ Native image attributes are also supported.
102102
| open | Controlled preview open state | boolean | - |
103103
| scaleStep | Scale step | number | 0.5 |
104104
| src | Custom preview image source | string | - |
105+
| wheel | Enable mouse wheel zoom | boolean | true |
105106
| onOpenChange | Callback when preview open state changes | `(open: boolean) => void` | - |
106107
| onTransform | Callback when transform changes | `(info: { transform: TransformType; action: TransformAction }) => void` | - |
107108

‎README.zh-CN.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ npm start
102102
| open | 受控预览打开状态 | boolean | - |
103103
| scaleStep | 缩放步长 | number | 0.5 |
104104
| src | 自定义预览图像源 | string | - |
105+
| wheel | 启用鼠标滚轮缩放 | boolean | true |
105106
| onOpenChange | 预览打开状态变化时回调 | `(open: boolean) => void` | - |
106107
| onTransform | 变换变化时的回调 | `(info: { transform: TransformType; action: TransformAction }) => void` | - |
107108

‎src/Preview/index.tsx‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ export interface InternalPreviewConfig {
7979
minScale?: number;
8080
maxScale?: number;
8181

82+
/** Whether to enable mouse wheel zoom. Default is true. */
83+
wheel?: boolean;
84+
8285
// Display
8386
motionName?: string;
8487
open?: boolean;
@@ -196,6 +199,7 @@ const Preview: React.FC<PreviewProps> = props => {
196199
styles = {},
197200
mousePosition,
198201
zIndex,
202+
wheel = true,
199203
focusTrap = true,
200204
} = props;
201205

@@ -223,6 +227,7 @@ const Preview: React.FC<PreviewProps> = props => {
223227
transform,
224228
updateTransform,
225229
dispatchZoomChange,
230+
wheel,
226231
);
227232
const { isTouching, onTouchStart, onTouchMove, onTouchEnd } = useTouchEvent(
228233
imgRef,

‎src/hooks/useMouseEvent.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export default function useMouseEvent(
1717
transform: TransformType,
1818
updateTransform: UpdateTransformFunc,
1919
dispatchZoomChange: DispatchZoomChangeFunc,
20+
wheel: boolean = true,
2021
) {
2122
const { rotate, scale, x, y } = transform;
2223

@@ -83,7 +84,7 @@ export default function useMouseEvent(
8384
};
8485

8586
const onWheel = (event: React.WheelEvent<HTMLImageElement>) => {
86-
if (!open || event.deltaY == 0) return;
87+
if (!open || !wheel || event.deltaY == 0) return;
8788
// Scale ratio depends on the deltaY size
8889
const scaleRatio = Math.abs(event.deltaY / 100);
8990
// Limit the maximum scale ratio

‎tests/preview.test.tsx‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,79 @@ describe('Preview', () => {
289289
});
290290
});
291291

292+
it('should zoom with wheel when wheel is explicitly true', () => {
293+
const { container } = render(
294+
<Image
295+
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
296+
preview={{
297+
open: true,
298+
wheel: true,
299+
}}
300+
/>,
301+
);
302+
fireEvent.click(container.querySelector('.rc-image'));
303+
act(() => {
304+
jest.runAllTimers();
305+
});
306+
307+
expect(document.querySelector('.rc-image-preview-img')).toHaveStyle({
308+
transform: 'translate3d(0px, 0px, 0) scale3d(1, 1, 1) rotate(0deg)',
309+
});
310+
311+
// Wheel zoom should work when wheel is true
312+
fireEvent.wheel(document.querySelector('.rc-image-preview-img'), {
313+
deltaY: -50,
314+
});
315+
316+
act(() => {
317+
jest.runAllTimers();
318+
});
319+
320+
// Scale should change to 1.25
321+
expect(document.querySelector('.rc-image-preview-img')).toHaveStyle({
322+
transform: 'translate3d(0px, 0px, 0) scale3d(1.25, 1.25, 1) rotate(0deg)',
323+
});
324+
});
325+
326+
it('should not zoom with wheel when wheel is false', () => {
327+
const { container } = render(
328+
<Image
329+
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
330+
preview={{
331+
open: true,
332+
wheel: false,
333+
}}
334+
/>,
335+
);
336+
337+
expect(document.querySelector('.rc-image-preview-img')).toHaveStyle({
338+
transform: 'translate3d(0px, 0px, 0) scale3d(1, 1, 1) rotate(0deg)',
339+
});
340+
341+
// Wheel zoom should not work when wheel is false
342+
fireEvent.wheel(document.querySelector('.rc-image-preview-img'), {
343+
deltaY: -50,
344+
});
345+
346+
act(() => {
347+
jest.runAllTimers();
348+
});
349+
350+
// Scale should remain 1
351+
expect(document.querySelector('.rc-image-preview-img')).toHaveStyle({
352+
transform: 'translate3d(0px, 0px, 0) scale3d(1, 1, 1) rotate(0deg)',
353+
});
354+
355+
// But zoom in button should still work
356+
fireEvent.click(document.querySelectorAll('.rc-image-preview-actions-action')[5]);
357+
act(() => {
358+
jest.runAllTimers();
359+
});
360+
expect(document.querySelector('.rc-image-preview-img')).toHaveStyle({
361+
transform: 'translate3d(-256px, -192px, 0) scale3d(1.5, 1.5, 1) rotate(0deg)',
362+
});
363+
});
364+
292365
it('scaleStep = 1', () => {
293366
const { container } = render(
294367
<Image

0 commit comments

Comments
 (0)