Stepper
用于指示多步骤过程的进度的一组步骤。
<script setup lang="ts">
import { Icon } from '@iconify/vue'
import { StepperDescription, StepperIndicator, StepperItem, StepperRoot, StepperSeparator, StepperTitle, StepperTrigger } from 'reka-ui'
const steps = [{
step: 1,
title: 'Address',
description: 'Add your address here',
icon: 'radix-icons:home',
}, {
step: 2,
title: 'Shipping',
description: 'Set your preferred shipping method',
icon: 'radix-icons:archive',
}, {
step: 3,
title: 'Checkout',
description: 'Confirm your order',
icon: 'radix-icons:check',
}]
</script>
<template>
<StepperRoot
:default-value="2"
class="flex gap-2 w-full max-w-[32rem]"
>
<StepperItem
v-for="item in steps"
:key="item.step"
class="w-full flex justify-center gap-2 cursor-pointer group relative px-4"
:step="item.step"
>
<StepperTrigger class="inline-flex border-2 shadow-sm items-center text-white bg-green-900 border-green-900 group-data-[state=inactive]:border-gray-200 group-data-[state=inactive]:bg-white group-data-[state=inactive]:text-stone-700 group-data-[disabled]:opacity-50 group-data-[disabled]:cursor-not-allowed justify-center rounded-full w-10 h-10 shrink-0 focus:shadow-[0_0_0_2px] focus:shadow-black focus:outline-none">
<StepperIndicator>
<Icon
:icon="item.icon"
class="w-5 h-5"
/>
</StepperIndicator>
</StepperTrigger>
<StepperSeparator
v-if="item.step !== steps[steps.length - 1].step"
class="absolute block top-5 left-[calc(50%+30px)] right-[calc(-50%+20px)] h-0.5 rounded-full bg-stone-300/50 shrink-0"
/>
<div class="absolute text-center top-full left-0 w-full mt-2 text-stone-700 dark:text-white group-data-[disabled]:opacity-50">
<StepperTitle class="font-medium">
{{ item.title }}
</StepperTitle>
<StepperDescription class="hidden sm:block text-xs">
{{ item.description }}
</StepperDescription>
</div>
</StepperItem>
</StepperRoot>
</template>
功能特点
- 支持键盘交互。
- 支持水平/垂直布局。
- 支持嵌套布局。
- 支持从右到左的方向。
- 可以有条件地挂载。
安装
从命令行安装组件。
$ npm add reka-ui
$ pnpm add reka-ui
$ yarn add reka-ui
$ bun add reka-ui
结构
导入所有部分并将其组合在一起。
<script setup>
import { StepperDescription, StepperIndicator, StepperItem, StepperRoot, StepperTitle, StepperTrigger } from 'reka-ui'
</script>
<template>
<StepperRoot>
<StepperItem>
<StepperTrigger />
<StepperIndicator />
<StepperTitle />
<StepperDescription />
<StepperSeparator />
</StepperItem>
</StepperRoot>
</template>
API 参考
Root
包含所有 Stepper 组件部分。
| 属性 | 默认值 | 类型 | 描述 |
|---|---|---|---|
as | 'div' | AsTag | Component | 此组件应渲染为的元素或组件。可以通过 asChild 覆盖。 |
asChild | false | boolean | 将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南。 |
defaultValue | 1 | number | 首次渲染时应激活的步骤值。当您不需要控制步骤状态时使用。 |
dir | 'ltr' | 'rtl' | 组合框(如果适用)的阅读方向。如果省略,则从 ConfigProvider 全局继承或假定为从左到右 (LTR) 阅读模式。 | |
linear | true | boolean | 步骤是否必须按顺序完成。 |
modelValue | number | 要激活的步骤的受控值。可以绑定为 v-model。 | |
orientation | 'horizontal' | 'vertical' | 'horizontal' | 步骤的布局方向。主要用于相应地进行箭头导航(左右 vs. 上下)。 |
触发事件 (Emit)
| 事件名称 | Payload | 描述 |
|---|---|---|
update:modelValue | [payload: number] | 值更改时调用的事件处理程序。 |
默认插槽
| 插槽参数 | 插槽参数类型 | 描述 |
|---|---|---|
modelValue | number | undefined | 当前步骤 |
totalSteps | number | 总步骤数 |
isNextDisabled | boolean | 下一步是否禁用 |
isPrevDisabled | boolean | 上一步是否禁用 |
isFirstStep | boolean | 是否是第一步 |
isLastStep | boolean | 是否是最后一步 |
goToStep | (step: number): void | 转到特定步骤 |
nextStep | (): void | 转到下一步 |
prevStep | (): void | 转到上一步 |
hasNext | (): boolean | 是否有下一步 |
hasPrev | (): boolean | 是否有上一步 |
方法
| 方法名称 | 类型 | 描述 |
|---|---|---|
goToStep | (step: number) => void | |
nextStep | () => void | |
prevStep | () => void | |
hasNext | () => boolean | |
hasPrev | () => boolean |
数据属性
| 属性 | 值 |
|---|---|
[data-orientation] | "vertical" | "horizontal" |
[data-linear] | 线性时存在 |
Item
步骤项组件。
| 属性 | 默认值 | 类型 | 描述 |
|---|---|---|---|
as | 'div' | AsTag | Component | 此组件应渲染为的元素或组件。可以通过 asChild 覆盖。 |
asChild | false | boolean | 将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南。 |
completed | false | boolean | 显示步骤是否已完成。 |
disabled | false | boolean | 当为 true 时,阻止用户与步骤交互。 |
step* | number | 将步进器项与索引关联的唯一值。 |
插槽 (默认)
| 插槽参数 | 插槽参数类型 | 描述 |
|---|---|---|
state | 'active' | 'completed' | 'inactive' | 步进器项的当前状态 |
数据属性
| 属性 | 值 |
|---|---|
[data-state] | "active" | "inactive" | "completed" |
[data-disabled] | 禁用时存在 |
[data-orientation] | "vertical" | "horizontal" |
Trigger
切换步骤的触发器。
| 属性 | 默认值 | 类型 | 描述 |
|---|---|---|---|
as | 'button' | AsTag | Component | 此组件应渲染为的元素或组件。可以通过 asChild 覆盖。 |
asChild | false | boolean | 将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南。 |
数据属性
| 属性 | 值 |
|---|---|
[data-state] | "active" | "inactive" | "completed" |
[data-disabled] | 禁用时存在 |
[data-orientation] | "vertical" | "horizontal" |
Indicator
步骤的指示器。
| 属性 | 默认值 | 类型 | 描述 |
|---|---|---|---|
as | 'div' | AsTag | Component | 此组件应渲染为的元素或组件。可以通过 asChild 覆盖。 |
asChild | false | boolean | 将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南。 |
默认插槽
| 插槽参数 | 插槽参数类型 | 描述 |
|---|---|---|
step | number | 当前步骤 |
Title
当步进器触发器聚焦时宣布的可访问标题。如果您想隐藏标题,请将其包装在我们的 Visually Hidden 实用程序中,如下所示 <VisuallyHidden asChild>。
| 属性 | 默认值 | 类型 | 描述 |
|---|---|---|---|
as | 'h4' | AsTag | Component | 此组件应渲染为的元素或组件。可以通过 asChild 覆盖。 |
asChild | false | boolean | 将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南。 |
Description
当步进器触发器聚焦时宣布的可选可访问描述。
如果您想隐藏描述,请将其包装在我们的 Visually Hidden 实用程序中,如下所示 <VisuallyHidden asChild>。如果您想完全删除描述,请删除此部分并将 aria-describedby="undefined" 传递给 StepperTrigger。
| 属性 | 默认值 | 类型 | 描述 |
|---|---|---|---|
as | 'div' | AsTag | Component | 此组件应渲染为的元素或组件。可以通过 asChild 覆盖。 |
asChild | false | boolean | 将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南。 |
completed | false | boolean | 显示步骤是否已完成。 |
disabled | false | boolean | 当为 true 时,阻止用户与步骤交互。 |
step* | number | 将步进器项与索引关联的唯一值。 |
默认插槽
| 插槽参数 | 插槽参数类型 | 描述 |
|---|---|---|
state | 'active' | 'completed' | 'inactive' | 步进器项的当前状态 |
示例
垂直
您可以使用 orientation prop 创建垂直步骤。
<script setup>
import { StepperDescription, StepperIndicator, StepperItem, StepperRoot, StepperTitle } from 'reka-ui'
</script>
<template>
<StepperRoot
:default-value="1"
orientation="vertical"
>
<StepperItem>
<StepperIndicator />
<StepperTitle />
<StepperDescription />
</StepperItem>
<StepperItem>
<StepperIndicator />
<StepperTitle />
<StepperDescription />
</StepperItem>
</StepperRoot>
</template>
使用控件
您可以使用按钮为步进器添加额外的控件,并使用 useTemplateRef 访问类型化的组件实例。
<script setup lang="ts">
const stepper = useTemplateRef('stepper')
</script>
<template>
<StepperRoot
ref="stepper"
:default-value="1"
>
<StepperItem>
<StepperIndicator />
<StepperTitle />
<StepperDescription />
</StepperItem>
<StepperItem>
<StepperIndicator />
<StepperTitle />
<StepperDescription />
</StepperItem>
</StepperRoot>
<div class="flex gap-2 justify-between mt-4">
<button
:disabled="!stepper?.hasPrev()"
@click="stepper?.prevStep()"
>
Prev
</button>
<button
:disabled="!stepper?.hasNext()"
@click="stepper?.nextStep()"
>
Next
</button>
</div>
</template>
可访问性
键盘交互
| 按键 | 描述 |
|---|---|
Tab | 当焦点移动到步骤时,聚焦第一个步骤。 |
ArrowDown | 根据 orientation 将焦点移动到下一步。 |
ArrowRight | 根据 orientation 将焦点移动到下一步。 |
ArrowUp | 根据 orientation 将焦点移动到上一步。 |
ArrowLeft | 根据 orientation 将焦点移动到上一步。 |
Enter Space | 选择聚焦的步骤。 |