fix(a11y): make collapsed Collapsible content non-tabbable

pr-agent #407 反馈:grid-template-rows: 0fr 把内容视觉裁掉,但内部的 input /
button / Toggle 仍 mounted 且 tabbable —— 键盘用户折叠 Section 之后仍能 tab
到不可见的控件,屏幕阅读器也会朗读。

修复:内容容器 inert={当未展开} + aria-hidden={当未展开}:
- inert 把整个子树从 tab 顺序、点击事件、a11y 树里同时移除
- aria-hidden 配合 inert 给保守的 AT 兜底

React 18 types 没收 inert,用 spread { inert: '' } 绕过 TS。Chromium 102+ /
Safari 15.4+ 支持,Tauri WebView 远高于此基线。
This commit is contained in:
baiqing committed 2026-05-12 00:27:14 +08:00
1 parent f5d9288716
commit e44dcbc7f1
1 file changed
+6
+6
View File
@@ -229,6 +229,12 @@ export function Collapsible({ title, desc, defaultOpen = false, embedded = false
gridTemplateRows: open ? '1fr' : '0fr',
transition: 'grid-template-rows 0.22s var(--ol-motion-soft)',
}}
// inert 把内部交互元素从 tab 顺序 + a11y 树移除,避免折叠后键盘用户
// 仍能 tab 到不可见的输入框 / 按钮 / Toggle(pr-agent #407 反馈)。
// 受支持范围:Chromium 102+(Tauri WebView 远高于此)/ Safari 15.4+。
// React 18 类型没收 `inert`,用 spread 传 string-boolean 绕过编译器。
{...(!open ? { inert: '' } : {})}
aria-hidden={!open}
>
{/* minHeight: 0 必填:默认 grid item 不允许收缩到小于内容固有高度,
没这条 trick 不生效,行高动画也跟着失败。 */}