coss Accordion 组件实战指南:从安装、受控展开到 Radix 迁移
【免费下载链接】app🎯 All you need. Nothing you don't. Open source project management that works for you, not against you.项目地址: https://gitcode.com/GitHub_Trending/app116/app
本指南以开源仓库 coss skill 参考文档 为核心,系统讲解 coss 组件体系中 Accordion(手风琴/可展开多区块内容区)的安装方式、规范导入、最小实现、多面板展开与受控模式,并结合本仓库中真实的 site 端实现 与 web 端实现 深入剖析其底层原理与常见陷阱。读完本文,你将掌握如何在 React + Tailwind CSS v4 + Base UI 项目中正确搭建、定制和迁移 coss Accordion,并规避从 Radix/shadcn 迁移时最容易踩的坑。
何时使用 coss Accordion
Accordion 用于组织可展开的多区块内容区域,是渐进式披露(progressive disclosure)的典型载体。根据原文档(accordion.md),它适合两类典型场景:
- 可展开的多区块内容:例如长文档的分节导航、配置面板中按类别收纳的设置项;
- FAQ 与设置页:需要把大量问答或选项压缩进有限空间,用户按需展开查看。
与之相对,若只需要一个独立的"展开/收起"区域(无多条目联动),应优先考虑 collapsible 原语;若需要多标签页互斥切换面板,则应选用 tabs 原语。组件选型可对照 component-registry.md 中的索引快速决策。
安装:CLI 一键添加与手动依赖
方式一:shadcn CLI 添加(推荐)
在项目根目录(需已配置 shadcn 与 Tailwind CSS v4)执行:
npx shadcn@latest add @coss/accordion根据 coss CLI 参考,项目使用 pnpm 或 bun 时应始终使用对应的包运行器,避免全局二进制版本漂移:
pnpm dlx shadcn@latest add @coss/accordion bunx --bun shadcn@latest add @coss/accordion建议在正式写入前使用预览模式确认改动范围(组件可能已存在于本地,或你只想先检查将要生成的文件):
npx shadcn@latest add @coss/accordion --dry-run npx shadcn@latest add @coss/accordion --diff npx shadcn@latest add @coss/accordion --view方式二:手动安装依赖
CLI 之外的"手动安装"路径,核心是按组件文档安装其声明的最小依赖。Accordion 的运行时依赖是 Base UI 的 React 包:
npm install @base-ui/react安装完成后,将本仓库 apps/site/components/ui/accordion.tsx(或 web 端 apps/web/src/components/ui/accordion.tsx)中导出的四个组件复制到你自己项目的components/ui/accordion.tsx,并把@/lib/cn等导入别名替换为项目实际的别名配置。
手动安装注意事项(见 cli.md):CLI 方式会自动接线所需的主题 token;手动方式若涉及
destructive-foreground、info、success、warning等颜色家族,需要自行从 coss 样式文档补齐对应 token。
规范导入
无论哪种安装方式,组件文件最终都从项目的 ui 目录导出以下四个成员:
import { Accordion, AccordionItem, AccordionPanel, AccordionTrigger, } from "@/components/ui/accordion"对照仓库源码 apps/site/components/ui/accordion.tsx 可以看到导出集合与文档完全一致:Accordion(根)、AccordionItem(条目)、AccordionTrigger(触发器)、AccordionPanel(内容面板),并且额外以别名AccordionContent导出AccordionPanel,兼容 Radix 时代的命名习惯。
最小模式:一个可展开的条目
<Accordion defaultValue={["item-1"]}> <AccordionItem value="item-1"> <AccordionTrigger>What is Base UI?</AccordionTrigger> <AccordionPanel> Base UI is a library of high-quality unstyled React components. </AccordionPanel> </AccordionItem> </Accordion>要点拆解:
Accordion接收字符串数组形式的defaultValue,这与 Base UI 的受控模型一致——即便只有一个面板,也要写成数组["item-1"];- 每个
AccordionItem必须有稳定且唯一的value,它是条目身份标识,也是受控行为的依据; AccordionTrigger与AccordionPanel必须是同一个AccordionItem的直接子级,不能跨条目混放。
源码实现印证
从仓库组件实现(apps/site/components/ui/accordion.tsx)可以看到Accordion直接透传AccordionPrimitive.Root的全部 props,并挂上data-slot="accordion"供 Tailwind v4 样式选择器定位;AccordionTrigger内部用AccordionPrimitive.Header包裹真实按钮,并附带一个旋转指示器ChevronDownIcon(见 第 28-42 行);AccordionPanel则通过--accordion-panel-height变量与transition-[height]实现展开/收起的高度动画(见 第 47-61 行)。这意味着你使用四个组件时,开箱即获得无障碍语义(Header + 按钮结构)、键盘焦点环与平滑动画,无需自行实现。
进阶模式:多开、受控与数据映射
多面板同时展开
默认(不传multiple)时 Accordion 为单开模式,展开新面板会收起旧面板。若需要多个面板同时保持展开,显式传入multiple并给出多个默认值:
<Accordion multiple defaultValue={["item-1", "item-2"]}> <AccordionItem value="item-1"> <AccordionTrigger>Section 1</AccordionTrigger> <AccordionPanel>Content 1</AccordionPanel> </AccordionItem> <AccordionItem value="item-2"> <AccordionTrigger>Section 2</AccordionTrigger> <AccordionPanel>Content 2</AccordionPanel> </AccordionItem> </Accordion>受控模式:外部状态驱动
当需要由外部逻辑(如"全部展开"按钮、URL 参数同步、搜索高亮定位)驱动面板状态时,使用value+onValueChange完全受控:
const [value, setValue] = useState<string[]>(["item-1"]) <Accordion value={value} onValueChange={setValue}> {/* items... */} </Accordion>再次强调:受控value永远是string[],而不是单个字符串或布尔值。这一约定与 Base UI 的 Accordion API 完全一致,也是从 Radix 迁移时最常见的认知断层。
数据映射(mapped items)模式
配合value数组,最常见的生产形态是遍历数据源批量渲染条目:
const faqs = [ { id: "q1", question: "How does coss work?", answer: "..." }, { id: "q2", question: "Is it accessible?", answer: "..." }, ]; <Accordion multiple defaultValue={faqs.map((f) => f.id)}> {faqs.map((f) => ( <AccordionItem key={f.id} value={f.id}> <AccordionTrigger>{f.question}</AccordionTrigger> <AccordionPanel>{f.answer}</AccordionPanel> </AccordionItem> ))} </Accordion>该模式对应粒子示例p-accordion-1(mapped items)、p-accordion-2(单开静态区块)、p-accordion-3(多开行为)、p-accordion-4(受控 value + 外部动作),完整列表见 accordion.md。
从 Radix / shadcn 迁移:模型差异对照
coss 的 Accordion 与 Radix 版本在 API 表面上高度相似,但状态模型不同。根据 migration.md 中的对照模板:
// shadcn/Radix:type="single" + collapsible + 字符串 defaultValue <Accordion type="single" collapsible defaultValue="item-1"> <AccordionItem value="item-1">...</AccordionItem> </Accordion> // coss/Base UI:multiple 布尔值 + 数组 defaultValue <Accordion defaultValue={["item-1"]}> <AccordionItem value="item-1">...</AccordionItem> </Accordion>迁移时只需记住三个等价替换:
| Radix 心智模型 | coss / Base UI 模型 |
|---|---|
type="single"/type="multiple" | 布尔属性multiple(缺省即 single) |
defaultValue="item-1"(字符串) | defaultValue={["item-1"]}(字符串数组) |
受控value为标量 | 受控value恒为string[] |
此外,coss 迁移规则(migration.md)强调:不要假设所有 shadcn 模式都能 1:1 平移;对触发器类组件要逐原语核对文档中的 trigger/content 层级;asChild仅在明确支持render的部件上替换为render。
常见陷阱清单
原文档(accordion.md)归纳了四个高频错误,全部可在仓库实现中找到对应约束:
- 把
AccordionTrigger/AccordionPanel放在AccordionItem之外——破坏条目的子级结构,导致状态无法归属到对应条目(实现见 apps/site/components/ui/accordion.tsx); - 在
AccordionItem上省略value——条目失去身份标识,展开状态无法追踪,受控模式直接失效; - 套用 Radix 的
type="single" | "multiple"心智——coss 用布尔multiple+ 数组值,混用会产生类型错误或行为异常; - 把受控
value当成标量——必须使用string[],否则受控行为不成立。
自检清单
在提交 coss Accordion 代码前,对照 SKILL.md 的输出清单逐项确认:
- 导入路径与导出成员与组件文档一致(
Accordion/AccordionItem/AccordionPanel/AccordionTrigger); - 每个
AccordionItem都有稳定唯一的value,Trigger与Panel是同一 item 的子级; - 受控用法使用
string[]类型的value+onValueChange; - 无障碍结构完整:
AccordionTrigger内含Header,可键盘操作,焦点环样式保留; - 迁移代码已用迁移规则核对(migration.md),未保留
type等 Radix 专属 props。
按此清单核对后,coss Accordion 即可安全落地到 FAQ、设置页等渐进式披露场景,并获得与仓库 site / web 实现一致的体验质量。
【免费下载链接】app🎯 All you need. Nothing you don't. Open source project management that works for you, not against you.项目地址: https://gitcode.com/GitHub_Trending/app116/app
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考