mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
feat(ImagePreview): add closeOnClickOverlay option (#12153)
This commit is contained in:
parent
afeef70429
commit
d988df7ba5
@ -69,6 +69,7 @@ export const imagePreviewProps = {
|
||||
startPosition: makeNumericProp(0),
|
||||
showIndicators: Boolean,
|
||||
closeOnPopstate: truthProp,
|
||||
closeOnClickOverlay: truthProp,
|
||||
closeIconPosition: makeStringProp<PopupCloseIconPosition>('top-right'),
|
||||
teleport: [String, Object] as PropType<TeleportProps['to']>,
|
||||
};
|
||||
@ -173,6 +174,7 @@ export default defineComponent({
|
||||
rootWidth={state.rootWidth}
|
||||
rootHeight={state.rootHeight}
|
||||
disableZoom={state.disableZoom}
|
||||
closeOnClickOverlay={props.closeOnClickOverlay}
|
||||
onScale={emitScale}
|
||||
onClose={emitClose}
|
||||
onLongPress={() => emit('longPress', { index })}
|
||||
|
@ -53,6 +53,7 @@ export default defineComponent({
|
||||
rootWidth: makeRequiredProp(Number),
|
||||
rootHeight: makeRequiredProp(Number),
|
||||
disableZoom: Boolean,
|
||||
closeOnClickOverlay: Boolean,
|
||||
},
|
||||
|
||||
emits: ['scale', 'close', 'longPress'],
|
||||
@ -241,7 +242,7 @@ export default defineComponent({
|
||||
}
|
||||
};
|
||||
|
||||
const checkTap = () => {
|
||||
const checkTap = (event: TouchEvent) => {
|
||||
if (fingerNum > 1) {
|
||||
return;
|
||||
}
|
||||
@ -260,6 +261,12 @@ export default defineComponent({
|
||||
doubleTapTimer = null;
|
||||
toggleScale();
|
||||
} else {
|
||||
if (
|
||||
!props.closeOnClickOverlay &&
|
||||
event.target === swipeItem.value?.$el
|
||||
) {
|
||||
return;
|
||||
}
|
||||
doubleTapTimer = setTimeout(() => {
|
||||
emit('close');
|
||||
doubleTapTimer = null;
|
||||
@ -314,7 +321,7 @@ export default defineComponent({
|
||||
// eliminate tap delay on safari
|
||||
preventDefault(event, stopPropagation);
|
||||
|
||||
checkTap();
|
||||
checkTap(event);
|
||||
touch.reset();
|
||||
};
|
||||
|
||||
|
@ -195,6 +195,7 @@ Vant exports following ImagePreview utility functions:
|
||||
| onChange | Emitted when current image changed | _Function_ | - |
|
||||
| onScale | Emitted when scaling current image | _Function_ | - |
|
||||
| closeOnPopstate | Whether to close when popstate | _boolean_ | `true` |
|
||||
| closeOnClickOverlay `v4.6.4` | Whether to close when overlay is clicked | _boolean_ | `true` |
|
||||
| beforeClose | Callback function before close | _(action) => boolean \| Promise_ | - |
|
||||
| className | Custom className | _string \| Array \| object_ | - |
|
||||
| maxZoom | Max zoom | _number \| string_ | `3` |
|
||||
@ -220,6 +221,7 @@ Vant exports following ImagePreview utility functions:
|
||||
| loop | Whether to enable loop | _boolean_ | `true` |
|
||||
| before-close | Callback function before close | _(action: number) => boolean \| Promise\<boolean\>_ | - |
|
||||
| close-on-popstate | Whether to close when popstate | _boolean_ | `true` |
|
||||
| close-on-click-overlay `v4.6.4` | Whether to close when overlay is clicked | _boolean_ | `true` |
|
||||
| class-name | Custom className | _string \| Array \| object_ | - |
|
||||
| max-zoom | Max zoom | _number \| string_ | `3` |
|
||||
| min-zoom | Min zoom | _number \| string_ | `1/3` |
|
||||
|
@ -209,6 +209,7 @@ Vant 中导出了以下 ImagePreview 相关的辅助函数:
|
||||
| onScale | 缩放图片时的回调函数,回调参数为当前索引和当前缩放值组成的对象 | _Function_ | - |
|
||||
| beforeClose | 关闭前的回调函数,返回 `false` 可阻止关闭,支持返回 Promise | _(active: number) => boolean \| Promise\<boolean\>_ | - |
|
||||
| closeOnPopstate | 是否在页面回退时自动关闭 | _boolean_ | `true` |
|
||||
| closeOnClickOverlay `v4.6.4` | 是否在点击遮罩层后关闭图片预览 | _boolean_ | `true` |
|
||||
| className | 自定义类名 | _string \| Array \| object_ | - |
|
||||
| maxZoom | 手势缩放时,最大缩放比例 | _number \| string_ | `3` |
|
||||
| minZoom | 手势缩放时,最小缩放比例 | _number \| string_ | `1/3` |
|
||||
@ -235,6 +236,7 @@ Vant 中导出了以下 ImagePreview 相关的辅助函数:
|
||||
| loop | 是否开启循环播放 | _boolean_ | `true` |
|
||||
| before-close | 关闭前的回调函数,返回 `false` 可阻止关闭,支持返回 Promise | _(active: number) => boolean \| Promise\<boolean\>_ | - |
|
||||
| close-on-popstate | 是否在页面回退时自动关闭 | _boolean_ | `true` |
|
||||
| close-on-click-overlay `v4.6.4` | 是否在点击遮罩层后关闭图片预览 | _boolean_ | `true` |
|
||||
| class-name | 自定义类名 | _string \| Array \| object_ | - |
|
||||
| max-zoom | 手势缩放时,最大缩放比例 | _number \| string_ | `3` |
|
||||
| min-zoom | 手势缩放时,最小缩放比例 | _number \| string_ | `1/3` |
|
||||
|
@ -26,6 +26,7 @@ const defaultConfig: ImagePreviewOptions = {
|
||||
swipeDuration: 300,
|
||||
showIndicators: false,
|
||||
closeOnPopstate: true,
|
||||
closeOnClickOverlay: true,
|
||||
closeIconPosition: 'top-right',
|
||||
};
|
||||
|
||||
|
@ -6,11 +6,11 @@ import {
|
||||
trigger,
|
||||
} from '../../../test';
|
||||
import { LONG_PRESS_START_TIME } from '../../utils';
|
||||
import ImagePreviewComponent from '../ImagePreview';
|
||||
import ImagePreview from '../ImagePreview';
|
||||
import { images, triggerZoom } from './shared';
|
||||
|
||||
test('should swipe to current index after calling the swipeTo method', async () => {
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
show: true,
|
||||
images,
|
||||
@ -26,7 +26,7 @@ test('should swipe to current index after calling the swipeTo method', async ()
|
||||
|
||||
test('should allow to use the teleport prop', () => {
|
||||
const root = document.createElement('div');
|
||||
mount(ImagePreviewComponent, {
|
||||
mount(ImagePreview, {
|
||||
props: {
|
||||
show: true,
|
||||
teleport: root,
|
||||
@ -37,7 +37,7 @@ test('should allow to use the teleport prop', () => {
|
||||
});
|
||||
|
||||
test('should render cover slot correctly', () => {
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
show: true,
|
||||
},
|
||||
@ -50,7 +50,7 @@ test('should render cover slot correctly', () => {
|
||||
});
|
||||
|
||||
test('should render index slot correctly', () => {
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
show: true,
|
||||
},
|
||||
@ -63,7 +63,7 @@ test('should render index slot correctly', () => {
|
||||
});
|
||||
|
||||
test('should render close icon when using closeable prop', () => {
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
show: true,
|
||||
images,
|
||||
@ -76,7 +76,7 @@ test('should render close icon when using closeable prop', () => {
|
||||
});
|
||||
|
||||
test('should change close icon when using close-icon prop', () => {
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
show: true,
|
||||
closeable: true,
|
||||
@ -90,7 +90,7 @@ test('should change close icon when using close-icon prop', () => {
|
||||
});
|
||||
|
||||
test('should change close icon position when using close-icon-position prop', () => {
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
show: true,
|
||||
closeable: true,
|
||||
@ -104,7 +104,7 @@ test('should change close icon position when using close-icon-position prop', ()
|
||||
});
|
||||
|
||||
test('should hide index when show-index prop is false', async () => {
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
show: true,
|
||||
},
|
||||
@ -116,7 +116,7 @@ test('should hide index when show-index prop is false', async () => {
|
||||
});
|
||||
|
||||
test('should hide ImagePreview after popstate', async () => {
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
images,
|
||||
show: true,
|
||||
@ -128,7 +128,7 @@ test('should hide ImagePreview after popstate', async () => {
|
||||
});
|
||||
|
||||
test('should not hide ImagePreview after popstate when close-on-popstate is false', async () => {
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
images,
|
||||
show: true,
|
||||
@ -141,7 +141,7 @@ test('should not hide ImagePreview after popstate when close-on-popstate is fals
|
||||
});
|
||||
|
||||
test('render image', async () => {
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: { images, show: true },
|
||||
});
|
||||
|
||||
@ -160,7 +160,7 @@ test('render image', async () => {
|
||||
});
|
||||
|
||||
test('before close prop', async () => {
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
images,
|
||||
show: true,
|
||||
@ -180,9 +180,46 @@ test('before close prop', async () => {
|
||||
expect(wrapper.emitted('close')![0]).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should close when overlay is clicked', async () => {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
images,
|
||||
show: true,
|
||||
'onUpdate:show': (show) => {
|
||||
wrapper.setProps({ show });
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const swipe = wrapper.find('.van-swipe-item');
|
||||
|
||||
await triggerDrag(swipe, 0, 0);
|
||||
await later(300);
|
||||
expect(wrapper.emitted('close')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should not close when overlay is clicked and closeOnClickOverlay is false', async () => {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
images,
|
||||
show: true,
|
||||
closeOnClickOverlay: false,
|
||||
'onUpdate:show': (show) => {
|
||||
wrapper.setProps({ show });
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const swipe = wrapper.find('.van-swipe-item');
|
||||
|
||||
triggerDrag(swipe, 0, 0);
|
||||
await later(300);
|
||||
expect(wrapper.emitted('close')).toBeFalsy();
|
||||
});
|
||||
|
||||
test('double click', async () => {
|
||||
const onScale = jest.fn();
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
images,
|
||||
show: true,
|
||||
@ -211,7 +248,7 @@ test('double click', async () => {
|
||||
test('zoom in and drag image to move', async () => {
|
||||
const restore = mockGetBoundingClientRect({ width: 100, height: 100 });
|
||||
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: { images, show: true },
|
||||
});
|
||||
|
||||
@ -240,7 +277,7 @@ test('zoom out', async () => {
|
||||
const restore = mockGetBoundingClientRect({ width: 100, height: 100 });
|
||||
|
||||
const onScale = jest.fn();
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
images,
|
||||
show: true,
|
||||
@ -258,7 +295,7 @@ test('zoom out', async () => {
|
||||
});
|
||||
|
||||
test('should render image slot correctly', async () => {
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
show: true,
|
||||
images,
|
||||
@ -274,7 +311,7 @@ test('should render image slot correctly', async () => {
|
||||
});
|
||||
|
||||
test('should render image slot correctly 2', async () => {
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
show: true,
|
||||
images,
|
||||
@ -292,7 +329,7 @@ test('should render image slot correctly 2', async () => {
|
||||
|
||||
test('should emit long-press event after long press', async () => {
|
||||
const onLongPress = jest.fn();
|
||||
const wrapper = mount(ImagePreviewComponent, {
|
||||
const wrapper = mount(ImagePreview, {
|
||||
props: {
|
||||
images,
|
||||
show: true,
|
||||
|
@ -27,6 +27,7 @@ export type ImagePreviewOptions = {
|
||||
showIndicators?: boolean;
|
||||
closeOnPopstate?: boolean;
|
||||
closeIconPosition?: PopupCloseIconPosition;
|
||||
closeOnClickOverlay?: boolean;
|
||||
onClose?(): void;
|
||||
onScale?(args: { scale: number; index: number }): void;
|
||||
onChange?(index: number): void;
|
||||
|
Loading…
x
Reference in New Issue
Block a user