跳转到内容

Accordion 手风琴 ​

一列可展开的区块,标题常驻,内容按需展开。

用法 ​

默认单开:展开一项即收起其余,defaultValue 只提供初始值,之后由组件自行维护

装 @xihan-ui/vue 与 @xihan-ui/styles 两个包,皮肤单独引一次。

组件结构 ​

加粗的是必需部件。

data-scope="accordion":root · item · item-separator · header · trigger · content · indicator

示例 ​

多项展开 ​

multiple 允许多项并存,展开集合恒为 string[],受控绑定即可获取它

value、defaultValue、multiple。

orientation 决定方向键走哪条轴,默认 vertical。

展开:basic、size

允许全部收起 ​

单开模式下最后一项默认无法收起,加 collapsible 后才能收起

点当前展开项的标题,它会收起,展开集合变成空数组。

指示器与禁用 ​

indicator 的朝向由 data-state 驱动,禁用项不可点击、方向键也跳过它

标题右侧那个箭头就是 indicator,展开时自动翻转。

颜色 ​

tone 落在展开态的标题上,六种颜色各预置一项展开做对照

tone="brand"

tone="neutral"

tone="success"

tone="warning"

tone="danger"

tone="info"

尺寸 ​

size 改变标题栏的高度、内边距与字号,三档并排对照

标题栏最矮,字号也最小。

不写 size 就是这一档。

标题栏最高,字号也最大。

嵌套 ​

content 中再放一组手风琴,内外两组各自维护展开集合,方向键也各自独立

次日达,节假日照常发货。

标题栏附加信息 ​

标题栏中的节点全部归作者,把计数与指示器包为一组排在末尾

还没有人认领。

指示器在前 ​

指示器写在标题之前即落到起始缘,标题用 auto 外边距占据余量

指示器在标题左边,展开时照样翻转。

缩小触发区域 ​

trigger 只包住指示器,标题文字留在 header 里,点标题不再展开

账户资料

只有右边那个按钮能展开这一段。

账单信息

自定义展开图标 ​

indicator 是可选部件,不渲染它就没有默认字形;标记由作者按展开集合自行绘制

同城次日达,跨省三日达。

变体 ​

ghost 不绘制外壳,outline 连成单一表面,subtle 用淡底;三档只改变与页面分开的方式

下单后 48 小时内发出。

下单后 48 小时内发出。

下单后 48 小时内发出。

设计指引 ​

何时使用 ​

  • 常见问题、设置分组等由标题即可判断是否需要展开的内容。
  • 内容较长,一次全部铺开会使页面失去结构。

何时不用 ​

  • 只有一块内容时,使用折叠区域。
  • 各块内容需要对照阅读时,直接铺开。
  • 各块是并列视图且同一时间只看一个时,使用标签页。

特性 ​

  • multiple 决定能否同时展开多项,collapsible 决定能否全部收起。
  • 指示器可置于标题前或标题后,图形可自定义。
  • 支持嵌套;触发区大小由作者决定。

组合 ​

  • 标题栏可以放置附加信息,如计数或状态徽标。

最佳实践 ​

  • 标题应说明区块内容,不依赖展开来发现。
  • 默认展开第一项,让用户看到内容的形态。

反模式 ​

  • 将关键信息放进折叠区块,用户不会逐个展开。
  • 展开时页面下方内容大幅跳动而没有滚动补偿。

API 参考 ​

产物 ​

层值
自定义元素<xh-accordion>
Vue 组件XhAccordionContent XhAccordionHeader XhAccordionIndicator XhAccordionItem XhAccordionItemSeparator XhAccordionRoot XhAccordionTrigger
组合式函数useAccordion
状态机accordionMachine
皮肤@xihan-ui/styles/accordion.css

Props ​

属性类型必填说明
collectionAccordionNode[]条目数据,标题文本、正文与禁用的事实源。提供后条目部件只需声明 value。 未提供时回到文本写在部件中、禁用写在条目上的方式。
valuestring[]展开集合,提供即受控。
defaultValuestring[]
multipleboolean允许多项同时展开;false 时展开一项即收起其余。
collapsibleboolean允许收起最后一个展开项,默认 false。
loopboolean方向键到达末尾是否回绕,默认 false。
disabledboolean整组禁用:所有条目都不可切换,条目上的 disabled 只能收紧不能放宽。
variantControlVariant形态:ghost 条目直接相邻不画容器(默认),outline 为单一连续表面,subtle 为淡底。默认 ghost。
orientationOrientation方向键轴向,默认 vertical。
dirDirection文字方向,默认 ltr;影响水平轴上 ArrowLeft / ArrowRight 的语义。
toneTone颜色:brand / neutral / success / warning / danger / info,决定使用哪组状态色。
sizeSize尺寸:sm / md / lg。
onValueChange(details: AccordionValueChangeDetails) => void展开集合变化回调。

