Feedback · Progress

Progress

Used to display the current progress and status of the user operation, and is generally used when the operation takes a long time. Can also be used to indicate the degree of completion of a task/object

Demos

How to import

<script setup lang="ts">
    import { Progress } from '@fibrous/semi-ui-vue';
</script>

Standard progress bar

Use stroke Property to control the filling color of the progress bar
Use Percent Property to control completed progress
Use size Property control progress bar size
Use aria-label Property to explain the specific role
If the preset size is not satisfied, You can pass height to customize the height of the progress bar through style property.






Code
<script setup lang="ts">
    import { Progress } from '@fibrous/semi-ui-vue';
</script>

<template>
    <div :style="{ width: '200px' }">
        <Progress aria-label="disk usage" :percent="10" stroke="var(--semi-color-warning)" />
        <br />
        <Progress aria-label="disk usage" :percent="25" stroke="var(--semi-color-danger)" />
        <br />
        <Progress aria-label="disk usage" :percent="50" />
        <br />
        <Progress aria-label="download progress" :percent="80" />
        <br />
        <Progress aria-label="disk usage" :percent="80" size="large" />
        <br />
        <Progress aria-label="disk usage" :percent="80" :style="{ height: '8px' }" />
    </div>
</template>

Indeterminate progress bar

Set indeterminate when progress cannot be calculated. It supports both line and circle progress bars. When enabled, percent no longer controls the progress length and showInfo text is hidden.


Code
<script setup lang="ts">
    import { Progress } from '@fibrous/semi-ui-vue';
</script>

<template>
    <div :style="{ width: '240px' }">
        <Progress aria-label="正在加载" indeterminate />
        <br />
        <Progress aria-label="正在加载" indeterminate size="large" />
        <div :style="{ display: 'flex', alignItems: 'center', gap: '16px', marginTop: '20px' }">
            <Progress aria-label="正在加载" indeterminate type="circle" />
            <Progress aria-label="正在加载" indeterminate size="small" type="circle" />
        </div>
    </div>
</template>

Show percentage text

You can control whether to show percentage number through the showInfo property In addition, you can format the percentage text show through the #format slot.

10%

25%

50%

500‰
Code
<script setup lang="ts">
    import { Progress } from '@fibrous/semi-ui-vue';
</script>

<template>
    <div :style="{ width: '200px' }">
        <Progress aria-label="disk usage" :percent="10" showInfo stroke="var(--semi-color-warning)" />
        <br />
        <Progress aria-label="disk usage" :percent="25" showInfo stroke="var(--semi-color-danger)" />
        <br />
        <Progress aria-label="disk usage" :percent="50" showInfo />
        <br />
        <Progress aria-label="disk usage" :percent="50" showInfo>
            <template #format="{ percent }">{{ percent * 10 }}‰</template>
        </Progress>
    </div>
</template>

Vertical progress bar

You can use vertical progress bar by setting direction='vertical' If preset width is not satisfied, you can pass width to customize the width of the vertical progress bar through style property.

Code
<script setup lang="ts">
    import { Progress } from '@fibrous/semi-ui-vue';
</script>

<template>
    <div :style="{ height: '100px', display: 'flex' }">
        <Progress aria-label="disk usage" direction="vertical" :percent="10" />
        <Progress aria-label="disk usage" direction="vertical" :percent="25" />
        <Progress aria-label="disk usage" direction="vertical" :percent="50" />
        <Progress aria-label="disk usage" direction="vertical" :percent="80" size="large" />
        <Progress aria-label="disk usage" direction="vertical" :percent="80" :style="{ width: '8px' }" />
    </div>
</template>

Circular progress bar

Set type tocircle, the progress bar will be displayed in a ring shape. The default size of the progress bar is 72 x 72

Code
<script setup lang="ts">
    import { Progress } from '@fibrous/semi-ui-vue';
</script>

<template>
    <div>
        <Progress aria-label="disk usage" :percent="10" :style="{ margin: '5px' }" type="circle" />
        <Progress aria-label="disk usage" :percent="25" :style="{ margin: '5px' }" type="circle" />
        <Progress aria-label="disk usage" :percent="50" :style="{ margin: '5px' }" type="circle" />
        <Progress aria-label="disk usage" :percent="80" :style="{ margin: '5px' }" type="circle" />
    </div>
