跳至内容

手风琴

一组垂直堆叠的交互式标题,每个标题都显示一个关联的内容部分。

vue
<script setup lang="ts">
import { AccordionContent, AccordionHeader, AccordionItem, AccordionRoot, AccordionTrigger } from 'radix-vue'
import { Icon } from '@iconify/vue'

const accordionItems = [
  {
    value: 'item-1',
    title: 'Is it accessible?',
    content: 'Yes. It adheres to the WAI-ARIA design pattern.',
  },
  {
    value: 'item-2',
    title: 'Is it unstyled?',
    content: 'Yes. It\'s unstyled by default, giving you freedom over the look and feel.',
  },
  {
    value: 'item-3',
    title: 'Can it be animated?',
    content: 'Yes! You can use the transition prop to configure the animation.',
  },
]
</script>

<template>
  <AccordionRoot
    class="bg-mauve6 w-[300px] rounded-md shadow-[0_2px_10px] shadow-black/5"
    default-value="item-1"
    type="single"
    :collapsible="true"
  >
    <template
      v-for="item in accordionItems"
      :key="item.value"
    >
      <AccordionItem
        class="focus-within:shadow-mauve12 mt-px overflow-hidden first:mt-0 first:rounded-t last:rounded-b focus-within:relative focus-within:z-10 focus-within:shadow-[0_0_0_2px]"
        :value="item.value"
      >
        <AccordionHeader class="flex">
          <AccordionTrigger class="text-grass11 shadow-mauve6 hover:bg-mauve2 flex h-[45px] flex-1 cursor-default items-center justify-between bg-white px-5 text-[15px] leading-none shadow-[0_1px_0] outline-none group">
            <span>{{ item.title }}</span>
            <Icon
              icon="radix-icons:chevron-down"
              class="text-green10 ease-[cubic-bezier(0.87,_0,_0.13,_1)] transition-transform duration-300 group-data-[state=open]:rotate-180"
              aria-label="Expand/Collapse"
            />
          </AccordionTrigger>
        </AccordionHeader>
        <AccordionContent class="text-mauve11 bg-mauve2 data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp overflow-hidden text-[15px]">
          <div class="px-5 py-4">
            {{ item.content }}
          </div>
        </AccordionContent>
      </AccordionItem>
    </template>
  </AccordionRoot>
</template>

特点

  • 完整键盘导航。
  • 支持水平/垂直方向。
  • 支持从右到左方向。
  • 可以展开一个或多个项目。
  • 可以是受控或不受控的。

安装

从命令行安装组件。

sh
$ npm add radix-vue

解剖

导入所有部分并将它们拼凑在一起。

vue
<script setup>
import { AccordionContent, AccordionHeader, AccordionItem, AccordionRoot, AccordionTrigger } from 'radix-vue'
</script>

<template>
  <AccordionRoot>
    <AccordionItem>
      <AccordionHeader>
        <AccordionTrigger />
      </AccordionHeader>
      <AccordionContent />
    </AccordionItem>
  </AccordionRoot>
</template>

API 参考

包含手风琴的所有部分

道具默认值类型
as
'div'
AsTag | 组件

此组件应渲染成的元素或组件。可以被 asChild 覆盖

asChild
布尔值

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以获取更多详细信息。

collapsible
false
布尔值

当类型为“single”时,允许在单击打开项目的触发器时关闭内容。当类型为“multiple”时,此属性无效。

defaultValue
字符串 | 字符串数组

项目(s)的默认活动值。

当您不需要控制项目(s)的状态时使用。

dir
'ltr' | 'rtl'

手风琴在适用时的阅读方向。如果省略,则假定为 LTR(从左到右)阅读模式。

disabled
false
布尔值

true 时,阻止用户与手风琴及其所有项目交互

modelValue
字符串 | 字符串数组

活动项目(s)的受控值。

当您需要控制项目的状态时使用。可以使用 v-model 绑定

orientation
'vertical'
'vertical' | 'horizontal'

手风琴的方向。

type
'single' | 'multiple'

确定一次可以按下“single”或“multiple”个项目。

如果定义了 v-modeldefaultValue 中的任何一个,此属性将被忽略,因为类型将从值推断出来。

发出有效载荷
update:modelValue
[value: string | string[]]

当项目的展开状态发生变化时调用的事件处理程序

插槽(默认)有效载荷
modelValue
字符串 | 字符串数组 | 未定义

当前活动值

数据属性价值
[data-orientation]"vertical" | "horizontal"

项目

包含可折叠部分的所有部分。

道具默认值类型
as
'div'
AsTag | 组件

此组件应渲染成的元素或组件。可以被 asChild 覆盖

asChild
布尔值

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以获取更多详细信息。

disabled
布尔值

手风琴项目是否被禁用用户交互。当 true 时,阻止用户与项目交互。

value*
字符串

手风琴项目的字符串值。手风琴中的所有项目都应使用唯一的值。

插槽(默认)有效载荷
open
布尔值

当前打开状态

数据属性价值
[data-state]"open" | "closed"
[data-disabled]禁用时出现
[data-orientation]"vertical" | "horizontal"

包装 AccordionTrigger。使用 asChild 属性将其更新为页面中合适的标题级别。

道具默认值类型
as
'h3'
AsTag | 组件

此组件应渲染成的元素或组件。可以被 asChild 覆盖

asChild
布尔值

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以获取更多详细信息。