AccordionNode ​

collection 的元素。

字段类型必填说明
valuestring是
labelstring标题文本;默认回退为 value。
contentstring正文;需要放置纯文本以外的内容时改用 content 插槽。
disabledboolean条目禁用:方向键跳过该条目,但它仍可聚焦、仍是导航起点。

事件 ​

自定义元素将载荷放在 detail;Vue 使用同名 emit。

事件载荷说明
value-changeAccordionValueChangeDetails展开集合变化;detail 为 { value: string[] }

React 适配器 props ​

只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。

React 组件属性类型必填说明
XhAccordionItemvaluestring是
XhAccordionItemdisabledboolean默认交给 connect 查询 collection,写死 false 会覆盖数据中的禁用。
XhAccordionRootrenderContent(node: AccordionNodeMeta) => ReactNode每个条目正文的自定义内容;未提供时使用 collection 中的 content。
XhAccordionRootchildrenReactNode

状态 ​

公开状态写入 data-state。

部件取值
item'open' | 'closed'
header'open' | 'closed'
trigger'open' | 'closed'
content'open' | 'closed'
indicator'open' | 'closed'

以下名称仅用于内部状态机。

状态:idle

事件:ITEM.TOGGLE · VALUE.SET · PRESS.START · PRESS.END

判据:canPress

connect API ​

getXxxProps() 返回对应部件的宿主属性。

成员类型说明
valuestring[]当前展开集合,单开模式下长度 ≤ 1。
collectionreadonly AccordionNodeMeta[]由 collection 推导的条目元信息,按数据顺序排列;未提供 collection 时为空数组。
setValue(next: string[]) => void
isOpen(value: string) => boolean
getRootProps() => T['element']
getItemProps(props: AccordionItemProps) => T['element']
getItemSeparatorProps() => T['element']
getHeaderProps(props: AccordionItemProps) => T['element']
getTriggerProps(props: AccordionItemProps) => T['button']
getContentProps(props: AccordionItemProps) => T['element']
getIndicatorProps(props: AccordionItemProps) => T['element']

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
Space / Enterfocus in trigger, not disabled展开/收起该条目的 content
ArrowDown / ArrowRightfocus in trigger, 按键与 orientation 同轴(dir=rtl 时左右键语义互换)焦点移到下一个 trigger,末条不回绕
ArrowUp / ArrowLeftfocus in trigger, 按键与 orientation 同轴(dir=rtl 时左右键语义互换)焦点移到上一个 trigger,首条不回绕
Homefocus in trigger焦点移到首个 trigger
Endfocus in trigger焦点移到末个 trigger
Tab / Shift+Tabfocus in trigger按文档序进出:每个 trigger 都是独立 Tab 停靠点,无 roving tabindex
Enter / Spaceheld in trigger, not disabled按住期间该 trigger 投影 data-pressed,与指针 :active 同一副按压面(disclosure trigger 只换面不缩放);抬起、失焦或整组转禁用撤下

ARIA ​

以下属性由 connect 生成。

部件属性值
item-separatoraria-hidden'true'
headeraria-level3
headerrole'heading'
triggeraria-controlscontent 部件的 id
triggeraria-disabled'true' | 'false'
triggeraria-expanded'true' | 'false'
contentaria-labelledbytrigger 部件的 id
contentrole'region'
indicatoraria-hidden'true'

样式参考 ​

皮肤 ​

@xihan-ui/styles/accordion.css 使用 [data-scope="accordion"][data-part="root"] 部件选择器,位于 xihan.components 与 xihan.motion 层。覆盖样式使用 xihan.overrides。

数据属性 ​

由 connect 生成;条件不成立时不输出无值属性。

部件属性值
rootdata-disabled''(条件成立时才出现)
rootdata-orientationprops.orientation
rootdata-sizeprops.size
rootdata-toneprops.tone
rootdata-variantprops.variant
itemdata-disabled''(条件成立时才出现)
itemdata-state'open' | 'closed'
headerdata-disabled''(条件成立时才出现)
headerdata-state'open' | 'closed'
triggerdata-disabled''(条件成立时才出现)
triggerdata-pressed''(条件成立时才出现)
triggerdata-state'open' | 'closed'
triggerdata-xh-action-control''
triggerdata-xh-action-display'always'
triggerdata-xh-action-profile'disclosure-trigger'
triggerdata-xh-action-sizeprops.size
triggerdata-xh-action-variant'ghost'
contentdata-instant''
contentdata-state'open' | 'closed'
indicatordata-disabled''(条件成立时才出现)
indicatordata-instant''
indicatordata-state'open' | 'closed'

CSS 变量 ​

本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。

