Skip to content

Commit

Permalink
feat:enable the left or right keyboard to switch image (#117)
Browse files Browse the repository at this point in the history
  • Loading branch information
zpc7 committed Apr 12, 2022
1 parent fdb9c0b commit 708d7ec
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 25 deletions.
42 changes: 35 additions & 7 deletions src/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import type { DialogProps as IDialogPropTypes } from 'rc-dialog';
import Dialog from 'rc-dialog';
import classnames from 'classnames';
import addEventListener from 'rc-util/lib/Dom/addEventListener';
import KeyCode from 'rc-util/lib/KeyCode';
import { warning } from 'rc-util/lib/warning';
import useFrameSetState from './hooks/useFrameSetState';
import getFixScaleEleTransPosition from './getFixScaleEleTransPosition';
import { context } from './PreviewGroup';

const { useState, useEffect } = React;
const { useState, useEffect, useCallback, useRef, useContext } = React;

export interface PreviewProps extends Omit<IDialogPropTypes, 'onClose'> {
onClose?: (e: React.SyntheticEvent<Element>) => void;
Expand Down Expand Up @@ -50,8 +51,8 @@ const Preview: React.FC<PreviewProps> = props => {
x: number;
y: number;
}>(initialPosition);
const imgRef = React.useRef<HTMLImageElement>();
const originPositionRef = React.useRef<{
const imgRef = useRef<HTMLImageElement>();
const originPositionRef = useRef<{
originX: number;
originY: number;
deltaX: number;
Expand All @@ -62,14 +63,14 @@ const Preview: React.FC<PreviewProps> = props => {
deltaX: 0,
deltaY: 0,
});
const [isMoving, setMoving] = React.useState(false);
const { previewUrls, current, isPreviewGroup, setCurrent } = React.useContext(context);
const [isMoving, setMoving] = useState(false);
const { previewUrls, current, isPreviewGroup, setCurrent } = useContext(context);
const previewGroupCount = previewUrls.size;
const previewUrlsKeys = Array.from(previewUrls.keys());
const currentPreviewIndex = previewUrlsKeys.indexOf(current);
const combinationSrc = isPreviewGroup ? previewUrls.get(current) : src;
const showLeftOrRightSwitches = isPreviewGroup && previewGroupCount > 1;
const [lastWheelZoomDirection, setLastWheelZoomDirection] = React.useState({ wheelDirection: 0 });
const [lastWheelZoomDirection, setLastWheelZoomDirection] = useState({ wheelDirection: 0 });

const onAfterClose = () => {
setScale(1);
Expand Down Expand Up @@ -201,6 +202,31 @@ const Preview: React.FC<PreviewProps> = props => {
setLastWheelZoomDirection({ wheelDirection });
};

const onKeyDown = useCallback(
(event: KeyboardEvent) => {
if (!visible || !showLeftOrRightSwitches) return;

event.preventDefault();
if (event.keyCode === KeyCode.LEFT) {
if (currentPreviewIndex > 0) {
setCurrent(previewUrlsKeys[currentPreviewIndex - 1]);
}
} else if (event.keyCode === KeyCode.RIGHT) {
if (currentPreviewIndex < previewGroupCount - 1) {
setCurrent(previewUrlsKeys[currentPreviewIndex + 1]);
}
}
},
[
currentPreviewIndex,
previewGroupCount,
previewUrlsKeys,
setCurrent,
showLeftOrRightSwitches,
visible,
],
);

useEffect(() => {
const { wheelDirection } = lastWheelZoomDirection;
if (wheelDirection > 0) {
Expand All @@ -219,6 +245,7 @@ const Preview: React.FC<PreviewProps> = props => {
const onScrollWheelListener = addEventListener(window, 'wheel', onWheelMove, {
passive: false,
});
const onKeyDownListener = addEventListener(window, 'keydown', onKeyDown, false);

try {
// Resolve if in iframe lost event
Expand All @@ -236,13 +263,14 @@ const Preview: React.FC<PreviewProps> = props => {
onMouseUpListener.remove();
onMouseMoveListener.remove();
onScrollWheelListener.remove();
onKeyDownListener.remove();

/* istanbul ignore next */
if (onTopMouseUpListener) onTopMouseUpListener.remove();
/* istanbul ignore next */
if (onTopMouseMoveListener) onTopMouseMoveListener.remove();
};
}, [visible, isMoving]);
}, [visible, isMoving, onKeyDown]);

return (
<Dialog
Expand Down
45 changes: 27 additions & 18 deletions tests/previewGroup.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { mount } from 'enzyme';
import { act } from 'react-dom/test-utils';
import KeyCode from 'rc-util/lib/KeyCode';
import Image from '../src';

describe('Preview', () => {
Expand All @@ -21,10 +22,7 @@ describe('Preview', () => {
);

act(() => {
wrapper
.find('.rc-image')
.at(0)
.simulate('click');
wrapper.find('.rc-image').at(0).simulate('click');
jest.runAllTimers();
wrapper.update();
});
Expand All @@ -44,10 +42,7 @@ describe('Preview', () => {
);

act(() => {
wrapper
.find('.rc-image')
.at(0)
.simulate('click');
wrapper.find('.rc-image').at(0).simulate('click');
jest.runAllTimers();
wrapper.update();
});
Expand All @@ -65,10 +60,7 @@ describe('Preview', () => {
);

act(() => {
wrapper
.find('.rc-image')
.at(0)
.simulate('click');
wrapper.find('.rc-image').at(0).simulate('click');
jest.runAllTimers();
wrapper.update();
});
Expand Down Expand Up @@ -96,6 +88,28 @@ describe('Preview', () => {
expect(
wrapper.find('.rc-image-preview .rc-image-preview-switch-left-disabled').get(0),
).toBeTruthy();

act(() => {
const event = new KeyboardEvent('keydown', { keyCode: KeyCode.RIGHT });
global.dispatchEvent(event);
jest.runAllTimers();
wrapper.update();
});

expect(
wrapper.find('.rc-image-preview .rc-image-preview-switch-right-disabled').get(0),
).toBeTruthy();

act(() => {
const event = new KeyboardEvent('keydown', { keyCode: KeyCode.LEFT });
global.dispatchEvent(event);
jest.runAllTimers();
wrapper.update();
});

expect(
wrapper.find('.rc-image-preview .rc-image-preview-switch-left-disabled').get(0),
).toBeTruthy();
});

it('With Controlled', () => {
Expand All @@ -113,11 +127,6 @@ describe('Preview', () => {
wrapper.update();
});

expect(
wrapper
.find('.rc-image-preview')
.at(0)
.render(),
).toMatchSnapshot();
expect(wrapper.find('.rc-image-preview').at(0).render()).toMatchSnapshot();
});
});

1 comment on commit 708d7ec

@vercel
Copy link

@vercel vercel bot commented on 708d7ec Apr 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.