Demos
How to import
<script setup lang="ts">
import { Steps } from '@fibrous/semi-ui-vue';
</script>
Steps.Step can also be imported by name as Step. The title, description and icon of a Step are slots (#title, #description, #icon). Steps only recognizes Steps.Step elements that are its direct children; any other child is not rendered, takes no step number, and logs a warning in development. A Step renders nothing outside Steps.
Default step bar(Deprecated)
It is recommended to use the simple version of steps, which will be gradually deprecated later
Code
<script setup lang="ts">
import { Steps } from '@fibrous/semi-ui-vue';
const log = (i: number) => console.log(i);
</script>
<template>
<Steps :current="1" @change="log">
<Steps.Step>
<template #title>Finished</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>In Progress</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>Waiting</template>
<template #description>This is a description</template>
</Steps.Step>
</Steps>
</template>Basic Steps(Recommended)
Set type="basic" to display a simple style step bar
Code
<script setup lang="ts">
import { Steps } from '@fibrous/semi-ui-vue';
const log = (i: number) => console.log(i);
</script>
<template>
<Steps :current="1" type="basic" @change="log">
<Steps.Step>
<template #title>Finished</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>In Progress</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>Waiting</template>
<template #description>This is a description</template>
</Steps.Step>
</Steps>
</template>Nav Steps
You can use type="nav" to set the navigation style step bar. The navigation style step bar has the following characteristics:
-
The step bar supports interaction as well: when Steps listens for step changes or a Step has a click handler, steps are focusable and clickable, the same as the other types.
-
It is suitable when the steps are not related to each other, the content does not affect each other, and the visual elements of the page need to be highlighted.
-
The width of the step bar is opened according to the content.
-
Steps.Step only renders the title;
description,iconandstatushave no effect. The other attributes and events (aria-label,role, click and keyboard handlers, class name and style, etc.) work as in the other types.
Mini size step bar
Display the mini size step bar by setting size="small"
Code
<script setup lang="ts">
import { Steps } from '@fibrous/semi-ui-vue';
const log = (i: number) => console.log(i);
</script>
<template>
<Steps :current="1" size="small" type="basic" @change="log">
<Steps.Step>
<template #title>Finished</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>In Progress</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>Waiting</template>
<template #description>This is a description</template>
</Steps.Step>
</Steps>
</template>Processing progress
Use with content and buttons to represent the processing progress of a process
Code
<script setup lang="ts">
import { ref } from 'vue';
import { Button, Steps } from '@fibrous/semi-ui-vue';
const steps = [
{ title: 'First', content: 'First-content' },
{ title: 'Second', content: 'Second-content' },
{ title: 'Last', content: 'Last-content' },
];
const current = ref(0);
const log = (i: number) => console.log(i);
const done = () => console.log('Processing complete!');
</script>
<template>
<div>
<Steps :current="current" type="basic" @change="log">
<Steps.Step v-for="item in steps" :key="item.title">
<template #title>{{ item.title }}</template>
</Steps.Step>
</Steps>
<div class="steps-content" :style="{ marginTop: '4px', marginBottom: '4px' }">
{{ steps[current].content }}
</div>
<div class="steps-action">
<Button v-if="current < steps.length - 1" type="primary" @click="current += 1">Next</Button>
<Button v-if="current === steps.length - 1" type="primary" @click="done">Done</Button>
<Button v-if="current > 0" :style="{ marginLeft: '8px' }" @click="current -= 1">Previous</Button>
</div>
</div>
</template>Steps bar in vertical direction
Show steps in vertical direction by setting direction
Code
<script setup lang="ts">
import { Steps } from '@fibrous/semi-ui-vue';
const log = (i: number) => console.log(i);
</script>
<template>
<Steps :current="1" direction="vertical" :style="{ width: '300px' }" @change="log">
<Steps.Step>
<template #title>Finished</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>In Progress</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>Waiting</template>
<template #description>This is a description</template>
</Steps.Step>
</Steps>
</template>Code
<script setup lang="ts">
import { Steps } from '@fibrous/semi-ui-vue';
const log = (i: number) => console.log(i);
</script>
<template>
<Steps :current="1" direction="vertical" type="basic" @change="log">
<Steps.Step>
<template #title>Finished</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>In Progress</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>Waiting</template>
<template #description>This is a description</template>
</Steps.Step>
</Steps>
</template>Specify step status
Using Steps status Property to specify the state of the current step.
Code
<script setup lang="ts">
import { Steps } from '@fibrous/semi-ui-vue';
const log = (i: number) => console.log(i);
</script>
<template>
<Steps :current="1" status="error" type="basic" @change="log">
<Steps.Step>
<template #title>Finished</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>In Process</template>
<template #description>This is a description</template>
</Steps.Step>
<Steps.Step>
<template #title>Waiting</template>
<template #description>This is a description</template>
</Steps.Step>
</Steps>
</template>Custom icons
Use the #icon slot of Steps.Step to show a custom icon; when the slot is present but its content is empty, no icon is shown.
By setting Steps.Step's status property, you can customize the status of each step.
Code
<script setup lang="ts">
import { IconHome, IconLock } from '@fibrous/semi-icons-vue';
import { Steps } from '@fibrous/semi-ui-vue';
const log = (i: number) => console.log(i);
</script>
<template>
<Steps type="basic" @change="log">
<Steps.Step status="finish">
<template #title>已完成</template>
</Steps.Step>
<Steps.Step status="error">
<template #title>错误</template>
</Steps.Step>
<Steps.Step status="warning">
<template #title>警告</template>
</Steps.Step>
<Steps.Step status="process">
<template #title>正在进行</template>
<template #icon>
<IconHome size="extra-large" />
</template>
</Steps.Step>
<Steps.Step status="wait">
<template #title>等待</template>
<template #icon>
<IconLock size="extra-large" />
</template>
</Steps.Step>
</Steps>
</template>onChange CallBack
Listen for step changes with @change (onChange of Steps is a function prop, and whether it is bound decides if the steps are clickable). The callback receives a number, equal to initial plus the index of the selected step; it is not called when the current step is clicked. current also supports v-model:current, and binding it makes every step clickable as well.
Code
<script setup lang="ts">
import { ref } from 'vue';
import { Steps } from '@fibrous/semi-ui-vue';
const steps = [{ title: 'First' }, { title: 'Second' }, { title: 'Last' }];
const current = ref(1);
</script>
<template>
<div>
<Steps v-model:current="current" type="basic">
<Steps.Step v-for="item in steps" :key="item.title">
<template #title>{{ item.title }}</template>
</Steps.Step>
</Steps>
</div>
</template>Accessibility
ARIA
- Steps and Step components support
aria-labeloraria-labelledby. The Steps root and a Step that is not clickable have no semantic role of their own, so when a name is passed they getrole="group"and the name reaches the accessible name; without a name noroleis added. The fill, basic and nav types behave the same - The current step has
aria-current="step"; other steps do not - When Steps listens for step changes or a Step has a click handler, steps are focusable with Tab and their
roledefaults tobutton(taking precedence overgroup; an explicitrolewins over both).Enteror Space on a focused step acts like a mouse click and runs both the Step's click handler and the change callback of Steps; steps that are not clickable are not focusable - A click that comes from another focusable element inside the step (
input,button, a link, and so on) runs only the Step's click handler, not the change callback of Steps. A clickable step is itselfrole="button", so a focusable control in the title or description is a nested interactive element; do not make such a step clickable
API reference
Steps
The whole step bar.
Props
| Property | Description | Type | Default |
|---|---|---|---|
| type | Steps type: fill, basic or nav. | StepsType | semiDefault("Steps", "type", "fill") |
| current | Current step, counting from 0; a child Step can override the state with status. | number | semiDefault("Steps", "current", 0) |
| initial | Starting index, counting from 0. | number | semiDefault("Steps", "initial", 0) |
| direction | Direction: horizontal or vertical. | StepsDirection | semiDefault("Steps", "direction", "horizontal") |
| status | State of the current step: wait, process, finish, error or warning. | StepStatus | semiDefault("Steps", "status", "process") |
| size | Size of the basic and nav types: default or small. | StepsSize | semiDefault("Steps", "size", "default") |
| hasLine | Whether the basic type shows connecting lines. | boolean | semiDefault("Steps", "hasLine", true) |
| prefixCls | Class name prefix of the root element. | string | semiDefault("Steps", "prefixCls", stepsClasses.PREFIX) |
| onChange | Called when a step is selected by click or keyboard, with its number (initial plus index); not called for the current step. It is a function prop, bound with @change as usual; passing it makes every Step clickable. | Type((current: number) => void) | undefined |
| onUpdate:current | Update function bound by v-model:current, behaving like onChange. | Type((current: number) => void) | undefined |
Events
| Event | Description | Callback parameters |
|---|---|---|
| None |
Slots
| Slot | Description | Scope parameters |
|---|---|---|
| default | Steps.Step children; every element or component takes one step position in order, whitespace and text excepted, and a component that wraps Step is numbered too. | any |
Exposes
| Name | Description | Type |
|---|---|---|
| None |
class, style and native attributes are passed through attrs and land on the root element of Steps.
Steps.Step
Step in the step bar.
Props
| Property | Description | Type | Default |
|---|---|---|---|
| status | Own status of the step; when omitted it follows current and status of Steps. | StepStatus | undefined |
Events
| Event | Description | Callback parameters |
|---|---|---|
| None |
Slots
| Slot | Description | Scope parameters |
|---|---|---|
| title | Title. | any |
| description | Description; not rendered by the nav type. | any |
| icon | Custom icon that replaces the status icon; empty content shows no icon. Not rendered by the nav type. | any |
Exposes
| Name | Description | Type |
|---|---|---|
| None |
class, style, aria-*, role, tabindex and native attributes and events such as @click and @keydown are passed through attrs and land on the root element of the Step. A @click from the caller makes that Step clickable; onChange of Steps runs before the Step's own @click. tabindex can be overridden by the caller.
Content Guidelines
- Step title
- title should be kept concise, avoiding truncation and line breaks
- use sentence capitalization
- do not include punctuation
- Step description
- supplementary contextual information for the title
- don't end with punctuation
Design Tokens
| Sass variable | Value | Usage |
|---|---|---|
| $transition_duration-steps_item_title-text | var(--semi-transition_duration-none) | 步骤条标题文字-背景色-动画持续时间 |
| $transition_function-steps_item_title-text | var(--semi-transition_function-easeIn) | 步骤条标题文字-背景色-过渡曲线 |
| $transition_delay-steps_item_title-text | var(--semi-transition_delay-none) | 步骤条标题文字-背景色-延迟时间 |
| $transition_duration-steps_item_title-icon | var(--semi-transition_duration-none) | 步骤条标题文字-背景色-动画持续时间 |
| $transition_function-steps_item_title-icon | var(--semi-transition_function-easeIn) | 步骤条标题文字-背景色-过渡曲线 |
| $transition_delay-steps_item_title-icon | var(--semi-transition_delay-none) | 步骤条标题文字-背景色-延迟时间 |
| $transition_duration-steps_item_backgroundColor | var(--semi-transition_duration-none) | 步骤条标题文字-背景色-动画持续时间 |
| $transition_function-steps_item_backgroundColor | var(--semi-transition_function-easeIn) | 步骤条标题文字-背景色-过渡曲线 |
| $transition_delay-steps_item_backgroundColor | var(--semi-transition_delay-none) | 步骤条标题文字-背景色-延迟时间 |
| $transform_scale-step-item | var(--semi-transform_scale-small) | 步骤条item-放大 |
| $color-steps-bg-active | var(--semi-color-fill-1) | 步骤条背景 - 按下态 |
| $color-steps-bg-default | var(--semi-color-text-2) | 未到达步骤条图标背景 |
| $color-steps-bg-hover | var(--semi-color-fill-0) | 步骤条背景 - 悬浮态 |
| $color-steps-border-default | transparent | 步骤条描边 - 默认 |
| $color-steps-icon-default | var(--semi-color-text-2) | 未到达步骤条图标背景 |
| $color-steps-text-default | var(--semi-white) | 步骤条图标默认文本颜色 |
| $color-steps_danger-text-active | var(--semi-color-danger-active) | 错误步骤条文本颜色 - 按下态 |
| $color-steps_danger-text-default | var(--semi-color-danger) | 错误步骤条文本颜色 - 默认态 |
| $color-steps_danger-text-hover | var(--semi-color-danger-hover) | 错误步骤条文本颜色 - 悬浮态 |
| $color-steps_icon_after-bg | var(--semi-color-fill-2) | |
| $color-steps_item_description-text-hover | var(--semi-color-focus-border) | 步骤条辅助描述文本颜色 - 悬浮态 |
| $color-steps_item_done_after-bg | var(--semi-color-primary) | 完成步骤条尾部连接线颜色 |
| $color-steps_item_done_icon_after-bg | var(--semi-color-primary) | |
| $color-steps_item_error_left-icon | var(--semi-color-danger) | 错误步骤条图标颜色 |
| $color-steps_item_error_left_number-icon | var(--semi-color-primary) | 错误步骤条数字序号文本颜色 |
| $color-steps_item_finish-icon | var(--semi-color-primary) | 已完成步骤条图标颜色 |
| $color-steps_item_finish_number-icon | var(--semi-color-white) | 已完成步骤条对勾图标颜色 |
| $color-steps_item_left_number_icon-bg | var(--semi-color-primary) | 步骤条图标背景颜色 |
| $color-steps_item_left_number_icon-icon | var(--semi-color-white) | 步骤条图标文字颜色 |
| $color-steps_item_process_left-icon | var(--semi-color-primary) | 进行中步骤条对勾图标颜色 |
| $color-steps_item_process_left_number-icon | var(--semi-color-white) | 进行中步骤条内部图标颜色 |
| $color-steps_item_title-text-hover | var(--semi-color-focus-border) | 步骤条标题文字悬停颜色 |
| $color-steps_item_wait_left_icon-icon | var(--semi-color-text-2) | 未到达步骤条图标颜色 |
| $color-steps_item_wait_left_number_icon-bg-hover | var(--semi-color-secondary-light-default) | 未到达步骤条图标背景颜色 - 悬浮态 |
| $color-steps_item_wait_left_number_icon-bg | var(--semi-color-fill-0) | 未到达步骤条图标背景颜色 |
| $color-steps_item_wait_left_number_icon-icon-hover | var(--semi-color-focus-border) | 未到达步骤条图标颜色 - 悬浮态 |
| $color-steps_item_wait_left_number_icon-icon | var(--semi-color-text-2) | 未到达步骤条内部图标颜色 |
| $color-steps_item_wait_title-text | var(--semi-color-text-2) | 未到达步骤条标题文字颜色 |
| $color-steps_item_warning_left-icon | var(--semi-color-warning) | 警告步骤条图标颜色 |
| $color-steps_item_warning_left_number-icon | var(--semi-color-white) | 警告步骤条数字序号文本颜色 |
| $color-steps_main-text-default | var(--semi-color-text-0) | 步骤条标题文本颜色 |
| $color-steps_minor-text-default | var(--semi-color-text-2) | 步骤条辅助描述文本颜色 |
| $color-steps_nav_item_container-text | var(--semi-color-text-2) | 步骤条容器内文本颜色 |
| $color-steps_nav_item-icon | var(--semi-grey-3) | |
| $color-steps_nav_item_title-text-active | var(--semi-color-text-0) | 步骤条标题颜色 - 按下态 |
| $color-steps_primary-bg-default | var(--semi-color-primary) | 旧版进行中步骤条背景色 - 默认 |
| $color-steps_primary-icon-default | var(--semi-color-primary) | 旧版进行中步骤条图标色 - 默认 |
| $color-steps_process-bg-default | var(--semi-color-primary-light-default) | 旧版进行中步骤条背景色 - 默认 |
| $color-steps_success-text-active | var(--semi-color-success-active) | 旧版已完成步骤条文字颜色 - 按下态 |
| $color-steps_success-text-default | var(--semi-color-success) | 旧版已完成步骤条文字颜色 - 默认态 |
| $color-steps_success-text-hover | var(--semi-color-success-hover) | 旧版已完成步骤条文字颜色 - 悬浮态 |
| $color-steps_title_after-bg | var(--semi-color-fill-2) | 旧版步骤条连线颜色 |
| $color-steps_warning-text-active | var(--semi-color-warning-active) | 旧版警告步骤条文字颜色 - 按下态 |
| $color-steps_warning-text-default | var(--semi-color-warning) | 旧版警告步骤条文字颜色 - 默认态 |
| $color-steps_warning-text-hover | var(--semi-color-warning-hover) | 旧版警告步骤条文字颜色 - 悬浮态 |
| $width-steps_basic_item_description | 100% | 步骤条辅助描述文本宽度 |
| $width-steps_basic_item_description-maxWidth | 268px | 步骤条辅助描述文本最大宽度 |
| $width-steps_basic_item_title-maxWidth | 80% | 步骤条标题宽度 |
| $height-steps_basic_vertical_icon_content-minHeight | 42px | 垂直步骤条图标+内容最小高度 |
| $width-steps_basic_vertical_item_title-maxWidth | 100% | 垂直步骤条标题最大宽度 |
| $width-steps_basic_vertical_item_description | 100% | 垂直步骤条辅助描述文本最大宽度 |
| $height-steps_basic_vertical_small_item_content-minHeight | 40px | 小尺寸垂直步骤条内容最小高度 |
| $height-steps_basic_item_left-icon | 24px | 步骤条左侧图标高度 |
| $width-steps_basic_item_left_number-icon | 24px | 步骤条左侧图标宽度 |
| $height-steps_basic_item_left_number-icon | 24px | 步骤条左侧图标高度 |
| $height-steps_basic_small_item_left-icon | 20px | 小尺寸步骤条左侧图标高度 |
| $width-steps_basic_small_item_left_number-icon | 20px | 小尺寸步骤条左侧数字图标高度 |
| $height-steps_item | 72px | 旧版步骤条高度 |
| $width-steps_item-border | 1px | 旧版步骤条高度 |
| $width-steps_item_title | 100% | 步骤条标题宽度 |
| $width-steps_item_description | 100% | 步骤条辅助描述文本宽度 |
| $width-steps_item_left | 24px | 步骤条左侧图标容器宽度 |
| $height-steps_item_left | 24px | 步骤条左侧图标容器高度 |
| $width-steps_title_after | 9999px | 步骤条连接线长度 |
| $height-steps_title_after | 1px | 步骤条连接线高度 |
| $width-steps_vertical_icon_after | 1px | |
| $height-steps_vertical_icon_after | 9999px | 垂直步骤条连接线长度 |
| $width-steps_nav_item_icon-minWidth | 60px | 导航型步骤条图标最小宽度 |
| $width-steps_nav_item_title-maxWidth | 17em | 导航型步骤条标题最大宽度 |
| $spacing-steps_basic_item-paddingLeft | 16px | 简版步骤条左侧内边距 |
| $spacing-steps_basic_vertical_item-paddingTop | 9px | 简版垂直步骤条顶部内边距 |
| $spacing-steps_basic_vertical_item_content-paddingBottom | 22px | 简版垂直步骤条内容区底部内边距 |
| $spacing-steps_basic_vertical_item_icon-paddingBottom | 9px | 简版垂直步骤条图标底部内边距 |
| $spacing-steps_basic_item_left-marginRight | 8px | 简版步骤条图标右侧外边距 |
| $spacing-steps_basic_item_title-paddingRight | 16px | 简版步骤条标题右侧内边距 |
| $spacing-steps_basic_item_title-paddingBottom | 4px | 简版步骤条标题底部内边距 |
| $spacing-steps_item-marginRight | 16px | 旧版步骤条右侧外边距 |
| $spacing-steps_item-paddingY | $spacing-base-tight | 旧版步骤条垂直方向内边距 |
| $spacing-steps_item-paddingX | $spacing-base | 旧版步骤条水平方向内边距 |
| $spacing-steps_item_content-marginLeft | $spacing-base | 旧版步骤条水平内容区左侧外边距 |
| $radius-steps_basic_item_left_number_icon | var(--semi-border-radius-circle) | 步骤条左侧图标圆角 |
| $radius-steps_item | var(--semi-border-radius-medium) | 步骤条整体圆角 |
| $radius-steps_item_left | 32px | 步骤条左侧距离 |
| $font-steps_basic_item_left_number_icon-fontWeight | 600 | 步骤条数字图标文本字重 |
| $font-steps_basic_item_title-fontWeight | 600 | 步骤条标题文本字重 |
| $font-steps_basic_item_title-lineHeight | 24px | 步骤条标题文本行高 |
| $font-steps_item_left-lineHeight | 32px | 步骤条标题左侧图标内部文本行高 |
| $font-steps_nav_item_title-fontWeight | $font-weight-regular | 导航型步骤条标题文本字重 - 默认态 |
| $font-steps_nav_item_title_active-fontWeight | 600 | 导航型步骤条标题文本字重 - 激活态 |