发现于 #3994 的实施过程(PR #3996 未夹带 —— 该单范围明确是 _shared.tsx 的三个原子 + 测试)。未认领,交 PM triage。
机制
packages/app-shell/src/views/metadata-admin/inspectors/InspectorComboField.tsx:170-176(带 label 的返回分支)与 #3994 的三个原子形状完全相同:
Label 渲染成 trigger 的兄弟节点,没有 htmlFor
- trigger 是
PopoverTrigger asChild 包的 Button(role="combobox"),没有 id,也没有 aria-label 兜底
所以标签与控件之间只有视觉邻接,没有可编程关联。getByLabelText(label) 到不了它;焦点落上去读到的是匿名 combobox,可见标签是一段无归属文本,点标签什么都不会发生。
与 #3994 的差别只在 label 是可选 prop:if (!label) return field; —— 无 label 时这个 combobox 干脆完全无名(既没有 for 也没有 aria-label),那是同一缺陷更重的一档,值得在实施时一并想清(要么要求调用方给 aria-label,要么让无 label 分支也承担命名)。
是不是 dormant
不是。InspectorComboField 被数据集 / 流程引用等检查器消费(它就是 issue 里描述的「可搜索单选 + 允许自定义值」的选择器),打开对应检查器面板即渲染。
修法与 #3994 同构、可直接照抄:React.useId() 生成 id,Label 补 htmlFor,id 落到真实 trigger(asChild 下 Button 渲染的那个 button[role=combobox],不是 Popover Root —— Root 不渲染 DOM,给它 id 会被静默丢弃,#3976 / PR #3992 的教训)。#3994 的 _shared.labels.test.tsx 那组 describe.each 可以直接把这个原子加进去(它已经把「for 有宿主 / 命中可聚焦控件 / 可访问名 / 只有一条命名通道 / 多实例不撞车」写成了与组件无关的形状)。
更宽的面(同一族,建议由 PM 决定是否拆)
同样是「Label 兄弟节点、无 htmlFor」的站点在 metadata-admin 还有(grep -rn '<'Label packages/app-shell/src/views/metadata-admin --include=*.tsx | grep -v htmlFor,已排除测试与本单):
widgets.tsx:1937 / :1945 / :1959
datasource/DatasourceResourcePage.tsx:445 / :461 / :471 / :484 / :579 / :592 / :597 / :611
PermissionAdvancedFacets.tsx:467 / :503
PermissionMatrixEditor.tsx:760 / :774
previews/FieldsListEditor.tsx:163
previews/FlowSimulatorPanel.tsx:298 / :360
这些没有逐个核过「label 下面到底是不是控件」(有几处可能是纯分组小标题,那种用 Label 只是取字号,本身不是缺陷),所以本单只把 InspectorComboField 这一个已核实的站点作为主体,列表附在这里供分诊时决定要不要另开一条 sweep。
边界与去重
发现于 #3994 的实施过程(PR #3996 未夹带 —— 该单范围明确是
_shared.tsx的三个原子 + 测试)。未认领,交 PM triage。机制
packages/app-shell/src/views/metadata-admin/inspectors/InspectorComboField.tsx:170-176(带 label 的返回分支)与 #3994 的三个原子形状完全相同:Label渲染成 trigger 的兄弟节点,没有htmlForPopoverTrigger asChild包的Button(role="combobox"),没有id,也没有aria-label兜底所以标签与控件之间只有视觉邻接,没有可编程关联。
getByLabelText(label)到不了它;焦点落上去读到的是匿名 combobox,可见标签是一段无归属文本,点标签什么都不会发生。与 #3994 的差别只在
label是可选 prop:if (!label) return field;—— 无 label 时这个 combobox 干脆完全无名(既没有for也没有aria-label),那是同一缺陷更重的一档,值得在实施时一并想清(要么要求调用方给aria-label,要么让无 label 分支也承担命名)。是不是 dormant
不是。
InspectorComboField被数据集 / 流程引用等检查器消费(它就是 issue 里描述的「可搜索单选 + 允许自定义值」的选择器),打开对应检查器面板即渲染。修法与 #3994 同构、可直接照抄:
React.useId()生成 id,Label补htmlFor,id 落到真实 trigger(asChild下Button渲染的那个button[role=combobox],不是PopoverRoot —— Root 不渲染 DOM,给它 id 会被静默丢弃,#3976 / PR #3992 的教训)。#3994 的_shared.labels.test.tsx那组describe.each可以直接把这个原子加进去(它已经把「for 有宿主 / 命中可聚焦控件 / 可访问名 / 只有一条命名通道 / 多实例不撞车」写成了与组件无关的形状)。更宽的面(同一族,建议由 PM 决定是否拆)
同样是「
Label兄弟节点、无htmlFor」的站点在 metadata-admin 还有(grep -rn '<'Label packages/app-shell/src/views/metadata-admin --include=*.tsx | grep -v htmlFor,已排除测试与本单):widgets.tsx:1937/:1945/:1959datasource/DatasourceResourcePage.tsx:445/:461/:471/:484/:579/:592/:597/:611PermissionAdvancedFacets.tsx:467/:503PermissionMatrixEditor.tsx:760/:774previews/FieldsListEditor.tsx:163previews/FlowSimulatorPanel.tsx:298/:360这些没有逐个核过「label 下面到底是不是控件」(有几处可能是纯分组小标题,那种用
Label只是取字号,本身不是缺陷),所以本单只把InspectorComboField这一个已核实的站点作为主体,列表附在这里供分诊时决定要不要另开一条 sweep。边界与去重
Label和控件放在一起但不关联 —— 屏幕阅读器读到的是"无名编辑框",可见标签成了孤立文本 #3994(PR fix(metadata-admin): 检查器三个共享字段原子的 label 与控件建立编程关联 (#3994) #3996):那单的三个原子在_shared.tsx,已修;本单是同目录另一个文件的第四个原子,PR fix(metadata-admin): 检查器三个共享字段原子的 label 与控件建立编程关联 (#3994) #3996 一字未动它。packages/components内建 select 空选项分支把 host id 落到div上;本单在 app-shell,且根本没有 id/htmlFor可言。for(#3975) #3983):那单是packages/fields多选控件的 chip group 用 IDREF 命名;不同站点、无共享实现。BlockPropField没有格式/校验能力位 —— 所有标识符类字段(sectionname、tabkey、accordionvalue)只能靠 placeholder 陈述约定 #3912:那单是BlockPropField的格式/校验能力位(数据面表达力),与标签关联无关。InspectorComboField、htmlFor label association、in:title metadata-admin Label、可访问名 label 关联),无同题单。