</template>

You can modify it's width to control the size of the circular progress bar.

Code
<script setup lang="ts">
    import { Progress } from '@fibrous/semi-ui-vue';
</script>

<template>
    <div>
        <Progress aria-label="disk usage" :percent="100" :style="{ margin: '5px' }" type="circle" :width="100" />
    </div>
    <div>
        <Progress aria-label="disk usage" :percent="100" stroke="var(--semi-color-danger)" :style="{ margin: '5px' }" type="circle" :width="100" />
    </div>
</template>

Small circular progress bar

Small progress bar default size is 24 x 24.

Code
<script setup lang="ts">
    import { Progress } from '@fibrous/semi-ui-vue';
</script>

<template>
    <Progress aria-label="disk usage" :percent="10" size="small" :style="{ margin: '5px' }" type="circle" />
    <Progress aria-label="disk usage" :percent="25" size="small" :style="{ margin: '5px' }" type="circle" />
    <Progress aria-label="disk usage" :percent="50" size="small" :style="{ margin: '5px' }" type="circle" />
    <Progress aria-label="disk usage" :percent="80" size="small" :style="{ margin: '5px' }" type="circle" />
</template>

Dynamic change percent

The number in the text animates to the new percent. When percent changes again while the animation is running, the new animation starts from the number currently shown.

40%
Code
<script setup lang="ts">
    import { ref } from 'vue';
    import { IconChevronLeft, IconChevronRight } from '@fibrous/semi-icons-vue';
    import { Button, Progress } from '@fibrous/semi-ui-vue';

    const percent = ref(40);
</script>

<template>
    <div>
        <Progress aria-label="disk usage" :percent="percent" showInfo />
        <Button aria-label="减少" :disabled="percent === 0" theme="light" @click="percent -= 10">
            <template #icon>
                <IconChevronLeft />
            </template>
        </Button>
        <Button aria-label="增加" :disabled="percent >= 100" theme="light" @click="percent += 10">
            <template #icon>
                <IconChevronRight />
            </template>
        </Button>
    </div>
</template>
Code
<script setup lang="ts">
    import { ref } from 'vue';
    import { IconChevronLeft, IconChevronRight } from '@fibrous/semi-icons-vue';
    import { Button, Progress } from '@fibrous/semi-ui-vue';

    const cirPerc = ref(40);
</script>

<template>
    <div>
        <div>
            <Progress aria-label="disk usage" :percent="cirPerc" type="circle" />
        </div>
        <Button aria-label="减少" :disabled="cirPerc === 0" theme="light" @click="cirPerc -= 10">
            <template #icon>
                <IconChevronLeft />
            </template>
        </Button>
        <Button aria-label="增加" :disabled="cirPerc >= 100" theme="light" @click="cirPerc += 10">
            <template #icon>
                <IconChevronRight />
            </template>
        </Button>
    </div>
</template>

Custom central text content

You can customize the central text with the #format="{ percent }" slot, where percent is the percentage currently shown. The slot runs only when the text is shown
If you don't need central text content, you can set showInfo to false or render nothing in the slot

75Days
Done
Code
<script setup lang="ts">
    import { Progress } from '@fibrous/semi-ui-vue';
</script>

<template>
    <Progress aria-label="disk usage" :percent="75" showInfo :style="{ margin: '10px' }" type="circle">
        <template #format="{ percent }">{{ percent }}Days</template>
    </Progress>
    <Progress aria-label="disk usage" :percent="100" showInfo :style="{ margin: '10px' }" type="circle">
        <template #format>Done</template>
    </Progress>
    <Progress aria-label="disk usage" :percent="50" :showInfo="false" :style="{ margin: '10px' }" type="circle" />
</template>

Round / square edges

With the strokeLinecap property, you can control the edge shape of the ring progress bar.

Code
<script setup lang="ts">
    import { Progress } from '@fibrous/semi-ui-vue';
</script>

<template>
    <Progress aria-label="disk usage" :percent="50" strokeLinecap="round" :style="{ margin: '10px' }" type="circle" />
    <Progress aria-label="disk usage" :percent="50" strokeLinecap="square" :style="{ margin: '10px' }" type="circle" />
</template>

Customise the progress bar color

The color of a specific percent can be customised by setting the stroke property