变量部件CSS 属性状态默认来源说明
--xh-accordion-borderrootbordervariant=outline--xh-border-defaultaccordion 的 root 部件 border 覆盖槽。
--xh-accordion-content-fgcontentcolordefault--xh-fg-mutedaccordion 的 content 部件 color 覆盖槽。
--xh-accordion-content-font-sizecontentfont-sizedefault--xh-text-secondary-sizeaccordion 的 content 部件 font-size 覆盖槽。
--xh-accordion-content-pbcontentpadding-block-end@keyframes xh-disclosure-collapse
@keyframes xh-disclosure-expand
default
--xh-_accordion-content-pbaccordion 的 content 部件 padding-block-end 覆盖槽。
--xh-accordion-content-pxcontentpadding-inlinedefault--xh-_accordion-content-pxaccordion 的 content 部件 padding-inline 覆盖槽。
--xh-accordion-icon-sizeroot
trigger
--xh-icon-sizedefault--xh-_action-profile-glyph-size
--xh-glyph-size-md
accordion 的 root、trigger 部件 --xh-icon-size 覆盖槽。
--xh-accordion-indicator-fgindicatorcolordefault--xh-fg-mutedaccordion 的 indicator 部件 color 覆盖槽。
--xh-accordion-item-bgrootbackgroundvariant=outline
variant=subtle
--xh-bg-subtle
--xh-bg-surface
accordion 的 root 部件 background 覆盖槽。
--xh-accordion-item-borderitem
item-separator
root
background
border-block-start
border-inline-start
default
is([data-variant='outline'], [data-variant='subtle'])
not(:last-child)
orientation=horizontal
variant=outline
variant=subtle
--xh-border-subtleaccordion 的 item、item-separator、root 部件 background、border-block-start、border-inline-start 覆盖槽。
--xh-accordion-item-radiusrootborder-radiusvariant=outline
variant=subtle
--xh-shape-surfaceaccordion 的 root 部件 border-radius 覆盖槽。
--xh-accordion-item-shadowrootbox-shadowvariant=outline
variant=subtle
noneaccordion 的 root 部件 box-shadow 覆盖槽。
--xh-accordion-trigger-bgtrigger--xh-ink-surface
background-color
default
xh-ink-surface
--xh-_action-variant-bg-restaccordion 的 trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-accordion-trigger-bg-hovertriggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hoveraccordion 的 trigger 部件 background-color 覆盖槽。
--xh-accordion-trigger-fgtriggercolordefault
disabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-fg-hover
--xh-_action-variant-fg-pressed
--xh-_action-variant-fg-rest
accordion 的 trigger 部件 color 覆盖槽。
--xh-accordion-trigger-fg-disabledtriggercolordisabled--xh-_action-variant-fg-disabledaccordion 的 trigger 部件 color 覆盖槽。
--xh-accordion-trigger-fg-opentriggercolordisabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
state=open
--xh-_accordion-open-fgaccordion 的 trigger 部件 color 覆盖槽。
--xh-accordion-trigger-font-sizetriggerfont-sizedefault--xh-_action-profile-font-sizeaccordion 的 trigger 部件 font-size 覆盖槽。
--xh-accordion-trigger-font-weighttriggerfont-weightdefault--xh-text-label-weightaccordion 的 trigger 部件 font-weight 覆盖槽。
--xh-accordion-trigger-gaptriggergapdefault--xh-_action-profile-gapaccordion 的 trigger 部件 gap 覆盖槽。
--xh-accordion-trigger-htriggerblock-size
min-block-size
default
xh-action-profile=disclosure-trigger
--xh-_action-profile-visual-sizeaccordion 的 trigger 部件 block-size、min-block-size 覆盖槽。
--xh-accordion-trigger-pxtriggerpadding-inlinedefault--xh-_action-profile-padding-inlineaccordion 的 trigger 部件 padding-inline 覆盖槽。
--xh-accordion-trigger-pytriggerpadding-blockxh-action-profile=disclosure-trigger--xh-_action-profile-padding-blockaccordion 的 trigger 部件 padding-block 覆盖槽。
--xh-accordion-trigger-radiustriggerborder-radiusdefault--xh-_action-profile-radiusaccordion 的 trigger 部件 border-radius 覆盖槽。

动效 ​

动效角色:按压 · 状态 · 披露(见动效规范)。

共享关键帧 xh-disclosure-collapse · xh-disclosure-expand 由 family/motion.css 提供,皮肤 @import 它,单独引入仍成立;rotate 走 transition 过渡。时长与缓动读动效令牌,改令牌即改全局节奏。

皮肤之外还有一段:退场由适配器的退场闸门把关,动画播完才真收起。

系统开启减弱动效时由令牌层统一收敛,皮肤不另作判断。

RTL ​

皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像。

Released under The MIT License