导航类

步骤

将复杂任务或存在先后关系的任务分解,使用步骤组件引导用户按规定流程操作,并让其知道其当前的进度

代码演示

如何引入

<script lang="ts">
    import { Steps } from '@fibrae/semi-ui-svelte';
</script>

Svelte 没有 Steps.Step:步骤写成 dataSource(StepData[])里的数据项,每项可带 status、title、description、icon、onClick,其余属性落在步骤根元素上。需要自定义标题和描述时,用 Steps 的 title、description snippet,参数为 { item, index };图标写在各项的 icon 字段里。

默认步骤条(旧版)

建议使用简易版 steps(新版),旧版后续会逐渐 deprecate

Finished
This is a description
2
In Progress
This is a description
3
Waiting
This is a description
代码
<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" 显示为简洁风格步骤条

Finished
This is a description
2
In Progress
This is a description
3
Waiting
This is a description
代码
<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" />

导航步骤条

通过设置 type="nav" 显示为导航风格步骤条。导航风格的步骤条有以下特点:

  1. 步骤条同样支持交互:Steps 监听步骤切换或 Step 绑定点击回调后,步骤可聚焦、可点击,行为与其他类型一致。

  2. 适用于步骤间互相关联较小,内容互不影响,且需要突出页面视觉元素时使用。

  3. 步骤条的宽度按照内容物撑开。

  4. Steps.Step 只渲染标题,description、icon、status 不生效;其余属性与事件(aria-label、role、点击与键盘回调、类名与样式等)与其他类型相同。

注册账号
这个项目的文字比较多多多多
产品用途
期待尝试功能
代码
<script lang="ts">
    import { Steps } from '@fibrae/semi-ui-svelte';

    const dataSource = [{ title: '注册账号' }, { title: '这个项目的文字比较多多多多' }, { title: '产品用途' }, { title: '期待尝试功能' }];
    const log = (i: number) => console.log(i);
</script>

<div style="display: flex; justify-content: center">
    <Steps current={1} {dataSource} onChange={log} style="margin: auto" type="nav" />
</div>

迷你尺寸步骤条

通过设置 size="small" 显示迷你尺寸步骤条

Finished
This is a description
2
In Progress
This is a description
3
Waiting
This is a description
代码
<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" />
注册账号
这个项目的文字比较多多多多
产品用途
期待尝试功能
代码
<script lang="ts">
    import { Steps } from '@fibrae/semi-ui-svelte';

    const dataSource = [{ title: '注册账号' }, { title: '这个项目的文字比较多多多多' }, { title: '产品用途' }, { title: '期待尝试功能' }];
    const log = (i: number) => console.log(i);
</script>

<div style="display: flex; justify-content: center">
    <Steps current={1} {dataSource} onChange={log} size="small" style="margin: auto" type="nav" />
</div>

处理进度

配合内容及按钮使用,表示一个流程的处理进度

1
First
2
Second
3
Last
First-content
代码
<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>

竖直方向的步骤条

通过设置 direction,使用竖直方向的步骤条

Finished
This is a description
2
In Progress
This is a description
3
Waiting
This is a description
代码
<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" />
Finished
This is a description
2
In Progress
This is a description
3
Waiting
This is a description
代码
<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" />

指定步骤状态

步骤运行错误,使用 Steps 的 status 属性来指定当前步骤的状态。

Finished
This is a description
In Process
This is a description
3
Waiting
This is a description
代码
<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" />

自定义图标/状态

通过 dataSource 项的 icon snippet 可以为该步骤启用自定义图标,未设置 icon 的步骤保留状态图标;icon 为 false 时该步骤不显示图标。

通过设置 Steps.Step 的 status 属性(Svelte 中为 dataSource 项的 status),可以自定义每个 step 的状态

已完成
错误
警告
正在进行
等待
代码
<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 回调

通过 onChange 监听步骤切换,回调接收一个 number 类型的参数,等于 initial 加所选步骤的索引;点击当前步骤不会触发。传入 onChange 后所有步骤变为可点击,dataSource 项带 onClick 的那一步也可点击。current 不可绑定,需要在 onChange 里自己更新。