10%
10%
Code
<script setup lang="ts">
    import { ref } from 'vue';
    import { IconChevronLeft, IconChevronRight } from '@fibrous/semi-icons-vue';
    import { Button, Progress } from '@fibrous/semi-ui-vue';

    const percent = ref(10);
    const strokeArr = [
        { percent: 20, color: 'red' },
        { percent: 40, color: 'orange-9' },
        { percent: 60, color: 'light-green-8' },
        { percent: 80, color: 'hsla(125, 50%, 46%, 1)' },
    ];
</script>

<template>
    <div>
        <Progress aria-label="disk usage" :percent="percent" showInfo :stroke="strokeArr" type="circle" :width="100" />
        <Progress aria-label="disk usage" :percent="percent" showInfo :stroke="strokeArr" :style="{ margin: '20px 0 10px' }" />
    </div>
    <Button aria-label="Decrease" :disabled="percent === 0" theme="light" @click="percent -= 10">
        <template #icon>
            <IconChevronLeft />
        </template>
    </Button>
    <Button aria-label="Increase" :disabled="percent === 100" theme="light" @click="percent += 10">
        <template #icon>
            <IconChevronRight />
        </template>
    </Button>
</template>

Auto-completion of colour intervals

The gradient can be generated by setting the strokeGradient property to true, automatically fill the colour interval.

0%
0%
65%
Code
<script setup lang="ts">
    import { ref, watchEffect } from 'vue';
    import { IconChevronLeft, IconChevronRight } from '@fibrous/semi-icons-vue';
    import { Button, Progress, Space } from '@fibrous/semi-ui-vue';

    const percent = ref(65);
    const percentInterval = ref(0);
    const strokeArr = [
        { percent: 0, color: 'rgb(249, 57, 32)' },
        { percent: 50, color: '#46259E' },
        { percent: 100, color: 'hsla(125, 50%, 46%, 1)' },
    ];
    const strokeArrReverse = [
        { percent: 0, color: 'hsla(125, 50%, 46%, 1)' },
        { percent: 50, color: '#46259E' },
        { percent: 100, color: 'rgb(249, 57, 32)' },
    ];

    // Each value schedules the next one; restarting after 100 pauses longer.
    watchEffect((onCleanup) => {
        const current = percentInterval.value;
        const timer = setTimeout(
            () => {
                percentInterval.value = current > 100 ? 0 : current + 3;
            },
            current === 0 || current > 100 ? 1200 : 290 - (current % 50) * 3
        );
        onCleanup(() => clearTimeout(timer));
    });
</script>

<template>
    <Space :spacing="20">
        <div>
            <Progress aria-label="file download speed" :percent="percentInterval" showInfo :stroke="strokeArr" strokeGradient type="circle" :width="100" />
        </div>
        <div>
            <Progress aria-label="file download speed" :percent="percentInterval" showInfo :stroke="strokeArrReverse" strokeGradient type="circle" :width="100" />
        </div>
    </Space>
    <div :style="{ width: '100%', margin: '20px 0 10px' }">
        <Progress aria-label="file download speed" :percent="percent" showInfo size="large" :stroke="strokeArr" strokeGradient />
    </div>
    <Button aria-label="Decrease" :disabled="percent === 0" theme="light" @click="percent -= 5">
        <template #icon>
            <IconChevronLeft />
        </template>
    </Button>
    <Button aria-label="Increase" :disabled="percent === 100" theme="light" @click="percent += 5">
        <template #icon>
            <IconChevronRight />
        </template>
    </Button>
</template>

API Reference

Props

