Skip to content

Collapsible 折叠面板 ​

点一下触发元素,在原地展开 / 收起一块内容。适合「高级设置」「显示更多」这类默认不必看、 需要时就近展开的区域。

基础用法

触发元素放进 trigger 插槽,点击切换展开态;内容放默认插槽。受控值走 open + ptChange,ptChange 只在用户点击切换时发。

<pt-collapsible>
  <pt-button slot="trigger" variant="secondary" size="sm">显示全部 4 个包</pt-button>
  <ul>
    <li>@ptengine/ui</li>
    <li>@ptengine/ui-react</li>
    <li>@ptengine/ui-vue</li>
    <li>@ptengine/ui-angular</li>
  </ul>
</pt-collapsible>
初始展开与禁用

open 让它一开始就展开;disabled 只拦住点击切换,外部改 open 照样生效。触发元素的外观由使用方自己禁用。

<pt-collapsible open>
  <pt-button slot="trigger" variant="ghost" size="sm">收起</pt-button>
  <p>一开始就是展开的内容。</p>
</pt-collapsible>
<pt-collapsible disabled>
  <pt-button slot="trigger" variant="secondary" size="sm" disabled>不可展开</pt-button>
  <p>禁用时点不开。</p>
</pt-collapsible>

受控值 ​

受控属性是 open,事件是 ptChange(detail 是切换后的 open):

  • Vue:<PtCollapsible v-model="expanded">
  • Angular:<pt-collapsible [(ngModel)]="expanded">,standalone 组件要在 imports 里加上 OpenValueAccessor,否则 ngModel 找不到 accessor
  • React:<PtCollapsible open={expanded} onPtChange={e => setExpanded(e.detail)}>

ptChange 只在用户点击触发元素切换时发;外部直接改 open 只改状态,不发事件, 不会和双向绑定来回打转。

触发元素 ​

触发元素放进 trigger 插槽,通常是一个 <button> 或 pt-button。键盘由它自己负责: 按钮上的 Enter / Space 本来就会派发 click,组件只听 click,不另拦按键。

组件会在触发元素上维护两个属性(WAI-ARIA Disclosure 模式):

  • aria-expanded:跟着 open 走;
  • aria-controls:指向默认插槽里的内容元素,它们没有 id 时自动补一个。默认插槽里只有文本时不写。

触发元素被换掉时,新元素补上这两个属性,旧元素上的清掉。

读屏与 pt-button

属性写在触发元素的宿主上。原生 <button> 直接生效;pt-button 的真实按钮在它自己的影子树里, 宿主上的 aria-expanded 目前读屏读不到。对读屏体验要求高的地方优先用原生按钮。

禁用 ​

disabled 只拦住点击切换,外部改 open 照样生效。它不改触发元素的外观 —— 触发元素是你的,需要一起变灰就在触发元素上写 disabled。

展开与收起 ​

内容区用 grid-template-rows 在 0fr 与 1fr 之间过渡,不需要量高度,内容变高变矮也跟着走。 系统开了「减少动态效果」时直接切换。

收起时内容区 inert 且不可见:Tab 不会走进看不见的内容,读屏也不会读到它。

API ​

属性

属性Attribute类型默认值说明
disableddisabledbooleanfalse禁用:点击触发元素不再切换。不影响通过 `open` 属性控制
openopenbooleanfalse是否展开。用户点击触发元素时组件自己改写它并发 `ptChange`;外部直接赋值不发事件

事件

事件detail 类型说明
ptChangeboolean用户点击触发元素切换展开态后触发,detail 是切换后的 `open`。 **不冒泡**(与其它组件的默认相反):折叠面板天然会嵌套,而三个框架的双向绑定都挂在宿主上 —— Vue 的 v-model 只按 tagName 过滤冒泡事件,内外层同是 PT-COLLAPSIBLE 拦不住;React 的 onPtChange 也会收到内层的事件。冒泡的话收起内层会连带改写外层绑定、把外层也收起。 要在外层容器上统一监听,用捕获阶段(`addEventListener('ptChange', fn, true)`)。

插槽

名称说明
(默认)折叠的内容
trigger触发元素,点击切换展开态。通常是一个 button / pt-button

可定制的内部元素(::part())

part说明
content内容区(做高度过渡的那一层)

Apache-2.0 协议开源