First
2
Second
3
Last
代码
<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、Step 组件支持传入 aria-label 或 aria-labelledby。Steps 根元素与不可点击的 Step 本身没有语义角色,传入名称时带 role="group",名称因此能进入可访问名称;没有名称时不加 role。fill、basic、nav 三种类型一致
  • 当前步骤带有 aria-current="step",其余步骤不带该属性
  • Steps 监听步骤切换或 Step 绑定点击回调后,步骤可通过 Tab 聚焦,role 默认为 button(优先于 group,显式传入的 role 优先于二者);焦点在步骤上时按 Enter 或空格与鼠标点击一致,同时触发 Step 的点击回调与 Steps 的切换回调;不可点击的步骤不可聚焦
  • 点击来自步骤内其他可聚焦元素(input、button、链接等)时只触发 Step 的点击回调,不触发 Steps 的切换回调。可点击的步骤本身是 role="button",title、description 中放可聚焦控件会形成嵌套交互元素,此时不要让步骤可点击

API 参考

Steps

整体步骤条。

Props

属性说明类型默认值
current当前步骤,从 0 开始计数;dataSource 项可用 status 覆盖状态。不可绑定,更新由使用方在 onChange 里写。number0
dataSource步骤数据,每项为 StepData:status(该步骤自己的状态,缺省时随 current 与 status 自动决定)、title、description(nav 类型不渲染)、icon(该步骤自定义图标的 snippet,false 不显示图标,缺省用状态图标;nav 类型不渲染)、onClick(设置后该步骤可点击),其余属性落在步骤根元素上。StepData[][]
description每个步骤详情描述的 snippet,参数 { item, index };缺省时显示 item.description。nav 类型不渲染。TypeSnippet<[StepSnippetProps]>-
direction步骤条方向,可选 horizontal、vertical。StepsDirection"horizontal"
hasLinebasic 类型是否显示连接线。booleantrue
initial起始序号,从 0 开始计数。number0
onChange点击或键盘选择步骤时调用,参数为该步骤序号(initial 加索引);点击当前步骤不调用。传入后所有步骤变为可点击。Type(current: number) => void-
prefixCls根元素的类名前缀。string"semi-steps"
sizebasic 与 nav 类型的尺寸,可选 default、small。StepsSize"default"
status当前步骤的状态,可选 wait、process、finish、error、warning。StepStatus"process"
title每个步骤标题的 snippet,参数 { item, index };缺省时显示 item.title。TypeSnippet<[StepSnippetProps]>-
type步骤条类型,可选 fill、basic、nav。StepsType"fill"

class、style(字符串)与其他原生属性落在 Steps 根元素上。

Steps.Step

步骤条内的每一个步骤。

Svelte 没有单独的 Step 组件,步骤的属性写在 dataSource 项里:status、title、description、icon、onClick 之外的属性(aria-label、role、class、style、onkeydown 等)落在步骤项(根元素)上,style 只接受字符串。role 在步骤可点击时默认为 button,传入时优先;tabindex 由步骤是否可点击决定。

文案规范

  • 步骤标题
    • 标题应保持简洁,避免截断和换行;
    • 使用句子大小写书写;
    • 不要包含标点符号
  • 描述
    • 为标题补充上下文信息
    • 不要以标点符号结尾

设计变量

