做 #3408(把内联字数统计从「每击键整句重播」改成 describedby + 阈值门控的 debounce 状态区)时顺带发现的,PM 已在该单裁定里明确把它排除在 #3408 范围之外(「不动 FullscreenFieldEditor 的 footer 计数」),故独立立单,免得随 #3408 合并一起消失在记忆里。
现状
packages/fields/src/widgets/TextAreaField.tsx 把全屏编辑对话框的 footer 计数交给共享的 FullscreenFieldEditor:
footer={(draft) =>
maxLength ? (
(span className="text-xs text-muted-foreground self-center")
{draft.length}/{maxLength}
(/span)
) : null
}
(尖括号写成圆括号,避免 GitHub 正文清洗器把标签吃掉。)
就是一串数字:没有 aria-label / 可访问名,没有 aria-live,没有任何东西把它和对话框里那个 data-testid="textarea-fullscreen-input" 的 textarea 关联起来。读屏把它读出来也只是「5 斜杠 500」——而且只有在浏览模式扫到它时才会读到;聚焦到输入框时一个字都不会提。
内联那一份在 #3408 之后已经有了三节点形制(可见数字 aria-hidden、aria-describedby 描述节点、阈值门控 + debounce 的 aria-live 状态节点)。同一个字段的同一件事,在全屏分支上等于零。
可达性
不是死代码。命中条件是字段同时有 maxLength(或旧拼法 max_length)和 mobile_fullscreen,后者由 ObjectForm 在 ObjectFormSchema.mobile.fullscreenLongText 打开时给每个长文本字段盖章(plugin-form/src/ObjectForm.tsx)。也就是说:手机上开了全屏长文本的表单里,每一个带字数上限的长文本字段都命中 —— 而全屏编辑恰恰是移动端的主力路径。RichTextField 走同一个 FullscreenFieldEditor,但它自己不传 footer,所以这条目前只影响 textarea。
形状问题(不自行裁定)
修的时候有几个选择,而且和 #3408 的裁定要保持一致,不该由实现者顺手定:
倾向 C 的方向 + B 的行为(全屏不需要 live region),但这是可访问性契约形状问题,不自行裁定。
不构成阻塞,但会碰同一个文件(TextAreaField.tsx 的 footer 回调)和同一个共享组件,建议排在 #3408 合并之后,免得两个 PR 在同一段 JSX 上撞车。
未打标签,交 PM triage 定级 —— 我判断它是「当前有人踩得到的具体缺陷」(移动端 + 读屏 + 有上限的长文本),但立单时的严重度判断本就不可靠,不自行加权。
Generated by Claude Code
做 #3408(把内联字数统计从「每击键整句重播」改成 describedby + 阈值门控的 debounce 状态区)时顺带发现的,PM 已在该单裁定里明确把它排除在 #3408 范围之外(「不动 FullscreenFieldEditor 的 footer 计数」),故独立立单,免得随 #3408 合并一起消失在记忆里。
现状
packages/fields/src/widgets/TextAreaField.tsx把全屏编辑对话框的 footer 计数交给共享的FullscreenFieldEditor:(尖括号写成圆括号,避免 GitHub 正文清洗器把标签吃掉。)
就是一串数字:没有
aria-label/ 可访问名,没有aria-live,没有任何东西把它和对话框里那个data-testid="textarea-fullscreen-input"的 textarea 关联起来。读屏把它读出来也只是「5 斜杠 500」——而且只有在浏览模式扫到它时才会读到;聚焦到输入框时一个字都不会提。内联那一份在 #3408 之后已经有了三节点形制(可见数字
aria-hidden、aria-describedby描述节点、阈值门控 + debounce 的aria-live状态节点)。同一个字段的同一件事,在全屏分支上等于零。可达性
不是死代码。命中条件是字段同时有
maxLength(或旧拼法max_length)和mobile_fullscreen,后者由ObjectForm在ObjectFormSchema.mobile.fullscreenLongText打开时给每个长文本字段盖章(plugin-form/src/ObjectForm.tsx)。也就是说:手机上开了全屏长文本的表单里,每一个带字数上限的长文本字段都命中 —— 而全屏编辑恰恰是移动端的主力路径。RichTextField走同一个FullscreenFieldEditor,但它自己不传 footer,所以这条目前只影响 textarea。形状问题(不自行裁定)
修的时候有几个选择,而且和 #3408 的裁定要保持一致,不该由实现者顺手定:
aria-hidden,加 visually-hidden 描述节点挂到对话框内 textarea 的aria-describedby,再加阈值门控 + debounce 的状态节点。语义与内联分支完全一致,代价是FullscreenFieldEditor的footer插槽签名要能表达这些(现在只收一个ReactNode),或者干脆把「计数」提升成FullscreenFieldEditor的一等能力而不是任意 footer 内容。aria-describedby+aria-hidden),不给全屏分支任何 live region —— 全屏是个专注编辑的模态,主动打断的价值比内联更低。改动面最小。倾向 C 的方向 + B 的行为(全屏不需要 live region),但这是可访问性契约形状问题,不自行裁定。
与 #3408 的关系
不构成阻塞,但会碰同一个文件(
TextAreaField.tsx的 footer 回调)和同一个共享组件,建议排在 #3408 合并之后,免得两个 PR 在同一段 JSX 上撞车。未打标签,交 PM triage 定级 —— 我判断它是「当前有人踩得到的具体缺陷」(移动端 + 读屏 + 有上限的长文本),但立单时的严重度判断本就不可靠,不自行加权。
Generated by Claude Code