Accordion
手风琴:支持单项 / 多项展开,标题可带图标,受控 / 非受控双支持,grid 高度动画,符合 WAI-ARIA 手风琴模式。
安装
添加组件
pnpm dlx @elyri/cli@latest add accordion示例
分隔线
默认样式,条目间以分隔线堆叠,适合 FAQ 列表。
Orders are packed within 24 hours and shipped the next business day. You will get a tracking link by email as soon as the parcel leaves the warehouse.
Yes. Unopened items can be returned within 30 days of delivery for a full refund, no questions asked.
Every product includes a two-year limited warranty.
import { Accordion } from './components/elyri/Accordion';
export function Example() {
return (
<Accordion defaultValue="shipping">
<Accordion.Item value="shipping">
<Accordion.Trigger>When will my order ship?</Accordion.Trigger>
<Accordion.Content>
Orders are packed within 24 hours and shipped the next business day. You will get a tracking link by
email as soon as the parcel leaves the warehouse.
</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="returns">
<Accordion.Trigger>Can I return a purchase?</Accordion.Trigger>
<Accordion.Content>
Yes. Unopened items can be returned within 30 days of delivery for a full refund, no questions asked.
</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="warranty" disabled>
<Accordion.Trigger>Is there a warranty?</Accordion.Trigger>
<Accordion.Content>Every product includes a two-year limited warranty.</Accordion.Content>
</Accordion.Item>
</Accordion>
);
}卡片
每条目一张卡片,展开时高亮描边并浮起阴影。
Open Settings, choose Security, then click Reset password. We email you a link that stays valid for one hour.
Every invoice lives under Billing → History and can be downloaded as a PDF at any time.
Workspace owners can invite unlimited members from the Team page. Roles control what each member can change.
import { Accordion } from './components/elyri/Accordion';
export function Example() {
return (
<Accordion defaultValue="account" variant="separated">
<Accordion.Item value="account">
<Accordion.Trigger>How do I reset my password?</Accordion.Trigger>
<Accordion.Content>
Open Settings, choose Security, then click Reset password. We email you a link that stays valid for
one hour.
</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="billing">
<Accordion.Trigger>Where are my invoices?</Accordion.Trigger>
<Accordion.Content>
Every invoice lives under Billing → History and can be downloaded as a PDF at any time.
</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="team">
<Accordion.Trigger>Can I invite my team?</Accordion.Trigger>
<Accordion.Content>
Workspace owners can invite unlimited members from the Team page. Roles control what each member can
change.
</Accordion.Content>
</Accordion.Item>
</Accordion>
);
}可收起
开启 collapsible 后,再次点击已展开项可将其收起。
Run npx @elyri/cli add accordion and the component source is copied straight into your project.
Yes. Every color, radius and shadow comes from CSS variables, so overriding a handful of tokens reskins the whole component.
import { Accordion } from './components/elyri/Accordion';
export function Example() {
return (
<Accordion defaultValue="install" collapsible>
<Accordion.Item value="install">
<Accordion.Trigger>How do I install Elyri?</Accordion.Trigger>
<Accordion.Content>
Run npx @elyri/cli add accordion and the component source is copied straight into your project.
</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="theme">
<Accordion.Trigger>Can I restyle it?</Accordion.Trigger>
<Accordion.Content>
Yes. Every color, radius and shadow comes from CSS variables, so overriding a handful of tokens
reskins the whole component.
</Accordion.Content>
</Accordion.Item>
</Accordion>
);
}多项展开 + 图标
type="multiple" 允许同时展开多项,Trigger 的 icon 给标题加上前置图标。
Colors, radii and shadows all read from CSS variables, so a theme change is a handful of overrides.
tsup emits ESM, CJS and type declarations for every package on each build.
Triggers expose aria-expanded and panels become labelled regions, matching the WAI-ARIA pattern.
import { Accordion } from './components/elyri/Accordion';
const SparkIcon = (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<path d="M12 3v18M3 12h18M5.6 5.6l12.8 12.8M18.4 5.6 5.6 18.4" />
</svg>
);
export function Example() {
return (
<Accordion type="multiple" defaultValue={['design', 'build']} variant="separated">
<Accordion.Item value="design">
<Accordion.Trigger icon={SparkIcon}>Design tokens</Accordion.Trigger>
<Accordion.Content>
Colors, radii and shadows all read from CSS variables, so a theme change is a handful of overrides.
</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="build">
<Accordion.Trigger icon={SparkIcon}>Build pipeline</Accordion.Trigger>
<Accordion.Content>tsup emits ESM, CJS and type declarations for every package on each build.</Accordion.Content>
</Accordion.Item>
<Accordion.Item value="a11y">
<Accordion.Trigger icon={SparkIcon}>Accessibility</Accordion.Trigger>
<Accordion.Content>
Triggers expose aria-expanded and panels become labelled regions, matching the WAI-ARIA pattern.
</Accordion.Content>
</Accordion.Item>
</Accordion>
);
}属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type | 'single' | 'multiple' | 'single' | 展开模式:single(每次只展开一项)/ multiple(可同时展开多项) |
value | string | string[] | — | 受控展开值;multiple 下为 string[] |
defaultValue | string | string[] | — | 非受控初始值;multiple 下为 string[] |
onValueChange | (value: string | string[]) => void | — | 展开值变化回调,签名随 type 变化(string / string[]) |
collapsible | boolean | false | 允许再次点击已展开项将其收起(multiple 天然可收起) |
variant | 'lined' | 'separated' | 'lined' | 外观样式:lined(分隔线堆叠)/ separated(独立卡片) |
Accordion.Item | { value: string; disabled?: boolean } & HTMLAttributes | — | 单个条目,value 关联标题与面板,可禁用 |
Accordion.Trigger | { icon?: ReactNode } & ButtonHTMLAttributes | — | 标题按钮,外层自动包裹 h3;icon 为前置图标 |
Accordion.Content | HTMLAttributes | — | 面板,始终留在 DOM 中,收起时仅隐藏 |
...rest | HTMLAttributes | — | 其余属性透传给原生 div |