Compare commits

...

2 Commits

Author SHA1 Message Date
inottn
5603aa22e8
feat(ImagePreview): add close-on-click-image prop (#12566) 2024-01-13 21:12:37 +08:00
neverland
e6dd92eed7
chore(deps): bump Rsbuild to v0.3.2 (#12565) 2024-01-13 11:32:25 +08:00
10 changed files with 1002 additions and 809 deletions

View File

@ -19,7 +19,7 @@
"engines": {
"pnpm": ">= 8.8.0"
},
"packageManager": "pnpm@8.8.0",
"packageManager": "pnpm@8.14.1",
"devDependencies": {
"@vant/cli": "workspace:*",
"@vant/eslint-config": "workspace:*",
@ -27,10 +27,5 @@
"husky": "^8.0.1",
"nano-staged": "^0.8.0",
"prettier": "^3.0.0"
},
"pnpm": {
"overrides": {
"@rspack/core": "0.4.3"
}
}
}

View File

@ -48,10 +48,10 @@
"dependencies": {
"@babel/core": "^7.23.2",
"@babel/preset-typescript": "^7.23.2",
"@rsbuild/core": "0.2.10",
"@rsbuild/plugin-babel": "0.2.10",
"@rsbuild/plugin-vue": "0.2.10",
"@rsbuild/plugin-vue-jsx": "0.2.10",
"@rsbuild/core": "0.3.2",
"@rsbuild/plugin-babel": "0.3.2",
"@rsbuild/plugin-vue": "0.3.2",
"@rsbuild/plugin-vue-jsx": "0.3.2",
"@vant/eslint-config": "workspace:^",
"@vant/touch-emulator": "workspace:^",
"@vitejs/plugin-vue": "^4.5.2",

View File

@ -73,6 +73,7 @@ export const imagePreviewProps = {
startPosition: makeNumericProp(0),
showIndicators: Boolean,
closeOnPopstate: truthProp,
closeOnClickImage: truthProp,
closeOnClickOverlay: truthProp,
closeIconPosition: makeStringProp<PopupCloseIconPosition>('top-right'),
teleport: [String, Object] as PropType<TeleportProps['to']>,
@ -185,6 +186,7 @@ export default defineComponent({
rootHeight={state.rootHeight}
disableZoom={state.disableZoom}
doubleScale={props.doubleScale}
closeOnClickImage={props.closeOnClickImage}
closeOnClickOverlay={props.closeOnClickOverlay}
onScale={emitScale}
onClose={emitClose}

View File

@ -54,6 +54,7 @@ const imagePreviewItemProps = {
rootHeight: makeRequiredProp(Number),
disableZoom: Boolean,
doubleScale: Boolean,
closeOnClickImage: Boolean,
closeOnClickOverlay: Boolean,
};
@ -251,8 +252,12 @@ export default defineComponent({
};
const checkClose = (event: TouchEvent) => {
const isClickOverlay = event.target === swipeItem.value?.$el;
const swipeItemEl: HTMLElement = swipeItem.value?.$el;
const imageEl = swipeItemEl.firstElementChild;
const isClickOverlay = event.target === swipeItemEl;
const isClickImage = imageEl?.contains(event.target as HTMLElement);
if (!props.closeOnClickImage && isClickImage) return;
if (!props.closeOnClickOverlay && isClickOverlay) return;
emit('close');

View File

@ -150,10 +150,14 @@ export default {
### Use image slot
When using ImagePreview component, you can custom the image through the `image` slot, such as render a video content.
When using ImagePreview component, you can custom the image through the `image` slot, such as render a video content. In this example, you can also set `close-on-click-image` prop to `false`, so that the preview won't be accidentally closed when you click on the video.
```html
<van-image-preview v-model:show="show" :images="images">
<van-image-preview
v-model:show="show"
:images="images"
:close-on-click-image="false"
>
<template #image="{ src }">
<video style="width: 100%;" controls>
<source :src="src" />
@ -206,6 +210,7 @@ Vant exports following ImagePreview utility functions:
| onScale | Emitted when scaling current image | _Function_ | - |
| closeOnPopstate | Whether to close when popstate | _boolean_ | `true` |
| doubleScale `v4.7.2` | Whether to enable double tap zoom gesture. When disabled, the image preview will be closed immediately upon clicking | _boolean_ | `true` |
| closeOnClickImage `v4.8.3` | Whether to close when image is clicked | _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_ | - |
@ -233,6 +238,7 @@ Vant exports following ImagePreview utility functions:
| double-scale | Whether to enable double tap zoom gesture. When disabled, the image preview will be closed immediately upon clicking | _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-image `v4.8.3` | Whether to close when image is clicked | _boolean_ | `true` |
| close-on-click-overlay `v4.6.4` | Whether to close when overlay is clicked | _boolean_ | `true` |
| class-name | Custom className (apply to Popup in image preview) | _string \| Array \| object_ | - |
| max-zoom | Max zoom | _number \| string_ | `3` |

View File

@ -151,10 +151,14 @@ export default {
### 使用 image 插槽
当以组件调用的方式使用 ImagePreview 时,可以通过 `image` 插槽来插入自定义的内容,比如展示一个视频内容。
当以组件调用的方式使用 ImagePreview 时,可以通过 `image` 插槽来插入自定义的内容,比如展示一个视频内容。在这个例子中,你可以将 `close-on-click-image` 属性设置为 `false`,这样当你点击视频时就不会意外关闭预览了。
```html
<van-image-preview v-model:show="show" :images="images">
<van-image-preview
v-model:show="show"
:images="images"
:close-on-click-image="false"
>
<template #image="{ src }">
<video style="width: 100%;" controls>
<source :src="src" />
@ -210,6 +214,7 @@ Vant 中导出了以下 ImagePreview 相关的辅助函数:
| onScale | 缩放图片时的回调函数,回调参数为当前索引和当前缩放值组成的对象 | _Function_ | - |
| beforeClose | 关闭前的回调函数,返回 `false` 可阻止关闭,支持返回 Promise | _(active: number) => boolean \| Promise\<boolean\>_ | - |
| closeOnPopstate | 是否在页面回退时自动关闭 | _boolean_ | `true` |
| closeOnClickImage `v4.8.3` | 是否在点击图片后关闭图片预览 | _boolean_ | `true` |
| closeOnClickOverlay `v4.6.4` | 是否在点击遮罩层后关闭图片预览 | _boolean_ | `true` |
| className | 自定义类名 (应用在图片预览的弹出层) | _string \| Array \| object_ | - |
| maxZoom | 手势缩放时,最大缩放比例 | _number \| string_ | `3` |
@ -238,6 +243,7 @@ Vant 中导出了以下 ImagePreview 相关的辅助函数:
| double-scale `v4.7.2` | 是否启用双击缩放手势,禁用后,点击时会立即关闭图片预览 | _boolean_ | `true` |
| before-close | 关闭前的回调函数,返回 `false` 可阻止关闭,支持返回 Promise | _(active: number) => boolean \| Promise\<boolean\>_ | - |
| close-on-popstate | 是否在页面回退时自动关闭 | _boolean_ | `true` |
| close-on-click-image `v4.8.3` | 是否在点击图片后关闭图片预览 | _boolean_ | `true` |
| close-on-click-overlay `v4.6.4` | 是否在点击遮罩层后关闭图片预览 | _boolean_ | `true` |
| class-name | 自定义类名 | _string \| Array \| object_ | - |
| max-zoom | 手势缩放时,最大缩放比例 | _number \| string_ | `3` |

View File

@ -134,7 +134,11 @@ const showFunctionCall = (options: Partial<ImagePreviewOptions> = {}) => {
:title="t('useImageSlot')"
@click="showComponentCallSlot"
/>
<van-image-preview v-model:show="showSlot" :images="imagesSlot">
<van-image-preview
v-model:show="showSlot"
:images="imagesSlot"
:close-on-click-image="false"
>
<template #image="{ src }">
<video style="width: 100%" controls>
<source :src="src" />

View File

@ -181,6 +181,25 @@ test('before close prop', async () => {
expect(wrapper.emitted('close')![0]).toBeTruthy();
});
test('should close when image is clicked', async () => {
const wrapper = mount(ImagePreview, {
props: {
images,
show: true,
'onUpdate:show': (show) => {
wrapper.setProps({ show });
},
},
});
await later();
const image = wrapper.find('.van-image');
await triggerDrag(image, 0, 0);
await later(300);
expect(wrapper.emitted('close')).toBeTruthy();
});
test('should close when overlay is clicked', async () => {
const wrapper = mount(ImagePreview, {
props: {
@ -199,6 +218,26 @@ test('should close when overlay is clicked', async () => {
expect(wrapper.emitted('close')).toBeTruthy();
});
test('should not close when image is clicked and closeOnClickImage is false', async () => {
const wrapper = mount(ImagePreview, {
props: {
images,
show: true,
closeOnClickImage: false,
'onUpdate:show': (show) => {
wrapper.setProps({ show });
},
},
});
await later();
const image = wrapper.find('.van-image');
triggerDrag(image, 0, 0);
await later(300);
expect(wrapper.emitted('close')).toBeFalsy();
});
test('should not close when overlay is clicked and closeOnClickOverlay is false', async () => {
const wrapper = mount(ImagePreview, {
props: {

View File

@ -29,6 +29,7 @@ export type ImagePreviewOptions = {
showIndicators?: boolean;
closeOnPopstate?: boolean;
closeIconPosition?: PopupCloseIconPosition;
closeOnClickImage?: boolean;
closeOnClickOverlay?: boolean;
onClose?(): void;
onScale?(args: { scale: number; index: number }): void;

1721
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff