Lzh on GitHub

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

结构

导入所有部分并将其组合在一起。

<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 覆盖。
asChildfalseboolean将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南
defaultValue1number首次渲染时应激活的步骤值。当您不需要控制步骤状态时使用。
dir'ltr' | 'rtl'组合框(如果适用)的阅读方向。如果省略,则从 ConfigProvider 全局继承或假定为从左到右 (LTR) 阅读模式。
lineartrueboolean步骤是否必须按顺序完成。
modelValuenumber要激活的步骤的受控值。可以绑定为 v-model
orientation'horizontal''vertical' | 'horizontal'步骤的布局方向。主要用于相应地进行箭头导航(左右 vs. 上下)。

触发事件 (Emit)

事件名称Payload描述
update:modelValue[payload: number]值更改时调用的事件处理程序。

默认插槽

插槽参数插槽参数类型描述
modelValuenumber | undefined当前步骤
totalStepsnumber总步骤数
isNextDisabledboolean下一步是否禁用
isPrevDisabledboolean上一步是否禁用
isFirstStepboolean是否是第一步
isLastStepboolean是否是最后一步
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 覆盖。
asChildfalseboolean将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南
completedfalseboolean显示步骤是否已完成。
disabledfalseboolean当为 true 时,阻止用户与步骤交互。
step*number将步进器项与索引关联的唯一值。

插槽 (默认)

插槽参数插槽参数类型描述
state'active' | 'completed' | 'inactive'步进器项的当前状态

数据属性

属性
[data-state]"active" | "inactive" | "completed"
[data-disabled]禁用时存在
[data-orientation]"vertical" | "horizontal"

Trigger

切换步骤的触发器。

属性默认值类型描述
as'button'AsTag | Component此组件应渲染为的元素或组件。可以通过 asChild 覆盖。
asChildfalseboolean将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南

数据属性

属性
[data-state]"active" | "inactive" | "completed"
[data-disabled]禁用时存在
[data-orientation]"vertical" | "horizontal"

Indicator

步骤的指示器。

属性默认值类型描述
as'div'AsTag | Component此组件应渲染为的元素或组件。可以通过 asChild 覆盖。
asChildfalseboolean将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南

默认插槽

插槽参数插槽参数类型描述
stepnumber当前步骤

Title

当步进器触发器聚焦时宣布的可访问标题。如果您想隐藏标题,请将其包装在我们的 Visually Hidden 实用程序中,如下所示 <VisuallyHidden asChild>

属性默认值类型描述
as'h4'AsTag | Component此组件应渲染为的元素或组件。可以通过 asChild 覆盖。
asChildfalseboolean将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南

Description

当步进器触发器聚焦时宣布的可选可访问描述。

如果您想隐藏描述,请将其包装在我们的 Visually Hidden 实用程序中,如下所示 <VisuallyHidden asChild>。如果您想完全删除描述,请删除此部分并将 aria-describedby="undefined" 传递给 StepperTrigger

属性默认值类型描述
as'div'AsTag | Component此组件应渲染为的元素或组件。可以通过 asChild 覆盖。
asChildfalseboolean将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南
completedfalseboolean显示步骤是否已完成。
disabledfalseboolean当为 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选择聚焦的步骤。