Skip to content
Lenso UI

Accordion

Accordion 从 HeroUI v2 到 v3 的迁移指南。

完整的 API 参考、样式指南与高级示例请参阅 v3 Accordion 文档。本指南只关注从 HeroUI v2 的迁移。

结构变化

在 v2 中,AccordionItem 是一个独立组件,通过 props 接收标题、副标题、内容等元素:

import { Accordion, AccordionItem } from "@lenso/ui";
export default function App() {  return (    <Accordion>      <AccordionItem        key="1"        title="Accordion 1"      >        Content here      </AccordionItem>      <AccordionItem        key="2"        title="Accordion 2"      >        Content here      </AccordionItem>    </Accordion>  );}

在 v3 中,Accordion 采用复合组件模式,并使用显式子组件进行组合:

import { Accordion } from "@lenso/ui";
export default function App() {  return (    <Accordion>      <Accordion.Item id="1">        <Accordion.Heading>          <Accordion.Trigger>            Accordion 1            <Accordion.Indicator />          </Accordion.Trigger>        </Accordion.Heading>        <Accordion.Panel>          <Accordion.Body>Content here</Accordion.Body>        </Accordion.Panel>      </Accordion.Item>      <Accordion.Item id="2">        <Accordion.Heading>          <Accordion.Trigger>            Accordion 2            <Accordion.Indicator />          </Accordion.Trigger>        </Accordion.Heading>        <Accordion.Panel>          <Accordion.Body>Content here</Accordion.Body>        </Accordion.Panel>      </Accordion.Item>    </Accordion>  );}

主要变化

1. 组件结构

v2: 单个带 props 的 AccordionItem 组件
v3: 复合组件:Accordion.Item、Accordion.Heading、Accordion.Trigger、Accordion.Panel、Accordion.Body、Accordion.Indicator

2. Prop 变更

v2 propv3 位置说明
selectedKeysAccordion已重命名为 expandedKeys;类型为 Iterable<Key>
defaultSelectedKeysAccordion已重命名为 defaultExpandedKeys
onSelectionChangeAccordion已重命名为 onExpandedChange;签名为 (keys: Set<Key>) => void
selectionMode="multiple"Accordion使用 allowsMultipleExpanded(布尔值)
isCompact—已移除(请使用 Tailwind CSS,例如 text-sm、py-2)
hideIndicator—不渲染 <Accordion.Indicator /> 即可隐藏
disableAnimation、disableIndicatorAnimation、motionProps—已移除(不支持动画 / 请使用 CSS)
showDivider、dividerProps—已移除(请手动添加分隔线或使用 Divider)
keepContentMounted—已移除(v3 中内容始终挂载)
selectionBehavior、disallowEmptySelection—已移除(不适用)
itemClasses—在各项上使用 className
startContent—将内容放在 <Accordion.Trigger> 内
title、subtitle—将内容放在 <Accordion.Trigger> 内

3. 变体

v2 变体: light、shadow、bordered、splitted
v3 变体: default、surface

v3 的变体更精简。若要接近 v2 的视觉效果:

  • v2 light → v3 default
  • v2 shadow → v3 surface
  • v2 bordered → v3 default + 添加边框类
  • v2 splitted → v3 default + 为各项添加背景色与间距 / 外边距

4. 条目标识

v2: React 的 key 同时用于列表调和与展开状态。
v3: 在 Accordion.Item 上使用 id 标识展开状态;列表中仍可为各项保留 React 的 key。

迁移示例

受控状态

import { useState } from "react";import { Accordion, AccordionItem } from "@lenso/ui";
const [selectedKeys, setSelectedKeys] = useState(new Set(["1"]));
<Accordion   selectedKeys={selectedKeys}   onSelectionChange={setSelectedKeys}>  <AccordionItem key="1" title="Item 1">    Content 1  </AccordionItem>  <AccordionItem key="2" title="Item 2">    Content 2  </AccordionItem></Accordion>

副标题与前置内容

import { Icon } from "@iconify/react";
<Accordion>  <AccordionItem     key="1"    title="Accordion 1"    subtitle="Press to expand"    startContent={<Icon icon="gravity-ui:box" />}  >    Content here  </AccordionItem></Accordion>

自定义指示器

import { Icon } from "@iconify/react";
<Accordion>  <AccordionItem     key="1"    title="Item 1"    indicator={(props) => (      props.isOpen ? <Icon icon="mdi:minus" /> : <Icon icon="mdi:plus" />    )}  >    Content  </AccordionItem></Accordion>

禁用项与默认展开键

<Accordion   defaultExpandedKeys={["1"]}  disabledKeys={["2"]}>  <AccordionItem key="1" title="Item 1">    Content 1  </AccordionItem>  <AccordionItem key="2" title="Item 2">    Content 2  </AccordionItem></Accordion>

样式变化

v2:classNames prop

<AccordionItem   classNames={{    base: "custom-base",    title: "custom-title",    content: "custom-content"  }}/>

v3:在各子组件上使用 className

<Accordion.Item className="custom-base">  <Accordion.Heading>    <Accordion.Trigger className="custom-title">      Title      <Accordion.Indicator />    </Accordion.Trigger>  </Accordion.Heading>  <Accordion.Panel>    <Accordion.Body className="custom-content">      Content    </Accordion.Body>  </Accordion.Panel></Accordion.Item>

组件剖析

v3 Accordion 的结构如下:

Accordion (Root)  └── Accordion.Item      ├── Accordion.Heading      │   └── Accordion.Trigger      │       ├── [Your content: title, subtitle, icons, etc.]      │       └── Accordion.Indicator (optional)      └── Accordion.Panel          └── Accordion.Body              └── [Your content]

总结

  1. 组件结构:必须使用复合组件,而不是仅靠 props 拼装。
  2. 状态 props:selectedKeys → expandedKeys,onSelectionChange → onExpandedChange。
  3. 多段展开:selectionMode="multiple" → allowsMultipleExpanded={true}。
  4. 条目标识:展开状态用 id;列表调和仍使用 React 的 key。
  5. 变体:由 4 种缩减为 2 种。
  6. 已移除的 props:大量便捷 props 已移除;请改用 Tailwind CSS 类。
  7. 内容结构:标题、副标题与前置内容需手动放入 Trigger。
  8. 指示器:必须显式渲染;不再自动生成指示器。