feat(components): [image-viewer] add progress slot and show-progress props (#19465)

* refactor(components): simplify computed properties in image-viewer

* feat(components): [image-viewer] add progress number

* test(components): remove console logs from image-viewer tests

* feat(components): [image-viewer] update progress display and style

* test(components): update progress selector in image-viewer tests

* feat(components): [image-viewer] add slot support for progress display

* docs(components): [image] add progress content description

* docs(components): update docs

* feat(components): [image] simplify progress slot binding

* docs(components): update

* Update packages/components/image-viewer/__tests__/image-viewer.test.tsx

Co-authored-by: btea <2356281422@qq.com>

* Update docs/en-US/component/image.md

Co-authored-by: btea <2356281422@qq.com>

* docs: update progress version in image documentation

* Update packages/components/image-viewer/src/image-viewer.vue

Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com>

* feat: add showProgress props

* docs: add demo

* docs: update v

* Update docs/en-US/component/image.md

Co-authored-by: btea <2356281422@qq.com>

---------

Co-authored-by: btea <2356281422@qq.com>
Co-authored-by: sea <45450994+warmthsea@users.noreply.github.com>
This commit is contained in:
jiaxiang 2025-01-16 11:44:35 +08:00 committed by GitHub
parent ce5963774c
commit ac42b639ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 81 additions and 26 deletions

View File

@ -100,28 +100,30 @@ image/manually-preview
### Image Slots
| Name | Description |
| ----------- | -------------------------------------------------------- |
| placeholder | custom placeholder content when image hasn't loaded yet. |
| error | custom image load failed content. |
| viewer | custom content when image preview. |
| Name | Description | Type |
| ----------------- | -------------------------------------------------------- | ------------------------------------------------- |
| placeholder | custom placeholder content when image hasn't loaded yet. | - |
| error | custom image load failed content. | - |
| viewer | custom content when image preview. | - |
| progress ^(2.9.4) | custom progress content when image preview. | ^[object]`{ activeIndex: number, total: number }` |
## Image Viewer API
### Image Viewer Attributes
| Name | Description | Type | Default |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------- |
| url-list | preview link list. | ^[object]`string[]` | [] |
| z-index | preview backdrop z-index. | ^[number] / ^[string] | — |
| initial-index | the initial preview image index, less than or equal to the length of `url-list`. | ^[number] | 0 |
| infinite | whether preview is infinite. | ^[boolean] | true |
| hide-on-click-modal | whether user can emit close event when clicking backdrop. | ^[boolean] | false |
| teleported | whether to append image itself to body. A nested parent element attribute transform should have this attribute set to `true`. | ^[boolean] | false |
| zoom-rate ^(2.2.27) | the zoom rate of the image viewer zoom event. | ^[number] | 1.2 |
| min-scale ^(2.4.0) | the min scale of the image viewer zoom event. | ^[number] | 0.2 |
| max-scale ^(2.4.0) | the max scale of the image viewer zoom event. | ^[number] | 7 |
| close-on-press-escape | whether the image-viewer can be closed by pressing ESC. | ^[boolean] | true |
| Name | Description | Type | Default |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------- |
| url-list | preview link list. | ^[object]`string[]` | [] |
| z-index | preview backdrop z-index. | ^[number] / ^[string] | — |
| initial-index | the initial preview image index, less than or equal to the length of `url-list`. | ^[number] | 0 |
| infinite | whether preview is infinite. | ^[boolean] | true |
| hide-on-click-modal | whether user can emit close event when clicking backdrop. | ^[boolean] | false |
| teleported | whether to append image itself to body. A nested parent element attribute transform should have this attribute set to `true`. | ^[boolean] | false |
| zoom-rate ^(2.2.27) | the zoom rate of the image viewer zoom event. | ^[number] | 1.2 |
| min-scale ^(2.4.0) | the min scale of the image viewer zoom event. | ^[number] | 0.2 |
| max-scale ^(2.4.0) | the max scale of the image viewer zoom event. | ^[number] | 7 |
| close-on-press-escape | whether the image-viewer can be closed by pressing ESC. | ^[boolean] | true |
| show-progress ^(2.9.4) | whether to display the preview image progress content | ^[boolean] | false |
### Image Viewer Events

View File

@ -7,6 +7,7 @@
:max-scale="7"
:min-scale="0.2"
:preview-src-list="srcList"
show-progress
:initial-index="4"
fit="cover"
/>

View File

@ -58,4 +58,23 @@ describe('<image-viewer />', () => {
expect(imgList[1].attributes('style')).not.contains('display: none;')
wrapper.unmount()
})
test('image progress render', async () => {
const wrapper = mount(
<ImageViewer
showProgress
urlList={[IMAGE_SUCCESS, IMAGE_SUCCESS]}
initial-index={1}
/>
)
await doubleWait()
const viewer = wrapper.find('.el-image-viewer__wrapper')
expect(viewer.exists()).toBe(true)
await wrapper.find('.el-image-viewer__next').trigger('click')
await doubleWait()
const innerText = wrapper.find('.el-image-viewer__progress').text()
expect(innerText).toBe('1 / 2')
wrapper.unmount()
})
})

View File

@ -78,6 +78,13 @@ export const imageViewerProps = buildProps({
type: Number,
default: 7,
},
/**
* @description show preview image progress content.
*/
showProgress: {
type: Boolean,
default: false,
},
/**
* @description set HTML attribute: crossorigin.
*/

View File

@ -37,6 +37,15 @@
</el-icon>
</span>
</template>
<div v-if="showProgress" :class="[ns.e('btn'), ns.e('progress')]">
<slot
name="progress"
:active-index="activeIndex"
:total="urlList.length"
>
{{ progress }}
</slot>
</div>
<!-- ACTIONS -->
<div :class="[ns.e('btn'), ns.e('actions')]">
<div :class="ns.e('actions__inner')">
@ -160,17 +169,11 @@ const isSingle = computed(() => {
return urlList.length <= 1
})
const isFirst = computed(() => {
return activeIndex.value === 0
})
const isFirst = computed(() => activeIndex.value === 0)
const isLast = computed(() => {
return activeIndex.value === props.urlList.length - 1
})
const isLast = computed(() => activeIndex.value === props.urlList.length - 1)
const currentImg = computed(() => {
return props.urlList[activeIndex.value]
})
const currentImg = computed(() => props.urlList[activeIndex.value])
const arrowPrevKls = computed(() => [
ns.e('btn'),
@ -205,6 +208,10 @@ const imgStyle = computed(() => {
return style
})
const progress = computed(
() => `${activeIndex.value + 1} / ${props.urlList.length}`
)
function hide() {
unregisterEventListener()
emit('close')

View File

@ -104,6 +104,13 @@ export const imageProps = buildProps({
type: Number,
default: 7,
},
/**
* @description show preview image progress content.
*/
showProgress: {
type: Boolean,
default: false,
},
/**
* @description set HTML attribute: crossorigin.
*/

View File

@ -31,6 +31,7 @@
:zoom-rate="zoomRate"
:min-scale="minScale"
:max-scale="maxScale"
:show-progress="showProgress"
:url-list="previewSrcList"
:crossorigin="crossorigin"
:hide-on-click-modal="hideOnClickModal"
@ -42,6 +43,9 @@
<div v-if="$slots.viewer">
<slot name="viewer" />
</div>
<template #progress="scoped">
<slot name="progress" v-bind="scoped" />
</template>
</image-viewer>
</template>
</div>

View File

@ -82,6 +82,14 @@
}
}
@include e(progress) {
left: 50%;
transform: translateX(-50%);
cursor: default;
color: #fff;
bottom: 90px;
}
@include e(prev) {
top: 50%;
transform: translateY(-50%);