Accordion
基础布局基于 Bootstrap 5 的 Accordion 手风琴组件,通过上下文将 Accordion、AccordionItem、AccordionHeader、AccordionButton、AccordionCollapse 与 AccordionBody 按 eventKey 关联,支持单个/多个条目同时展开、去边框样式、受控与非受控模式、自定义触发器与完整的 ARIA 无障碍属性;折叠过渡由 useReducer 状态机统一驱动,双重 requestAnimationFrame 保证首次挂载动画生效,并自适应 prefers-reduced-motion 偏好,自定义过渡变量统一使用 --rbs-accordion-* 前缀
Component Demo
Basic usage and examples of the Accordion component
基础用法
Accordion 渲染 `div.accordion`,AccordionItem 渲染 `div.accordion-item`,AccordionHeader 渲染 `h2.accordion-header` 并在内部渲染 `button.accordion-button`,AccordionBody 渲染 `div.accordion-body`,与 Bootstrap 的手风琴结构一一对应
去边框样式
flush 为容器追加 `accordion-flush` 类,对应 Bootstrap 的去边框样式
多个条目同时展开
alwaysOpen 允许同一时刻展开多个条目,激活状态由 key 数组维护,点击已激活条目将其移出数组
受控模式
传入 activeKey 后 Accordion 变为受控组件,切换状态完全由 onSelect 驱动的外部 state 决定;alwaysOpen 模式下 activeKey 使用数组
自定义触发器
3 个条目
useAccordionButton 把切换逻辑从样式结构中解耦出来,可搭配任意按钮样式;AccordionButton 与 AccordionCollapse 同样支持独立组合使用
API Documentation
Complete API reference for the Accordion component
Props
Accordion
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
activeKey | AccordionEventKey | AccordionEventKey[] | - | 受控激活 key,传入单个 key 或 key 数组(配合 alwaysOpen)后展开状态完全由外部控制,需配合 onSelect 更新 |
defaultActiveKey | AccordionEventKey | AccordionEventKey[] | - | 非受控模式下的初始激活 key,单个 key 或 key 数组 |
alwaysOpen | boolean | false | 允许多个条目同时展开,点击已展开的条目仅折叠自身 |
flush | boolean | false | 渲染 `accordion-flush` 类,移除外层边框与圆角 |
id | string | 自动生成 | 容器 id 与无障碍 id 前缀,同时渲染到根元素上,并为按钮生成 `{id}-heading-{key}`、为折叠面板生成 `{id}-collapse-{key}` 并互相关联;未设置时仅使用 useId 自动生成关联 id |
onSelect | AccordionSelectCallback | - | 选择回调,在任意条目按钮点击且 key 不为 null 时触发 |
as | ElementType | 'div' | 根元素标签,默认渲染 `div.accordion` |
AccordionItem
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
eventKey | AccordionEventKey | 自动生成 | 条目唯一 key,未设置时使用 useId 自动生成;Header/Button/Collapse/Body 通过条目上下文消费该 key |
as | ElementType | 'div' | 根元素标签,默认渲染 `div.accordion-item` |
AccordionHeader
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
as | ElementType | 'h2' | 标题标签,默认渲染 `h2.accordion-header` |
onClick | (event: MouseEvent<HTMLElement>) => void | - | 标题点击回调,透传给内部的 AccordionButton |
children | ReactNode | - | 标题内容,渲染在 accordion-button 内部 |
AccordionButton
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
as | ElementType | 'button' | 渲染的元素标签,默认渲染 `button.accordion-button` |
onClick | (event: MouseEvent<HTMLElement>) => void | - | 点击回调,触发后事件继续冒泡到 Accordion 切换展开状态,`preventDefault` 可阻止切换 |
type | 'button' | 'reset' | 'submit' | 'button' | 渲染为原生按钮时的 type 属性 |
AccordionCollapse
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
eventKey | AccordionEventKey | 条目上下文 key | 关联 Accordion 激活状态的 key,覆盖所在 AccordionItem 的 eventKey |
dimension | AccordionCollapseDimension | 'height' | 折叠维度,'height' 为垂直折叠(高度过渡),'width' 为水平折叠(宽度过渡,对应 Bootstrap 的 collapse-horizontal) |
duration | number | 300 | 展开与折叠过渡动画时长(毫秒),系统开启减少动态效果时自动为 0 |
onEnter | () => void | - | 展开开始(show)时触发,此时元素即将挂载并开始测量内容尺寸 |
onEntering | () => void | - | 展开过渡开始(元素已挂载并完成尺寸测量,高度/宽度开始过渡)时触发 |
onEntered | () => void | - | 展开过渡完成(shown)时触发,此时元素尺寸恢复为 auto,内容可自然撑开 |
onExit | () => void | - | 折叠开始(hide)时触发,此时会先测量并冻结当前尺寸再开始收缩 |
onExiting | () => void | - | 折叠过渡开始(尺寸开始向 0 收缩)时触发 |
onExited | () => void | - | 折叠过渡完成(hidden)时触发,此时元素已卸载 |
children | ReactNode | - | 折叠面板内容,渲染 `div.accordion-collapse`,过渡状态由 useReducer 驱动并渲染为 data-status 属性 |
AccordionBody
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
as | ElementType | 'div' | 渲染的元素标签,默认渲染 `div.accordion-body` |
children | ReactNode | - | 正文内容,自动包裹在 AccordionCollapse 内 |
...rest | AccordionCollapseProps | - | 透传 AccordionCollapse 属性(如 dimension、duration、onEnter、onExited 等) |
useAccordionButton
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
eventKey | AccordionEventKey | - | 目标条目的 key,未设置时回退到所在 AccordionItem 的 eventKey |
onClick | (event: MouseEvent<HTMLElement>) => void | - | 点击回调,触发后继续执行切换逻辑 |
返回 | AccordionButtonHandleProps | - | 返回可展开到自定义触发器上的按钮属性:onClick、aria-expanded、aria-controls 与 id |
Common Props
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
children | ReactNode | - | 组件内容 |
className | string | - | 自定义类名 |
...rest | HTMLAttributes | - | 透传原生元素属性(如 onClick、style、role 等) |
Type Definitions
AccordionEventKey
手风琴条目 key 类型
export type AccordionEventKey = null | number | string;AccordionSelectCallback
手风琴选择回调类型
export type AccordionSelectCallback = (eventKey: AccordionEventKey, event: SyntheticEvent) => void;AccordionProps
Accordion 容器组件属性接口
export interface AccordionProps extends Omit<HTMLAttributes<HTMLElement>, 'onSelect'> {
activeKey?: AccordionEventKey | AccordionEventKey[];
alwaysOpen?: boolean;
as?: ElementType;
children?: ReactNode;
className?: string;
defaultActiveKey?: AccordionEventKey | AccordionEventKey[];
flush?: boolean;
id?: string;
onSelect?: AccordionSelectCallback;
}AccordionContextValue
手风琴上下文,供各子组件与 useAccordionButton 消费
export interface AccordionContextValue {
activeKeys: AccordionEventKey[];
alwaysOpen: boolean;
id?: string;
onSelect: AccordionSelectCallback;
}AccordionItemProps
手风琴条目组件属性接口
export interface AccordionItemProps extends HTMLAttributes<HTMLElement> {
as?: ElementType;
children?: ReactNode;
className?: string;
eventKey?: AccordionEventKey;
}AccordionItemContextValue
手风琴条目上下文,供 Header/Button/Collapse/Body 消费
export interface AccordionItemContextValue {
eventKey: AccordionEventKey;
}AccordionHeaderProps
手风琴标题组件属性接口
export interface AccordionHeaderProps extends Omit<HTMLAttributes<HTMLElement>, 'onClick'> {
as?: ElementType;
children?: ReactNode;
className?: string;
onClick?: (event: MouseEvent<HTMLElement>) => void;
}AccordionButtonProps
手风琴标题按钮组件属性接口
export interface AccordionButtonProps extends Omit<HTMLAttributes<HTMLElement>, 'onClick'> {
as?: ElementType;
children?: ReactNode;
className?: string;
onClick?: (event: MouseEvent<HTMLElement>) => void;
type?: 'button' | 'reset' | 'submit';
}AccordionButtonHandleProps
useAccordionButton 返回的按钮属性接口
export interface AccordionButtonHandleProps {
'aria-controls'?: string;
'aria-expanded': boolean;
id?: string;
onClick: (event: MouseEvent<HTMLElement>) => void;
}AccordionAnimationStatus
AccordionCollapse 过渡动画状态类型,由 useReducer 统一驱动
export type AccordionAnimationStatus = 'closed' | 'closing' | 'opened' | 'opening';AccordionCollapseDimension
AccordionCollapse 折叠维度类型
export type AccordionCollapseDimension = 'height' | 'width';AccordionCollapseProps
手风琴折叠面板组件属性接口
export interface AccordionCollapseProps extends HTMLAttributes<HTMLDivElement> {
children?: ReactNode;
className?: string;
dimension?: AccordionCollapseDimension;
duration?: number;
eventKey?: AccordionEventKey;
onEnter?: () => void;
onEntered?: () => void;
onEntering?: () => void;
onExit?: () => void;
onExited?: () => void;
onExiting?: () => void;
}AccordionBodyProps
手风琴正文组件属性接口
export interface AccordionBodyProps extends Omit<AccordionCollapseProps, 'children' | 'eventKey'> {
as?: ElementType;
children?: ReactNode;
}