Skip to content

Commit

Permalink
fix(ImagePreview): double-scale and close-on-click-overlay may not wo…
Browse files Browse the repository at this point in the history
…rk in certain scenarios (#12521)
  • Loading branch information
inottn authored Dec 23, 2023
1 parent de023c6 commit 8756ceb
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 18 deletions.
18 changes: 10 additions & 8 deletions packages/vant/src/image-preview/ImagePreviewItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,14 @@ export default defineComponent({
}
};

const checkClose = (event: TouchEvent) => {
const isClickOverlay = event.target === swipeItem.value?.$el;

if (!props.closeOnClickOverlay && isClickOverlay) return;

emit('close');
};

const checkTap = (event: TouchEvent) => {
if (fingerNum > 1) {
return;
Expand All @@ -272,19 +280,13 @@ export default defineComponent({
doubleTapTimer = null;
toggleScale();
} else {
if (
!props.closeOnClickOverlay &&
event.target === swipeItem.value?.$el
) {
return;
}
doubleTapTimer = setTimeout(() => {
emit('close');
checkClose(event);
doubleTapTimer = null;
}, TAP_TIME);
}
} else {
emit('close');
checkClose(event);
}
}
// long press
Expand Down
36 changes: 27 additions & 9 deletions packages/vant/src/image-preview/test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from '../../../test';
import { LONG_PRESS_START_TIME } from '../../utils';
import ImagePreview from '../ImagePreview';
import { images, triggerZoom } from './shared';
import { images, triggerDoubleTap, triggerZoom } from './shared';
import type { ImagePreviewInstance } from '../types';

test('should swipe to current index after calling the swipeTo method', async () => {
Expand Down Expand Up @@ -230,38 +230,56 @@ test('should trigger scale after double clicking', async () => {

await later();
const swipe = wrapper.find('.van-swipe-item');
triggerDrag(swipe, 0, 0);
triggerDrag(swipe, 0, 0);

triggerDoubleTap(swipe);
expect(onScale).toHaveBeenCalledWith({
index: 0,
scale: 2,
});

await later();
triggerDrag(swipe, 0, 0);
triggerDrag(swipe, 0, 0);
triggerDoubleTap(swipe);
expect(onScale).toHaveBeenLastCalledWith({
index: 0,
scale: 1,
});

// when closeOnClickOverlay is set to false, it will not affect the zooming.
onScale.mockClear();
await wrapper.setProps({ closeOnClickOverlay: false });
triggerDoubleTap(swipe);
expect(onScale).toHaveBeenCalled();
});

test('should allow to disable double click gesture', async () => {
const onScale = vi.fn();
const onClose = vi.fn();
const wrapper = mount(ImagePreview, {
props: {
images,
show: true,
doubleScale: false,
onClose,
onScale,
'onUpdate:show': (show) => {
wrapper.setProps({ show });
},
},
});

// The ImagePreview will close because double-click is disabled.
await later();
const swipe = wrapper.find('.van-swipe-item');
triggerDrag(swipe, 0, 0);
triggerDrag(swipe, 0, 0);
expect(onScale).toHaveBeenCalledTimes(0);
await triggerDoubleTap(swipe);
expect(onClose).toHaveBeenCalled();
expect(onScale).not.toHaveBeenCalled();

// The ImagePreview will not close when closeOnClickOverlay is set to false.
onClose.mockClear();
await wrapper.setProps({ closeOnClickOverlay: false, show: true });
await triggerDrag(swipe, 0, 0);
expect(onClose).not.toHaveBeenCalled();
await triggerDoubleTap(swipe, 0, 0);
expect(onClose).not.toHaveBeenCalled();
});

test('zoom in and drag image to move', async () => {
Expand Down
14 changes: 13 additions & 1 deletion packages/vant/src/image-preview/test/shared.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { nextTick } from 'vue';
import { DOMWrapper } from '@vue/test-utils/dist/domWrapper';
import { cdnURL } from '../../../docs/site';
import { trigger } from '../../../test';
import { trigger, triggerDrag } from '../../../test';

export const images = [
cdnURL('apple-1.jpeg'),
Expand Down Expand Up @@ -38,3 +39,14 @@ export function triggerZoom(

trigger(el, 'touchend', 0, 0, { touchList: [] });
}

export function triggerDoubleTap(
el: HTMLElement | DOMWrapper<Element>,
x: number = 0,
y: number = 0,
) {
triggerDrag(el, x, y);
triggerDrag(el, x, y);

return nextTick();
}

0 comments on commit 8756ceb

Please sign in to comment.