Lzh on GitHub

Tabs

一组分层的内容部分(称为选项卡面板),一次显示一个。
<script setup lang="ts">
import { TabsContent, TabsIndicator, TabsList, TabsRoot, TabsTrigger } from 'reka-ui'
</script>

<template>
  <TabsRoot
    class="flex flex-col w-full sm:w-[300px] shadow-sm rounded-lg border"
    default-value="tab1"
  >
    <TabsList
      class="relative shrink-0 flex border-b border-mauve6"
      aria-label="Manage your account"
    >
      <TabsIndicator class="absolute px-8 left-0 h-[2px] bottom-0 w-[--reka-tabs-indicator-size] translate-x-[--reka-tabs-indicator-position] translate-y-[1px] rounded-full transition-[width,transform] duration-300">
        <div class="bg-green-500 w-full h-full" />
      </TabsIndicator>
      <TabsTrigger
        class="bg-white px-5 h-[45px] flex-1 flex items-center justify-center text-sm leading-none text-mauve11 select-none  rounded-tl-md  hover:text-green-900 data-[state=active]:text-green-900 outline-none cursor-default focus-visible:relative focus-visible:shadow-[0_0_0_2px] focus-visible:shadow-black"
        value="tab1"
      >
        Account
      </TabsTrigger>
      <TabsTrigger
        class="bg-white px-5 h-[45px] flex-1 flex items-center justify-center text-sm leading-none text-mauve11 select-none  rounded-tr-md hover:text-green-900 data-[state=active]:text-green-900 outline-none cursor-default focus-visible:relative focus-visible:shadow-[0_0_0_2px] focus-visible:shadow-black"
        value="tab2"
      >
        Password
      </TabsTrigger>
    </TabsList>
    <TabsContent
      class="grow p-5 bg-white rounded-b-md outline-none focus:shadow-[0_0_0_2px] focus:shadow-black"
      value="tab1"
    >
      <p class="mb-5 !mt-0 text-mauve11 text-sm !leading-normal">
        Make changes to your account here. Click save when you're done.
      </p>
      <fieldset class="mb-[15px] w-full flex flex-col justify-start">
        <label
          class="text-xs leading-none mb-2.5 text-green12 block"
          for="name"
        > Name </label>
        <input
          id="name"
          class="bg-stone-50 grow shrink-0 rounded-md px-2.5 text-sm leading-none text-grass11 shadow-[0_0_0_1px] shadow-green7 h-[35px] focus:shadow-[0_0_0_2px] focus:shadow-green8 outline-none"
          value="Pedro Duarte"
        >
      </fieldset>
      <fieldset class="mb-[15px] w-full flex flex-col justify-start">
        <label
          class="text-xs leading-none mb-2.5 text-green12 block"
          for="username"
        > Username </label>
        <input
          id="username"
          class="bg-stone-50 grow shrink-0 rounded-md px-2.5 text-sm leading-none text-grass11 shadow-[0_0_0_1px] shadow-green7 h-[35px] focus:shadow-[0_0_0_2px] focus:shadow-green8 outline-none"
          value="@peduarte"
        >
      </fieldset>
      <div class="flex justify-end mt-5">
        <button
          class="inline-flex items-center justify-center rounded-md px-[15px] text-sm leading-none font-medium h-[35px] bg-green-400 text-green-900 hover:bg-green-500 focus:shadow-[0_0_0_2px] focus:shadow-green-700 outline-none cursor-default"
        >
          Save changes
        </button>
      </div>
    </TabsContent>
    <TabsContent
      class="grow p-5 bg-white rounded-b-md outline-none focus:shadow-[0_0_0_2px] focus:shadow-black"
      value="tab2"
    >
      <p class="mb-5 !mt-0 text-mauve11 text-sm !leading-normal">
        Change your password here. After saving, you'll be logged out.
      </p>
      <fieldset class="mb-[15px] w-full flex flex-col justify-start">
        <label
          class="text-xs leading-none mb-2.5 text-green12 block"
          for="currentPassword"
        >
          Current password
        </label>
        <input
          id="currentPassword"
          class="bg-stone-50 grow shrink-0 rounded-md px-2.5 text-sm leading-none text-grass11 shadow-[0_0_0_1px] shadow-green7 h-[35px] focus:shadow-[0_0_0_2px] focus:shadow-green8 outline-none"
          type="password"
        >
      </fieldset>
      <fieldset class="mb-[15px] w-full flex flex-col justify-start">
        <label
          class="text-xs leading-none mb-2.5 text-green12 block"
          for="newPassword"
        > New password </label>
        <input
          id="newPassword"
          class="bg-stone-50 grow shrink-0 rounded-md px-2.5 text-sm leading-none text-grass11 shadow-[0_0_0_1px] shadow-green7 h-[35px] focus:shadow-[0_0_0_2px] focus:shadow-green8 outline-none"
          type="password"
        >
      </fieldset>
      <fieldset class="mb-[15px] w-full flex flex-col justify-start">
        <label
          class="text-xs leading-none mb-2.5 text-green12 block"
          for="confirmPassword"
        >
          Confirm password
        </label>
        <input
          id="confirmPassword"
          class="bg-stone-50 grow shrink-0 rounded-md px-2.5 text-sm leading-none text-grass11 shadow-[0_0_0_1px] shadow-green7 h-[35px] focus:shadow-[0_0_0_2px] focus:shadow-green8 outline-none"
          type="password"
        >
      </fieldset>
      <div class="flex justify-end mt-5">
        <button
          class="inline-flex items-center justify-center rounded-md px-[15px] text-sm leading-none font-medium h-[35px] bg-green4 text-green11 hover:bg-green5 focus:shadow-[0_0_0_2px] focus:shadow-green7 outline-none cursor-default"
        >
          Change password
        </button>
      </div>
    </TabsContent>
  </TabsRoot>
