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] markdown / html / richtext 的**可编辑**分支从不转发 host 下发的 id 与 aria-describedby —— label for 悬空、description 零消费者,且 #3318 的 aria-invalid 账本按设计看不见这一半 #4810

Closed

Description

@yinlianghui

在 #4788 的形态扫描中实测到的相邻一条,与 #4788 无关(#4788 只谈只读替换显示,本条发生在可编辑态),也不在 #3318 的完成范围内(理由见下)。不认领、不扩围。

实测

真 form renderer + 裸注册(与 #3990 / #4005 / #4788 的 probe 同一套),字段带 description: 'Some help',数「引用 …-form-item-description 这个 id 的元素个数」,并单独看 host label 的 for 解析到什么:

markdown  editable  descEl=SET  consumers=0  hostIdEl=NONE  for=DANGLING
markdown  readonly  descEl=SET  consumers=0  hostIdEl=NONE  for=DANGLING     ← 这一半属于 #4788
text      editable  descEl=SET  consumers=1  hostIdEl=input  for=RESOLVES    ← 对照组
textarea  editable  descEl=SET  consumers=1  hostIdEl=textarea for=RESOLVES  ← 对照组

html / richtext 与 markdown 是同一个 widget(fieldWidgetMap 里三个键都指向 RichTextField),读数相同。

机理

packages/fields/src/widgets/RichTextField.tsx 全文没有 toDomProps(实测 grep 计数 0)。可编辑分支把 props 只用来取 className / disabled,渲染 RichTextEditorSurface 时不铺任何 DOM pass-through:

  • host id(…-form-item)整个文档无元素承载 → 可见 label 的 for 指向一个不存在的 id;
  • FormControl 的 Slot 注入的 aria-describedby 同样落地失败 → 渲染出来的 FormDescription 零消费者。

对照组 TextAreaField / TextField 同一 host 同一 Slot,toDomProps(props) 一铺就都对了。

为什么这不在 #3318 的完成范围内(所以立成独立单,不是 #3318 的子单)

#3318 的账本是按 aria-invalid 一根轴扫出来的,而 markdown / html / richtext 在那次实测里是 PASS 的 17 个之一(RichTextEditorSurface 自己读 error 并置 aria-invalid)。也就是说:

#3318 正文给的修法(「把 toDomProps(props) spread 到 widget 的真实可聚焦控件」)如果照做在 RichTextField 上,顺手也修了本条 —— 但 RichTextField 不在它的待修名单里,所以照 #3318 收工不会碰到它。

相关但不同的

参考


备注:由 os-dev 在 #4788 的实施中实测发现并按 Prime Directive #10 立单(不认领、不扩围到 #4788)。

Activity

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

    @yinlianghui
    ContributorAuthor

    【认领】objectui 分片 PM(session_01GTRjn8xBqp75dk7kFupVRt)批次 11 补位派发。分支:claude/issue-4810-richtext-editable-plumbing。范围:RichTextField 可编辑分支按 #3318 既定配方把 toDomProps(props) 铺到真实可聚焦控件(markdown/html/richtext 三键同一 widget 一次修);⛔ 只读半边不碰(#4788 三问在决策箱,机制未裁);⛔ 其它 widget 不碰(slider/grid/signature 归 #3318 账本)。


    Generated by Claude Code

  3. yinlianghui commented on Aug 16, 2026

    @yinlianghui
    ContributorAuthor

    【实施完成】PR #4821(draft)。分支 claude/issue-4810-richtext-editable-plumbing,base d44279598。

    前提复核:卡内断言逐条为真 —— RichTextField.tsx 全文 toDomProps 计数 0;fieldWidgetMap 的 markdown / html / richtext 三键确实同指此 widget(index.tsx:2411-2413);probe 复现读数与卡内一致(consumers=0 hostIdEl=NONE for=DANGLING)。

    修法:toDomProps(props) 铺到 RichTextEditorSurface 内部那个 Textarea —— 实读确认它是本 widget 唯一接收焦点的元素,外层两级都是 div。只给 inline 那一份 surface;fullscreen 对话框那一份不给(同一 host id 会被两个同时挂载的编辑面共用,且 host 的 aria-describedby 指的节点在 modal 外被 Radix aria-hidden),与 TextAreaField 对同一对 surface 的切分一致。

    #3318 的 PASS 项无回归:aria-invalid={!!error} 留在 spread 之后,widget 自读仍是权威。反向验证里这一条得到独立确认 —— 删掉 spread 后 3 条 aria-invalid='false' 钉子仍绿,3 条 required-failure 用例也只在最后一句 aria-describedby 上红(aria-invalid='true' 的 waitFor 照过),即该属性在「修前 / 修后 / 变异后」三态完全相同。

    范围:只读分支一个字符未动(#4788 未裁);其它 widget 未动。改动仅 packages/fields,3 个文件(widget + 新钉子文件 + changeset)。

    顺手发现,已按 Prime Directive #10 另立:#4824 —— 全屏对话框那一份编辑面不播报校验失败,richtext 甚至恒 aria-invalid="false"(实测,与同刻 inline 面的 true 相反)。不认领、不在本单修。


    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