发现于 #3997 的实施过程(该单主体是 InspectorComboField,PR 未夹带本条)。未认领,交 PM triage。
机制
DashboardWidgetInspector 用一个本地 Field 包装器给控件命名,约定是「包装器渲染 Label htmlFor={id},被包的控件自己带同一个 id」:
packages/app-shell/src/views/metadata-admin/inspectors/DashboardWidgetInspector.tsx:447-464 —— Field({ id, label, children }) 渲染 Label htmlFor={id}。
其余站点都履行了这个约定:widget-title / widget-w / widget-h 落在 Input id,widget-type 落在 SelectTrigger id。
widget-dataset 原本落不下去(combo 根本不收 id),已随 检查器第四个字段原子 InspectorComboField 的 label 仍与 trigger 不关联 —— #3994 修了三个,这个同族站点没在围栏内 #3997 修好。
剩下 widget-color(:377) :子节点是 ColorVariantPicker,其 props 只有 { value, onChange, disabled, options }(packages/app-shell/src/views/metadata-admin/color-variant-field.tsx:43-48),不接受 id。
所以 htmlFor="widget-color" 指向一个没有任何元素持有 的 id —— 悬空 IDREF。按 #3994 / #3997 的判据这比「没有标签」更糟:工具会报告一个解析不到的关联,静态检查看到 for 存在就以为命名闭合了。
第二层(同一处、更实的一档):ColorVariantPicker 渲染 div role="radiogroup"(color-variant-field.tsx:55),这个 radiogroup 既没有 aria-label 也没有 aria-labelledby。组内每个 radio 各自有 aria-label(颜色名),但组本身完全无名 —— 焦点进组读到的是一个匿名 radiogroup,不知道这组颜色改的是什么;可见的「Color」标签是一段无归属文本。
是不是 dormant
不是。widget-color 是 Field 的无条件分支,打开任一 dashboard widget 检查器即渲染。另外 widgets.tsx:1790 与 PageBlockInspector.tsx:30 也消费 ColorVariantPicker,那两处外层是否也有一个无归属的 Label 没有逐处核过,实施时应一并核。
修法方向(未实施,供分诊)
radiogroup 是容器,不是 labelable 元素,所以 for 指向它本身也不合法(与 #3991 同类:host id 落在不可 label 的元素上不算关联)。两条候选:
ColorVariantPicker 收 ariaLabelledBy,Field 把它那个 Label 的 id 传进来,radiogroup 用 aria-labelledby 命名 —— 与 [fields] 只读 / 零选项的 group-labelled 选项 widget 提前 return,groupDomProps 没被展开 —— host label 的 IDREF 没有消费者,标签仍然什么都不命名(#3961 的残留,checkboxes 今天的 main 上就这样) #3990 (PR fix(fields): group-labelled widget 的只读/零选项分支也消费 host label 的 IDREF (#3990) #4002 )的 group-labelled widget 用 IDREF 命名同构,可见文本即可访问名,单一通道。
ColorVariantPicker 自带 ariaLabel,Field 的可见 Label 不再 for 任何东西 —— 但那把可见文本重新变成无归属文本,只解决了悬空、没解决命名。
倾向 1,但它改的是 Field 包装器的对外形状(目前 Field 的契约是「id 给控件」,IDREF 命名要的是「label 的 id 给控件」),属于 contract-first 该单独定的一步,故只记录不动手。
边界与去重
不是 检查器第四个字段原子 InspectorComboField 的 label 仍与 trigger 不关联 —— #3994 修了三个,这个同族站点没在围栏内 #3997 :那单主体是 InspectorComboField;同一个 Field 包装器的 widget-dataset 分支已在该 PR 里修好(combo 新增 id 命名通道),但 widget-color 分支与 ColorVariantPicker 该 PR 一字未动。该 PR 的回归钉子刻意只锁 Dataset 那一对,没有做整面板的「无悬空 for」扫描,正是为了不把本条锁成绿色或红色。
不是 [components] 内建 select 的空选项/依赖门态分支把 host id 落在一个 div 上 —— label 的 for 指向不可 label 元素,仍是不关联的 #3991 :那条在 packages/components 内建 select,host id 落到 div 上;本单在 app-shell,且 id 连落点都没有。同族不同站点、无共享实现。
不是 metadata-admin 检查器的三个共享字段组件把 Label 和控件放在一起但不关联 —— 屏幕阅读器读到的是"无名编辑框",可见标签成了孤立文本 #3994 (PR fix(metadata-admin): 检查器三个共享字段原子的 label 与控件建立编程关联 (#3994) #3996 ) :_shared.tsx 三个原子,已修。
不是 检查器第四个字段原子 InspectorComboField 的 label 仍与 trigger 不关联 —— #3994 修了三个,这个同族站点没在围栏内 #3997 正文附的 18 处宽面清单 :那份清单是「Label 兄弟节点、缺 htmlFor」;本单相反 —— htmlFor 有,指向空。
检索过 open issues(ColorVariantPicker、widget-color radiogroup htmlFor dangling、label 关联 可访问名、color variant picker 颜色),无同题单。
发现于 #3997 的实施过程(该单主体是
InspectorComboField,PR 未夹带本条)。未认领,交 PM triage。机制
DashboardWidgetInspector用一个本地Field包装器给控件命名,约定是「包装器渲染 Label htmlFor={id},被包的控件自己带同一个 id」:packages/app-shell/src/views/metadata-admin/inspectors/DashboardWidgetInspector.tsx:447-464——Field({ id, label, children })渲染 Label htmlFor={id}。widget-title/widget-w/widget-h落在Input id,widget-type落在SelectTrigger id。widget-dataset原本落不下去(combo 根本不收 id),已随 检查器第四个字段原子 InspectorComboField 的 label 仍与 trigger 不关联 —— #3994 修了三个,这个同族站点没在围栏内 #3997 修好。widget-color(:377):子节点是ColorVariantPicker,其 props 只有{ value, onChange, disabled, options }(packages/app-shell/src/views/metadata-admin/color-variant-field.tsx:43-48),不接受 id。所以
htmlFor="widget-color"指向一个没有任何元素持有的 id —— 悬空 IDREF。按 #3994 / #3997 的判据这比「没有标签」更糟:工具会报告一个解析不到的关联,静态检查看到 for 存在就以为命名闭合了。第二层(同一处、更实的一档):
ColorVariantPicker渲染 div role="radiogroup"(color-variant-field.tsx:55),这个 radiogroup 既没有aria-label也没有aria-labelledby。组内每个 radio 各自有aria-label(颜色名),但组本身完全无名 —— 焦点进组读到的是一个匿名 radiogroup,不知道这组颜色改的是什么;可见的「Color」标签是一段无归属文本。是不是 dormant
不是。
widget-color是Field的无条件分支,打开任一 dashboard widget 检查器即渲染。另外widgets.tsx:1790与PageBlockInspector.tsx:30也消费ColorVariantPicker,那两处外层是否也有一个无归属的 Label 没有逐处核过,实施时应一并核。修法方向(未实施,供分诊)
radiogroup 是容器,不是 labelable 元素,所以
for指向它本身也不合法(与 #3991 同类:host id 落在不可 label 的元素上不算关联)。两条候选:ColorVariantPicker收ariaLabelledBy,Field把它那个 Label 的 id 传进来,radiogroup 用aria-labelledby命名 —— 与 [fields] 只读 / 零选项的 group-labelled 选项 widget 提前 return,groupDomProps没被展开 —— host label 的 IDREF 没有消费者,标签仍然什么都不命名(#3961 的残留,checkboxes 今天的 main 上就这样) #3990(PR fix(fields): group-labelled widget 的只读/零选项分支也消费 host label 的 IDREF (#3990) #4002)的 group-labelled widget 用 IDREF 命名同构,可见文本即可访问名,单一通道。ColorVariantPicker自带ariaLabel,Field的可见 Label 不再 for 任何东西 —— 但那把可见文本重新变成无归属文本,只解决了悬空、没解决命名。倾向 1,但它改的是
Field包装器的对外形状(目前Field的契约是「id 给控件」,IDREF 命名要的是「label 的 id 给控件」),属于 contract-first 该单独定的一步,故只记录不动手。边界与去重
InspectorComboField;同一个Field包装器的widget-dataset分支已在该 PR 里修好(combo 新增id命名通道),但widget-color分支与ColorVariantPicker该 PR 一字未动。该 PR 的回归钉子刻意只锁 Dataset 那一对,没有做整面板的「无悬空 for」扫描,正是为了不把本条锁成绿色或红色。packages/components内建 select,host id 落到 div 上;本单在 app-shell,且 id 连落点都没有。同族不同站点、无共享实现。Label和控件放在一起但不关联 —— 屏幕阅读器读到的是"无名编辑框",可见标签成了孤立文本 #3994(PR fix(metadata-admin): 检查器三个共享字段原子的 label 与控件建立编程关联 (#3994) #3996):_shared.tsx三个原子,已修。ColorVariantPicker、widget-color radiogroup htmlFor dangling、label 关联 可访问名、color variant picker 颜色),无同题单。