Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

[fields/components] 全屏长文本对话框里的编辑控件没有可访问名(三个渲染面一致):inline 面读到「F」,对话框面读到空 #4832

Closed

Description

@yinlianghui

做 #4824 的测量任务时实测发现,按 Prime Directive #10 立单(不认领、不扩围到 #4824)。与 #4824 相邻但不同:#4824 是对话框里的校验状态与错误文案,本条是对话框里那个控件的可访问名。

实测

真表单渲染器 + 注册 widget,字段 label: 'F'、mobile_fullscreen: true,点开展开按钮后同时读 inline 面与对话框面(happy-dom + jest-dom 7.0.0 的 accname 计算):

INLINE  richtext(field:markdown)   accName= F      accDescription= F is required
DIALOG  richtext(field:markdown)   accName=        accDescription=
INLINE  textarea(field:textarea)   accName= F      accDescription= F is required
DIALOG  textarea(field:textarea)   accName=        accDescription=
INLINE  builtin textarea           accName= F      accDescription= F is required
DIALOG  builtin textarea           accName=        accDescription=

三个渲染面完全一致:对话框里的编辑控件可访问名为空。

机理

对话框里的那份编辑控件是从零构造的,宿主的 id / aria-describedby 都不给它(这是三处都写了注释的、有理由的取舍 —— 宿主 id 唯一、宿主 describedby 指向模态外被 Radix aria-hidden 的节点):

  • packages/fields/src/widgets/TextAreaField.tsx 对话框分支的 textarea
  • packages/fields/src/widgets/RichTextField.tsx 对话框分支的 RichTextEditorSurface(其 domProps 注释明说只给 inline 面)
  • packages/components/src/renderers/form/form.tsx 内置 FullscreenTextarea 的对话框 textarea

于是可见 label 的 for 指向 inline 面那个控件,对话框里的控件既没有 for 关联、也没有 aria-label / aria-labelledby。

这算不算缺陷:两面都说清楚

减轻的一面:对话框本身是有名字的 —— #3393 已经把字段 label 接进 DialogTitle,Radix 用它给 DialogContent 发 aria-labelledby。读屏进入对话框时会播报「F,对话框」。

仍然是缺口的一面:进入对话框之后,焦点落到那个 textarea 上,播报的是「编辑框,空」——没有字段名。按控件导航(表单元素列表、快捷键在控件间跳)时同样拿不到名字。同一个字段的 inline 面读得到「F」,对话框面读不到,这正是 #3417 / #4824 反复出现的那条分叉:同一件事在两个编辑面上不一致,而对话框面是移动端的主力路径。

形状问题(不自行裁定)

至少两种,改动面不同,且与 #4824 的裁决相互影响(同一批控件、同一处代码):

可达性

不是死代码:命中条件与 #4824 完全相同(mobile.fullscreenLongText 开启 + 长文本字段 + 读屏),而该 opt-in 已发布,手机端全屏编辑正是它的主力场景。

未打标签,交 PM triage 定级。建议与 #4824 同批考虑——两条改的是同一批对话框控件,分两次改会在同一段代码上撞车。


Generated by Claude Code

Activity

  1. self-assigned this
    on Aug 16, 2026
  2. yinlianghui commented on Aug 16, 2026

    @yinlianghui
    ContributorAuthor

    【认领】objectui 分片 PM(session_01GTRjn8xBqp75dk7kFupVRt)批次 12:按 2026-08-16 维护者裁定与 #4824 同批同 PR 实施(同一批控件、同一段 JSX)。分支:claude/issue-4824-fullscreen-dialog-aria。命名通道随 E1 的必填 aria 参数一处交付(复用 DialogTitle 的可见文本,不新造名字来源)。细节与文件面声明见 #4824 的认领评论。


    Generated by Claude Code

  3. yinlianghui commented on Aug 16, 2026

    @yinlianghui
    ContributorAuthor

    【os-dev 实施完成】随 #4824 同批同 PR 交付:draft PR #4864,分支 claude/issue-4824-fullscreen-dialog-aria。

    按裁定走的是本单的形状 B 且落在 C 的位置:不新造 aria-label 文案来源(#3978 单一命名通道),而是 aria-labelledby 指向 DialogTitle 的可见文本,并由 FullscreenEditor 一处交出 —— 与 #4824 的必填第 4 aria 参数是同一个通道,宿主只管展开、不知道 id,所以「宿主必须记得用」这个 #4788 反复点名的易漏契约在这里不存在(三个宿主一个都没有自己的命名逻辑)。

    实现细节里一条值得记的:id 不能放在 DialogTitle 上,必须放在它内部的一个 span 上。Radix 渲染 h2 元素时把 id={context.titleId} 放在属性展开之前,传 id 会替换掉 DialogContent 自己 aria-labelledby 所指的那个 id —— 那就是用对话框的名字换控件的名字,把 #3393 顶掉。钉子两边都钉:控件有名 且 对话框仍有名。

    三面可访问名读数:inline F / 对话框空 → 三个面的对话框控件都读到 F(与 inline 一致)。另有一条钉子断言控件不带 aria-label,一个自己 mint 字符串的实现会在那里红。

    验证与反向验证见 #4824 的完成评论与 PR 正文。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions