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 prop | v3 位置 | 说明 |
|---|---|---|
selectedKeys | Accordion | 已重命名为 expandedKeys;类型为 Iterable<Key> |
defaultSelectedKeys | Accordion | 已重命名为 defaultExpandedKeys |
onSelectionChange | Accordion | 已重命名为 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→ v3default - v2
shadow→ v3surface - v2
bordered→ v3default+ 添加边框类 - v2
splitted→ v3default+ 为各项添加背景色与间距 / 外边距
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]总结
- 组件结构:必须使用复合组件,而不是仅靠 props 拼装。
- 状态 props:
selectedKeys→expandedKeys,onSelectionChange→onExpandedChange。 - 多段展开:
selectionMode="multiple"→allowsMultipleExpanded={true}。 - 条目标识:展开状态用
id;列表调和仍使用 React 的key。 - 变体:由 4 种缩减为 2 种。
- 已移除的 props:大量便捷 props 已移除;请改用 Tailwind CSS 类。
- 内容结构:标题、副标题与前置内容需手动放入
Trigger。 - 指示器:必须显式渲染;不再自动生成指示器。