</template>

功能特点

  • 可控或不可控。
  • 支持水平/垂直方向。
  • 支持自动/手动激活。
  • 完整的键盘导航。

安装

从命令行安装组件。

$ npm add reka-ui

结构

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

<script setup>
  import { TabsContent, TabsIndicator, TabsList, TabsRoot, TabsTrigger } from 'reka-ui'
</script>

<template>
  <TabsRoot>
    <TabsList>
      <TabsIndicator />
      <TabsTrigger />
    </TabsList>
    <TabsContent />
  </TabsRoot>
</template>

API 参考

Root

包含所有选项卡组件部分。

属性默认值类型描述
activationMode'automatic''automatic' | 'manual'选项卡是自动激活(聚焦时)还是手动激活(点击时)。
as'div'AsTag | Component此组件应渲染为的元素或组件。可以通过 asChild 覆盖。
asChildfalseboolean将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南
defaultValuestring | number选项卡首次渲染时应激活的值。当您不需要控制选项卡状态时使用。
dir'ltr' | 'rtl'组合框(如果适用)的阅读方向。如果省略,则从 ConfigProvider 全局继承或假定为从左到右 (LTR) 阅读模式。
modelValuestring | number要激活的选项卡的受控值。可以绑定为 v-model
orientation'horizontal''vertical' | 'horizontal'选项卡的布局方向。主要用于相应地进行箭头导航(左右 vs. 上下)。
unmountOnHidetrueboolean当为 true 时,元素将在关闭状态时卸载。

触发事件 (Emit)

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

默认插槽

插槽参数插槽参数类型描述
modelValuestring | number当前输入值

数据属性

属性
[data-orientation]"vertical" | "horizontal"

List

包含与活动内容边缘对齐的触发器。

属性默认值类型描述
as'div'AsTag | Component此组件应渲染为的元素或组件。可以通过 asChild 覆盖。
asChildfalseboolean将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南
looptrueboolean当为 true 时,键盘导航将从最后一个选项卡循环到第一个选项卡,反之亦然。

数据属性

属性
[data-orientation]"vertical" | "horizontal"

Trigger

激活其关联内容的按钮。

属性默认值类型描述
as'button'AsTag | Component此组件应渲染为的元素或组件。可以通过 asChild 覆盖。
asChildfalseboolean将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南
disabledfalseboolean当为 true 时,阻止用户与选项卡交互。
value*string | number将触发器与内容关联的唯一值。

数据属性

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

Indicator

突出显示当前活动选项卡的指示器。

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

CSS 变量

变量描述
--reka-tabs-indicator-size指示器的大小
--reka-tabs-indicator-position指示器的位置

Content

包含与每个触发器关联的内容。

使用 Presence 组件构建 - 支持任何[动画技术](animation techniques),同时保持对存在(presence)触发事件的访问。
属性默认值类型描述
as'div'AsTag | Component此组件应渲染为的元素或组件。可以通过 asChild 覆盖。
asChildfalseboolean将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南
forceMountfalseboolean当需要更多控制时,用于强制挂载。在与 Vue 动画库控制动画时很有用。
value*string | number将内容与触发器关联的唯一值。

数据属性

属性
[data-state]"active" | "inactive"
[data-orientation]"vertical" | "horizontal"

示例

垂直

您可以使用 orientation prop 创建垂直选项卡。

<script setup>
  import { TabsContent, TabsList, TabsRoot, TabsTrigger } from 'reka-ui'
</script>

<template>
  <TabsRoot
    default-value="tab1"
    orientation="vertical"
  >
    <TabsList aria-label="tabs example">
      <TabsTrigger value="tab1">
        One
      </TabsTrigger>
      <TabsTrigger value="tab2">
        Two
      </TabsTrigger>
      <TabsTrigger value="tab3">
        Three
      </TabsTrigger>
    </TabsList>
    <TabsContent value="tab1">
      Tab one content
    </TabsContent>
    <TabsContent value="tab2">
      Tab two content
    </TabsContent>
    <TabsContent value="tab3">
      Tab three content
    </TabsContent>
  </TabsRoot>
</template>

可访问性

遵循 Tabs WAI-ARIA 设计模式

键盘交互

按键描述
Tab当焦点移动到选项卡时,聚焦活动触发器。当触发器聚焦时,将焦点移动到活动内容。
ArrowDown根据 orientation 将焦点移动到下一个触发器并激活其关联内容。
ArrowRight根据 orientation 将焦点移动到下一个触发器并激活其关联内容。
ArrowUp根据 orientation 将焦点移动到上一个触发器并激活其关联内容。
ArrowLeft根据 orientation 将焦点移动到上一个触发器并激活其关联内容。
Home将焦点移动到第一个触发器并激活其关联内容。
End将焦点移动到最后一个触发器并激活其关联内容。