PropertyDescriptionTypeDefault
directionDirection of the line progress bar: horizontal or vertical.ProgressDirectionsemiDefault("Progress", "direction", "horizontal")
indeterminateWhether the progress is indeterminate. When on, percent no longer controls the length, the text is hidden and aria-valuenow is omitted.booleansemiDefault("Progress", "indeterminate", false)
motionWhether the shown number animates to the new percent. When off it jumps to the target.booleansemiDefault("Progress", "motion", true)
orbitStrokeFill color of the track.stringsemiGlobalDefault("Progress", "orbitStroke")
percentProgress percentage. Passing NaN throws an error.numbersemiDefault("Progress", "percent", 0)
showInfoWhether to show the text: in the center of a circle, or on the right of a bar.booleansemiDefault("Progress", "showInfo", false)
sizeSize: default, small (circle only) or large (line only).SizesemiDefault("Progress", "size", "default")
strokeFill color. An array is a list of { percent, color } intervals, where color is any CSS color or a Semi palette name.string | StrokeArrsemiGlobalDefault("Progress", "stroke")
strokeGradientWhether to generate gradient colors between intervals. Requires at least one interval in stroke.booleansemiDefault("Progress", "strokeGradient", false)
strokeLinecapLine cap of the circle progress bar: round or square."round" | "square"semiDefault("Progress", "strokeLinecap", "round")
strokeWidthStroke width of the circle progress bar.numbersemiDefault("Progress", "strokeWidth", 4)
typeType: line or circle.ProgressTypesemiDefault("Progress", "type", "line")
widthDiameter of the circle progress bar. Defaults to 24 when size is small and 72 otherwise.numbersemiGlobalDefault("Progress", "width")

Events

EventDescriptionCallback parameters
None

Slots

SlotDescriptionScope parameters
formatCustom text. percent is the shown number clamped to 0-100. It runs only when the text is shown.{ percent: number; }

Exposes

NameDescriptionType
None

class, style and native attributes (id, aria-label, aria-labelledby, aria-valuetext and so on) are passed through attrs to the root element.

Accessibility

ARIA

  • Progress has a progressbar role to indicate that it is a progress bar component.
  • Progress will automatically set aria-valuenow as the progress percentage (percent) passed to the component to ensure that the screen reader can get the correct percentage value. When indeterminate=true, aria-valuenow is omitted because the current progress value is unknown. In addition, Progress supports incoming aria-valuetext. When you pass in, according to W3C specifications, aria-valuetext will be used and consumed by screen readers instead of aria-valuenow
  • Progress support aria-label, aria-labelledby
    • When there is a description element about the role of Progress outside of Progress, you can explicitly specify that the id of certain elements is the label of Progress through aria-labelledby
    • Otherwise, you should use aria-label to explain the specific meaning of the value represented by Progress
<template>
    <!-- good case -->
    <p id="progressbar-label">Disk Usage</p>
    <Progress aria-labelledby="progressbar-label" :percent="80" />

    <!-- good case -->
    <Progress aria-label="Percent of disk usage" :percent="80" />
    <Progress aria-label="Percent of file downloaded" :percent="80" />

    <!-- usage of aria-valuetext -->
    <Progress aria-label="Percent of disk usage" :percent="80" aria-valuetext="Step 2: Copying files... " />
</template>

Content Guidelines

  • If the progress bar process is complicated, or there is a long waiting time, you can use the help text to explain. This lets the user know what progress is happening.

Design Tokens

These are the component's internal Sass variables and cannot be overridden. To customize styles, override the --semi-* CSS variables (see the Design Token page) or write unlayered CSS rules.
Sass variableValueUsage
$color-progress_default-bgvar(--semi-color-fill-0)默认背景色
$color-progress_track_inner-bgvar(--semi-color-success)默认进度色
$color-progress_line_text-textvar(--semi-color-text-0)百分比文本文字颜色
$color-progress_circle-textvar(--semi-color-text-0)环形进度百分比文字颜色
$motion-progress-transition_duration0.3s进度条动画时长
$motion-progress-transition_timing_functioncubic-bezier(0.62, 0.05, 0.36, 0.95)进度条动画曲线
$height-progress_horizontal4px水平进度条高度
$height-progress_horizontal_large6px大尺寸水平进度条高度
$spacing-progress_line_text-marginLeft$spacing-base水平进度条百分比文本左侧外边距
$spacing-progress_vertical-marginX$spacing-extra-tight垂直进度条水平方向外边距
$spacing-progress_horizontal-marginY$spacing-extra-tight水平进度条垂直方向外边距
$spacing-progress_vertical_line_text-marginTop$spacing-tight垂直进度条百分比文本顶部外边距
$font-progress_line_text-fontWeight600百分比文本字重
$width-progress_line_text45px百分比文本最小宽度
$width-progress_vertical4px垂直进度条宽度
$width-progress_vertical_large6px大尺寸垂直进度条宽度
$radius-progress_trackvar(--semi-border-radius-small)背景圆角大小
$radius-progress_track_innervar(--semi-border-radius-small)进度条圆角大小