下表是组件内部的 Sass 变量,不能覆写。定制样式请覆写 --semi-* CSS 变量(见 Design Token 页),或写不分层的 CSS 规则。
Sass 变量值用法
$transition_duration-steps_item_title-textvar(--semi-transition_duration-none)步骤条标题文字-背景色-动画持续时间
$transition_function-steps_item_title-textvar(--semi-transition_function-easeIn)步骤条标题文字-背景色-过渡曲线
$transition_delay-steps_item_title-textvar(--semi-transition_delay-none)步骤条标题文字-背景色-延迟时间
$transition_duration-steps_item_title-iconvar(--semi-transition_duration-none)步骤条标题文字-背景色-动画持续时间
$transition_function-steps_item_title-iconvar(--semi-transition_function-easeIn)步骤条标题文字-背景色-过渡曲线
$transition_delay-steps_item_title-iconvar(--semi-transition_delay-none)步骤条标题文字-背景色-延迟时间
$transition_duration-steps_item_backgroundColorvar(--semi-transition_duration-none)步骤条标题文字-背景色-动画持续时间
$transition_function-steps_item_backgroundColorvar(--semi-transition_function-easeIn)步骤条标题文字-背景色-过渡曲线
$transition_delay-steps_item_backgroundColorvar(--semi-transition_delay-none)步骤条标题文字-背景色-延迟时间
$transform_scale-step-itemvar(--semi-transform_scale-small)步骤条item-放大
$color-steps-bg-activevar(--semi-color-fill-1)步骤条背景 - 按下态
$color-steps-bg-defaultvar(--semi-color-text-2)未到达步骤条图标背景
$color-steps-bg-hovervar(--semi-color-fill-0)步骤条背景 - 悬浮态
$color-steps-border-defaulttransparent步骤条描边 - 默认
$color-steps-icon-defaultvar(--semi-color-text-2)未到达步骤条图标背景
$color-steps-text-defaultvar(--semi-white)步骤条图标默认文本颜色
$color-steps_danger-text-activevar(--semi-color-danger-active)错误步骤条文本颜色 - 按下态
$color-steps_danger-text-defaultvar(--semi-color-danger)错误步骤条文本颜色 - 默认态
$color-steps_danger-text-hovervar(--semi-color-danger-hover)错误步骤条文本颜色 - 悬浮态
$color-steps_icon_after-bgvar(--semi-color-fill-2)
$color-steps_item_description-text-hovervar(--semi-color-focus-border)步骤条辅助描述文本颜色 - 悬浮态
$color-steps_item_done_after-bgvar(--semi-color-primary)完成步骤条尾部连接线颜色
$color-steps_item_done_icon_after-bgvar(--semi-color-primary)
$color-steps_item_error_left-iconvar(--semi-color-danger)错误步骤条图标颜色
$color-steps_item_error_left_number-iconvar(--semi-color-primary)错误步骤条数字序号文本颜色
$color-steps_item_finish-iconvar(--semi-color-primary)已完成步骤条图标颜色
$color-steps_item_finish_number-iconvar(--semi-color-white)已完成步骤条对勾图标颜色
$color-steps_item_left_number_icon-bgvar(--semi-color-primary)步骤条图标背景颜色
$color-steps_item_left_number_icon-iconvar(--semi-color-white)步骤条图标文字颜色
$color-steps_item_process_left-iconvar(--semi-color-primary)进行中步骤条对勾图标颜色
$color-steps_item_process_left_number-iconvar(--semi-color-white)进行中步骤条内部图标颜色
$color-steps_item_title-text-hovervar(--semi-color-focus-border)步骤条标题文字悬停颜色
$color-steps_item_wait_left_icon-iconvar(--semi-color-text-2)未到达步骤条图标颜色
$color-steps_item_wait_left_number_icon-bg-hovervar(--semi-color-secondary-light-default)未到达步骤条图标背景颜色 - 悬浮态
$color-steps_item_wait_left_number_icon-bgvar(--semi-color-fill-0)未到达步骤条图标背景颜色
$color-steps_item_wait_left_number_icon-icon-hovervar(--semi-color-focus-border)未到达步骤条图标颜色 - 悬浮态
$color-steps_item_wait_left_number_icon-iconvar(--semi-color-text-2)未到达步骤条内部图标颜色
$color-steps_item_wait_title-textvar(--semi-color-text-2)未到达步骤条标题文字颜色
$color-steps_item_warning_left-iconvar(--semi-color-warning)警告步骤条图标颜色
$color-steps_item_warning_left_number-iconvar(--semi-color-white)警告步骤条数字序号文本颜色
$color-steps_main-text-defaultvar(--semi-color-text-0)步骤条标题文本颜色
$color-steps_minor-text-defaultvar(--semi-color-text-2)步骤条辅助描述文本颜色
$color-steps_nav_item_container-textvar(--semi-color-text-2)步骤条容器内文本颜色
$color-steps_nav_item-iconvar(--semi-grey-3)
$color-steps_nav_item_title-text-activevar(--semi-color-text-0)步骤条标题颜色 - 按下态
$color-steps_primary-bg-defaultvar(--semi-color-primary)旧版进行中步骤条背景色 - 默认
$color-steps_primary-icon-defaultvar(--semi-color-primary)旧版进行中步骤条图标色 - 默认
$color-steps_process-bg-defaultvar(--semi-color-primary-light-default)旧版进行中步骤条背景色 - 默认
$color-steps_success-text-activevar(--semi-color-success-active)旧版已完成步骤条文字颜色 - 按下态
$color-steps_success-text-defaultvar(--semi-color-success)旧版已完成步骤条文字颜色 - 默认态
$color-steps_success-text-hovervar(--semi-color-success-hover)旧版已完成步骤条文字颜色 - 悬浮态
$color-steps_title_after-bgvar(--semi-color-fill-2)旧版步骤条连线颜色
$color-steps_warning-text-activevar(--semi-color-warning-active)旧版警告步骤条文字颜色 - 按下态
$color-steps_warning-text-defaultvar(--semi-color-warning)旧版警告步骤条文字颜色 - 默认态
$color-steps_warning-text-hovervar(--semi-color-warning-hover)旧版警告步骤条文字颜色 - 悬浮态
$width-steps_basic_item_description100%步骤条辅助描述文本宽度
$width-steps_basic_item_description-maxWidth268px步骤条辅助描述文本最大宽度
$width-steps_basic_item_title-maxWidth80%步骤条标题宽度
$height-steps_basic_vertical_icon_content-minHeight42px垂直步骤条图标+内容最小高度
$width-steps_basic_vertical_item_title-maxWidth100%垂直步骤条标题最大宽度
$width-steps_basic_vertical_item_description100%垂直步骤条辅助描述文本最大宽度
$height-steps_basic_vertical_small_item_content-minHeight40px小尺寸垂直步骤条内容最小高度
$height-steps_basic_item_left-icon24px步骤条左侧图标高度
$width-steps_basic_item_left_number-icon24px步骤条左侧图标宽度
$height-steps_basic_item_left_number-icon24px步骤条左侧图标高度
$height-steps_basic_small_item_left-icon20px小尺寸步骤条左侧图标高度
$width-steps_basic_small_item_left_number-icon20px小尺寸步骤条左侧数字图标高度
$height-steps_item72px旧版步骤条高度
$width-steps_item-border1px旧版步骤条高度
$width-steps_item_title100%步骤条标题宽度
$width-steps_item_description100%步骤条辅助描述文本宽度
$width-steps_item_left24px步骤条左侧图标容器宽度
$height-steps_item_left24px步骤条左侧图标容器高度
$width-steps_title_after9999px步骤条连接线长度
$height-steps_title_after1px步骤条连接线高度
$width-steps_vertical_icon_after1px
$height-steps_vertical_icon_after9999px垂直步骤条连接线长度
$width-steps_nav_item_icon-minWidth60px导航型步骤条图标最小宽度
$width-steps_nav_item_title-maxWidth17em导航型步骤条标题最大宽度
$spacing-steps_basic_item-paddingLeft16px简版步骤条左侧内边距
$spacing-steps_basic_vertical_item-paddingTop9px简版垂直步骤条顶部内边距
$spacing-steps_basic_vertical_item_content-paddingBottom22px简版垂直步骤条内容区底部内边距
$spacing-steps_basic_vertical_item_icon-paddingBottom9px简版垂直步骤条图标底部内边距
$spacing-steps_basic_item_left-marginRight8px简版步骤条图标右侧外边距
$spacing-steps_basic_item_title-paddingRight16px简版步骤条标题右侧内边距
$spacing-steps_basic_item_title-paddingBottom4px简版步骤条标题底部内边距
$spacing-steps_item-marginRight16px旧版步骤条右侧外边距
$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_iconvar(--semi-border-radius-circle)步骤条左侧图标圆角
$radius-steps_itemvar(--semi-border-radius-medium)步骤条整体圆角
$radius-steps_item_left32px步骤条左侧距离
$font-steps_basic_item_left_number_icon-fontWeight600步骤条数字图标文本字重
$font-steps_basic_item_title-fontWeight600步骤条标题文本字重
$font-steps_basic_item_title-lineHeight24px步骤条标题文本行高
$font-steps_item_left-lineHeight32px步骤条标题左侧图标内部文本行高
$font-steps_nav_item_title-fontWeight$font-weight-regular导航型步骤条标题文本字重 - 默认态
$font-steps_nav_item_title_active-fontWeight600导航型步骤条标题文本字重 - 激活态