Skip to content

[fields] 注册 widget 路径的 select 空状态丢掉 host id —— label 的 for 悬空(objectui#3991 实测出的另一半,不同机制) #8803

Description

@claude

拆自 objectui#3991 的实测:那张卡按 arm 1 修了内建 select 分支(无控件 ⇒ 不发 for),
并实测出注册 widget 路径是同一缺陷类、不同机制,按派发裁决「说明并留下」,故单独立此卡。

实测(objectui#3991 的 worktree,origin/main @ b6d07df4b)

用真实的 @object-ui/fields widget + 真实表单渲染器,一个 { name: 'wempty', label: 'WEmpty', type: 'field' 冒号 'select', options: [] }:

label="WEmpty"  for="_r_2_-form-item"  ->  ownerTag = NONE

渲染出的行(去掉尖括号写法):

label ... for="_r_2_-form-item"  文本 WEmpty
div data-testid="select-empty-wempty" class="... h-9"  文本 No options available

for 悬空 —— 指向一个文档里没有任何元素携带的 id。
getByLabelText('WEmpty')
"Found a label with the text of: WEmpty, however no form control was found associated to that label"。

与 objectui#3991 的内建分支同形,但不是同一个机制

内建 select(#3991 已修) 注册 field 冒号 select(本卡)
空分支的归属 宿主自己(form.tsxrenderFieldComponent) widget(SelectField,另一个包)
host id 去向 展开到空状态的 div(...rest) 整个丢弃,不到达任何元素
症状 for 指向不可 label 的 div for 悬空,无 owner
宿主能否得知 ,同文件、条件读的是宿主自己算出并下发的值 不能,组件由 ComponentRegistry 解析

宿主侧不能顺手扩过来,这正是 #3991 没有一起修的原因:第三方完全可以注册一个
field 冒号 select,在空选项时渲染一个真实控件;宿主基于猜测抹掉 for,
会把一个本来正确的 widget 的关联打断。#3991 的 PR 里对这一条留了正面 pin。

四个选项 widget 里只有 select 受影响

FIELD_WIDGET_LABELLING 声明 multiselect / radio / checkboxes'group',
它们的空状态已经由 objectui#3990 / #4005 修好 —— 实测 field 冒号 radio 空选项:

label="REmpty"  for=null   (改为发布 id="..._group-label")
div id="..." aria-labelledby="..._group-label" aria-describedby="..." role="group"

select 声明的是 'control',没有这条 IDREF 通道,所以只有它落在这个状态里。
OptionsEmptyStatehostGroupProps 注释也把这一条写明了:
"Absent for the single SelectField — it is not group-labelled, its label still uses a plain for"。

影响面(与 #3991 同样诚实)

  • 用户侧:。这个状态里没有任何可聚焦控件,所以「点标签没反应」与「控件无可访问名」都无处发生。
  • 作者/测试侧:getByLabelText 抛错,读起来像渲染器坏了,而实际是正确渲染的空状态。

方向属于裁决,这里不预设

至少三条,和 #3991 当初的三岔一样,且这次不能直接照搬它的结论(那条结论的成立前提是宿主拥有分支):

  1. SelectField 的空分支把 host 的 pass-through 交给那个 div(会得到 [components] 内建 select 的空选项/依赖门态分支把 host id 落在一个 div 上 —— label 的 for 指向不可 label 元素,仍是不关联的 #3991 刚判定为惰性的形状);
  2. 给单 select 一条 labelling 侧的声明,让宿主像 group 那样知道空态无控件;
  3. 让空状态走 objectui#3990 / [fields] 只读态的 group-labelled 字段:description 的 IDREF 同样没有消费者(#3990 修的是「名」,这条是「描述」) #4005 已有的 hostGroupProps 通道(但 select 不是 group-labelled,
    这等于改它的 labelling 归类)。

参考


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions