feat(Progress): add pivot slot for custom content (#13777)

This commit is contained in:
Gavin
2026-02-18 10:05:42 +04:00
committed by GitHub
parent d8a578d79c
commit 162ab6b14f
7 changed files with 149 additions and 4 deletions
+4 -4
View File
@@ -32,7 +32,7 @@ export default defineComponent({
props: progressProps,
setup(props) {
setup(props, { slots }) {
const background = computed(() =>
props.inactive ? undefined : props.color,
);
@@ -42,9 +42,9 @@ export default defineComponent({
const renderPivot = () => {
const { textColor, pivotText, pivotColor, percentage } = props;
const safePercentage = format(percentage);
const text = pivotText ?? `${percentage}%`;
const text = pivotText ?? `${safePercentage}%`;
if (props.showPivot && text) {
if (props.showPivot && (slots.pivot || text)) {
const style = {
color: textColor,
left: `${safePercentage}%`,
@@ -57,7 +57,7 @@ export default defineComponent({
style={style}
class={bem('pivot', { inactive: props.inactive })}
>
{text}
{slots.pivot ? slots.pivot({ percentage: safePercentage }) : text}
</span>
);
}
+19
View File
@@ -53,6 +53,19 @@ Use `pivot-text` to custom text, use `color` to custom bar color.
/>
```
### Custom Pivot Content
Use `pivot` slot to custom the pivot content.
```html
<van-progress :percentage="50">
<template #pivot="{ percentage }">
<van-icon name="fire" />
<span>{{ percentage }}%</span>
</template>
</van-progress>
```
## API
### Props
@@ -69,6 +82,12 @@ Use `pivot-text` to custom text, use `color` to custom bar color.
| inactive | Whether to be gray | _boolean_ | `false` |
| show-pivot | Whether to show text | _boolean_ | `true` |
### Slots
| Name | Description | SlotProps |
| ----- | -------------------- | ------------------------ |
| pivot | Custom pivot content | _{ percentage: number }_ |
### Types
The component exports the following type definitions:
@@ -57,6 +57,19 @@ app.use(Progress);
/>
```
### 自定义插槽内容
通过 `pivot` 插槽可以自定义进度文字的内容。
```html
<van-progress :percentage="50">
<template #pivot="{ percentage }">
<van-icon name="fire" />
<span>{{ percentage }}%</span>
</template>
</van-progress>
```
## API
### Props
@@ -73,6 +86,12 @@ app.use(Progress);
| inactive | 是否置灰 | _boolean_ | `false` |
| show-pivot | 是否显示进度文字 | _boolean_ | `true` |
### Slots
| 名称 | 说明 | 参数 |
| ----- | -------------- | ------------------------ |
| pivot | 自定义进度文字 | _{ percentage: number }_ |
### 类型定义
组件导出以下类型定义:
+14
View File
@@ -1,6 +1,7 @@
<script setup lang="ts">
import VanProgress from '..';
import VanButton from '../../button';
import VanIcon from '../../icon';
import { ref } from 'vue';
import { useTranslate } from '../../../docs/site';
@@ -8,12 +9,14 @@ const t = useTranslate({
'zh-CN': {
title2: '置灰',
title3: '样式定制',
title4: '进度插槽内容',
strokeWidth: '线条粗细',
transition: '过渡效果',
},
'en-US': {
title2: 'Inactive',
title3: 'Custom Style',
title4: 'Pivot Slot',
strokeWidth: 'Stroke Width',
transition: 'Transition',
},
@@ -54,6 +57,17 @@ const reduce = () => {
/>
</demo-block>
<demo-block :title="t('title4')">
<van-progress :percentage="percentage">
<template #pivot="{ percentage: value }">
<span style="display: inline-flex; align-items: center">
<van-icon name="fire" />
<span style="margin-left: 2px">{{ value }}%</span>
</span>
</template>
</van-progress>
</demo-block>
<demo-block :title="t('transition')">
<van-progress :percentage="percentage" />
<div style="margin-top: 15px">
@@ -110,6 +110,36 @@ exports[`should render demo and match snapshot 1`] = `
</span>
</div>
</div>
<div>
<!--[-->
<div
class="van-progress"
style
>
<span
class="van-progress__portion"
style="width:50%;"
>
</span>
<span
style="left:50%;transform:translate(-50%,-50%);"
class="van-progress__pivot"
>
<!--[-->
<span style="display:inline-flex;align-items:center;">
<i
class="van-badge__wrapper van-icon van-icon-fire"
style
>
<!--[-->
</i>
<span style="margin-left:2px;">
50%
</span>
</span>
</span>
</div>
</div>
<div>
<!--[-->
<div
@@ -90,6 +90,27 @@ exports[`should render demo and match snapshot 1`] = `
</span>
</div>
</div>
<div>
<div class="van-progress">
<span
class="van-progress__portion"
style="width: 50%;"
>
</span>
<span
style="left: 50%; transform: translate(-50%,-50%);"
class="van-progress__pivot"
>
<span style="display: inline-flex; align-items: center;">
<i class="van-badge__wrapper van-icon van-icon-fire">
</i>
<span style="margin-left: 2px;">
50%
</span>
</span>
</span>
</div>
</div>
<div>
<div class="van-progress">
<span
@@ -27,3 +27,45 @@ test('should change track color when using track-color prop', () => {
expect(wrapper.style.background).toEqual('green');
});
test('should render pivot slot with correct percentage', () => {
const wrapper = mount(Progress, {
props: {
percentage: 75,
},
slots: {
pivot: (props: { percentage: number }) =>
`${props.percentage}% completed`,
},
});
expect(wrapper.find('.van-progress__pivot').text()).toEqual('75% completed');
});
test('should render pivot slot instead of pivotText when both provided', () => {
const wrapper = mount(Progress, {
props: {
percentage: 50,
pivotText: 'prop text',
},
slots: {
pivot: () => 'slot content',
},
});
expect(wrapper.find('.van-progress__pivot').text()).toEqual('slot content');
});
test('should not render pivot slot when showPivot is false', () => {
const wrapper = mount(Progress, {
props: {
percentage: 50,
showPivot: false,
},
slots: {
pivot: () => 'slot content',
},
});
expect(wrapper.find('.van-progress__pivot').exists()).toBeFalsy();
});