Demos
How to import
<script lang="ts">
import { Steps } from '@fibrae/semi-ui-svelte';
</script>
Svelte has no Steps.Step: steps are data items in dataSource (StepData[]), and each item can carry status, title, description, icon and onClick; other attributes land on the step's root element. For a custom title or description, use the title and description snippets of Steps, whose argument is { item, index }; icons are set per item through its icon field.
Default step bar(Deprecated)
It is recommended to use the simple version of steps, which will be gradually deprecated later
Code
<script lang="ts">
import { Steps } from '@fibrae/semi-ui-svelte';
const dataSource = [
{ title: 'Finished', description: 'This is a description' },
{ title: 'In Progress', description: 'This is a description' },
{ title: 'Waiting', description: 'This is a description' },
];
const log = (i: number) => console.log(i);
</script>
<Steps current={1} {dataSource} onChange={log} />Basic Steps(Recommended)
Set type="basic" to display a simple style step bar
Code
<script lang="ts">
import { Steps } from '@fibrae/semi-ui-svelte';
const dataSource = [
{ title: 'Finished', description: 'This is a description' },
{ title: 'In Progress', description: 'This is a description' },
{ title: 'Waiting', description: 'This is a description' },
];
const log = (i: number) => console.log(i);
</script>
<Steps current={1} {dataSource} onChange={log} type="basic" />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 lang="ts">
import { Steps } from '@fibrae/semi-ui-svelte';
const dataSource = [
{ title: 'Finished', description: 'This is a description' },
{ title: 'In Progress', description: 'This is a description' },
{ title: 'Waiting', description: 'This is a description' },
];
const log = (i: number) => console.log(i);
</script>
<Steps current={1} {dataSource} onChange={log} size="small" type="basic" />Processing progress
Use with content and buttons to represent the processing progress of a process
Code
<script lang="ts">
import { Button, Steps } from '@fibrae/semi-ui-svelte';
const steps = [
{ title: 'First', content: 'First-content' },
{ title: 'Second', content: 'Second-content' },
{ title: 'Last', content: 'Last-content' },
];
let current = $state(0);
const log = (i: number) => console.log(i);
const done = () => console.log('Processing complete!');
</script>
<div>
<Steps {current} dataSource={steps} onChange={log} type="basic" />
<div class="steps-content" style="margin-top: 4px; margin-bottom: 4px">
{steps[current].content}
</div>
<div class="steps-action">
{#if current < steps.length - 1}
<Button type="primary" onclick={() => (current += 1)}>Next</Button>
{/if}
{#if current === steps.length - 1}
<Button type="primary" onclick={done}>Done</Button>
{/if}
{#if current > 0}
<Button style="margin-left: 8px" onclick={() => (current -= 1)}>Previous</Button>
{/if}
</div>
</div>Steps bar in vertical direction
Show steps in vertical direction by setting direction
Code
<script lang="ts">
import { Steps } from '@fibrae/semi-ui-svelte';
const dataSource = [
{ title: 'Finished', description: 'This is a description' },
{ title: 'In Progress', description: 'This is a description' },
{ title: 'Waiting', description: 'This is a description' },
];
const log = (i: number) => console.log(i);
</script>
<Steps current={1} {dataSource} direction="vertical" onChange={log} style="width: 300px" />Code
<script lang="ts">
import { Steps } from '@fibrae/semi-ui-svelte';
const dataSource = [
{ title: 'Finished', description: 'This is a description' },
{ title: 'In Progress', description: 'This is a description' },
{ title: 'Waiting', description: 'This is a description' },
];
const log = (i: number) => console.log(i);
</script>
<Steps current={1} {dataSource} direction="vertical" onChange={log} type="basic" />Specify step status
Using Steps status Property to specify the state of the current step.
Code
<script lang="ts">
import { Steps } from '@fibrae/semi-ui-svelte';
const dataSource = [
{ title: 'Finished', description: 'This is a description' },
{ title: 'In Process', description: 'This is a description' },
{ title: 'Waiting', description: 'This is a description' },
];
const log = (i: number) => console.log(i);
</script>
<Steps current={1} {dataSource} onChange={log} status="error" type="basic" />Custom icons
Set the icon snippet of a dataSource item to show a custom icon for that step. Steps without icon keep their status icon, and icon: false shows no icon for that step.
By setting Steps.Step's status property (the status of a dataSource item in Svelte), you can customize the status of each step.
Code
<script lang="ts">
import { IconHome, IconLock } from '@fibrae/semi-icons-svelte';
import { Steps, type StepData } from '@fibrae/semi-ui-svelte';
// Steps without `icon` keep their built-in status icon
const dataSource: StepData[] = [
{ status: 'finish', title: '已完成' },
{ status: 'error', title: '错误' },
{ status: 'warning', title: '警告' },
{ status: 'process', title: '正在进行', icon: homeIcon },
{ status: 'wait', title: '等待', icon: lockIcon },
];
const log = (i: number) => console.log(i);
</script>
{#snippet homeIcon()}<IconHome size="extra-large" />{/snippet}
{#snippet lockIcon()}<IconLock size="extra-large" />{/snippet}
<Steps {dataSource} onChange={log} type="basic" />onChange CallBack
Listen for step changes with onChange. 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. Passing onChange makes every step clickable, and so is a step whose dataSource item has an onClick. current is not bindable: update it yourself in onChange.
Code
<script lang="ts">
import { Steps } from '@fibrae/semi-ui-svelte';
const dataSource = [{ title: 'First' }, { title: 'Second' }, { title: 'Last' }];
let current = $state(1);
</script>
<div>
<Steps {current} {dataSource} onChange={(next) => (current = next)} type="basic" />
</div>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 |
|---|---|---|---|
| current | Current step, counting from 0; a dataSource item can override the state with status. Not bindable: update it yourself in onChange. | number | 0 |
| dataSource | Step data. Each item is a StepData: status (own status of the step; when omitted it follows current and status), title, description (not rendered by the nav type), icon (snippet for a custom icon of that step; false shows no icon; the status icon is used when omitted; not rendered by the nav type) and onClick (setting it makes that step clickable). Other attributes land on the step's root element. | StepData[] | [] |
| description | Snippet for the description of each step, with { item, index }; defaults to item.description. Not rendered by the nav type. | TypeSnippet<[StepSnippetProps]> | - |
| direction | Direction: horizontal or vertical. | StepsDirection | "horizontal" |
| hasLine | Whether the basic type shows connecting lines. | boolean | true |
| initial | Starting index, counting from 0. | number | 0 |
| onChange | Called when a step is selected by click or keyboard, with its number (initial plus index); not called for the current step. Passing it makes every step clickable. | Type(current: number) => void | - |
| prefixCls | Class name prefix of the root element. | string | "semi-steps" |
| size | Size of the basic and nav types: default or small. | StepsSize | "default" |
| status | State of the current step: wait, process, finish, error or warning. | StepStatus | "process" |
| title | Snippet for the title of each step, with { item, index }; defaults to item.title. | TypeSnippet<[StepSnippetProps]> | - |
| type | Steps type: fill, basic or nav. | StepsType | "fill" |
class, style (a string) and other native attributes land on the root element of Steps.
Steps.Step
Step in the step bar.
Svelte has no separate Step component; the attributes of a step go in its dataSource item. Attributes other than status, title, description, icon and onClick (aria-label, role, class, style, onkeydown and so on) land on the step item (the root element), and style only accepts a string. role defaults to button when the step is clickable, and a passed role takes precedence; tabindex follows whether the step is clickable.
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 | 导航型步骤条标题文本字重 - 激活态 |