数据属性价值
[data-state]"open" | "closed"
[data-disabled]禁用时出现
[data-orientation]"vertical" | "horizontal"

触发器

切换其关联项目的折叠状态。它应该嵌套在 AccordionHeader 中。

道具默认值类型
as
'div'
AsTag | 组件

此组件应渲染成的元素或组件。可以被 asChild 覆盖

asChild
布尔值

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以获取更多详细信息。

数据属性价值
[data-state]"open" | "closed"
[data-disabled]禁用时出现
[data-orientation]"vertical" | "horizontal"

内容

包含项目的可折叠内容。

道具默认值类型
as
'div'
AsTag | 组件

此组件应渲染成的元素或组件。可以被 asChild 覆盖

asChild
布尔值

将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。

阅读我们的 组合 指南以获取更多详细信息。

数据属性价值
[data-state]"open" | "closed"
[data-disabled]禁用时出现
[data-orientation]"vertical" | "horizontal"
CSS 变量描述
--radix-accordion-content-width
内容打开/关闭时的宽度
--radix-accordion-content-height
内容打开/关闭时的高度

示例

默认展开

使用 defaultValue 属性定义默认打开的项目。

vue
<template>
  <AccordionRoot
    type="single"
    default-value="item-2"
  >
    <AccordionItem value="item-1">

    </AccordionItem>
    <AccordionItem value="item-2">

    </AccordionItem>
  </AccordionRoot>
</template>

允许折叠所有项目

使用 collapsible 属性允许所有项目关闭。

vue
<template>
  <AccordionRoot
    type="single"
    collapsible
  >
    <AccordionItem value="item-1">

    </AccordionItem>
    <AccordionItem value="item-2">

    </AccordionItem>
  </AccordionRoot>
</template>

多个项目同时打开

type 属性设置为 multiple 以启用一次打开多个项目。

vue
<template>
  <AccordionRoot type="multiple">
    <AccordionItem value="item-1">

    </AccordionItem>
    <AccordionItem value="item-2">

    </AccordionItem>
  </AccordionRoot>
</template>

打开时旋转图标

您可以添加额外的装饰元素,例如斜杠,并在项目打开时旋转它。

vue
// index.vue
<script setup>
import { AccordionContent, AccordionHeader, AccordionItem, AccordionRoot, AccordionTrigger } from 'radix-vue'
import { Icon } from '@iconify/vue'
import './styles.css'
</script>

<template>
  <AccordionRoot type="single">
    <AccordionItem value="item-1">
      <AccordionHeader>
        <AccordionTrigger class="AccordionTrigger">
          <span>Trigger text</span>
          <Icon
            icon="radix-icons:chevron-down"
            class="AccordionChevron"
          />
        </AccordionTrigger>
      </AccordionHeader>
      <AccordionContent></AccordionContent>
    </AccordionItem>
  </AccordionRoot>
</template>
css
/* styles.css */
.AccordionChevron {
  transition: transform 300ms;
}
.AccordionTrigger[data-state="open"] > .AccordionChevron {
  transform: rotate(180deg);
}

水平方向

使用 orientation 属性创建水平手风琴

vue
<template>
  <AccordionRoot orientation="horizontal">
    <AccordionItem value="item-1">

    </AccordionItem>
    <AccordionItem value="item-2">

    </AccordionItem>
  </AccordionRoot>
</template>

动画内容大小

使用 --radix-accordion-content-width 和/或 --radix-accordion-content-height CSS 变量来动画内容打开/关闭时的尺寸

vue
// index.vue
<script setup>
import { AccordionContent, AccordionHeader, AccordionItem, AccordionRoot, AccordionTrigger } from 'radix-vue'
import './styles.css'
</script>

<template>
  <AccordionRoot type="single">
    <AccordionItem value="item-1">
      <AccordionHeader></AccordionHeader>
      <AccordionContent class="AccordionContent">

      </AccordionContent>
    </AccordionItem>
  </AccordionRoot>
</template>
css
/* styles.css */
.AccordionContent {
  overflow: hidden;
}
.AccordionContent[data-state="open"] {
  animation: slideDown 300ms ease-out;
}
.AccordionContent[data-state="closed"] {
  animation: slideUp 300ms ease-out;
}

@keyframes slideDown {
  from {
    height: 0;
  }
  to {
    height: var(--radix-accordion-content-height);
  }
}

@keyframes slideUp {
  from {
    height: var(--radix-accordion-content-height);
  }
  to {
    height: 0;
  }
}

无障碍性

符合 手风琴 WAI-ARIA 设计模式

键盘交互

关键描述
空格
当焦点在折叠部分的 AccordionTrigger 上时,展开该部分。
输入
当焦点在折叠部分的 AccordionTrigger 上时,展开该部分。
制表符
将焦点移动到下一个可聚焦元素。
Shift + Tab
将焦点移动到上一个可聚焦元素。
向下箭头
orientationvertical 时,将焦点移动到下一个 AccordionTrigger
向上箭头
orientationvertical 时,将焦点移动到上一个 AccordionTrigger
向右箭头
orientationhorizontal 时,将焦点移动到下一个 AccordionTrigger
向左箭头
orientationhorizontal 时,将焦点移动到上一个 AccordionTrigger
主页
当焦点在 AccordionTrigger 上时,将焦点移动到开始 AccordionTrigger
结尾
当焦点在 AccordionTrigger 上时,将焦点移动到最后一个 AccordionTrigger