What was measured
CelPredicateField accepts an optional id prop and uses it for BOTH halves of the association:
Label className="…" htmlFor={id} ← packages/app-shell/src/views/metadata-admin/CelPredicateField.tsx:311
Textarea ref={taRef} id={id} ← same file, :316
When a call site omits id, both become undefined, so the visible label is bound to no control: the textarea has no accessible name, and the label is orphaned text.
Three of the four call-site groups omit it:
| call site |
passes id? |
inspectors/ObjectFieldInspector.tsx :478 / :615 / :628 / (formula) |
yes — id={"field-rule-visible-…"} etc. |
PermissionAdvancedFacets.tsx :356 (RLS USING), :372 (RLS CHECK) |
no |
ConditionalFormattingEditor.tsx :272 |
no |
So the RLS policy editor's USING and CHECK predicate fields — the row-filter authoring surface of a permission set — and the conditional-formatting rule editor render a label that reads correctly on screen and resolves to nothing for a screen reader. ObjectFieldInspector shows the intended shape: the prop exists and is used correctly there.
How it surfaced
Writing the wire pins for objectui#4302 I reached for the obvious selector and testing-library refused it verbatim:
TestingLibraryElementError: Found a label with the text of: USING (read filter),
however no form control was found associated to that label. Make sure you're using
the "for" attribute or "aria-labelledby" attribute correctly.
The test now selects that textarea by placeholder instead, with a comment pointing here. That is a workaround in a test, not a fix.
Why this is filed rather than fixed
Out of scope for objectui#4302, whose ruling limits the surface to the package-door slice merge and its pins. Same family as the already-fixed objectui#3994 (metadata-admin inspectors' shared field components had Label next to the control without associating them) and objectui#3341 — this is the residue those two did not reach.
Suggested shape
Pass an id at the three call sites (the RLS facet has a policy index available: rls-{i}-using / rls-{i}-check), or have CelPredicateField fall back to a generated id (React.useId()) when the prop is absent, so a call site cannot silently produce an unlabelled control. The second is the "hard to get wrong" direction — the label is rendered by the component itself, so the component can guarantee the association rather than trusting every caller to remember.
Unassigned, for triage.
Generated by Claude Code
What was measured
CelPredicateFieldaccepts an optionalidprop and uses it for BOTH halves of the association:When a call site omits
id, both becomeundefined, so the visible label is bound to no control: the textarea has no accessible name, and the label is orphaned text.Three of the four call-site groups omit it:
id?inspectors/ObjectFieldInspector.tsx:478 / :615 / :628 / (formula)id={"field-rule-visible-…"}etc.PermissionAdvancedFacets.tsx:356 (RLS USING), :372 (RLS CHECK)ConditionalFormattingEditor.tsx:272So the RLS policy editor's USING and CHECK predicate fields — the row-filter authoring surface of a permission set — and the conditional-formatting rule editor render a label that reads correctly on screen and resolves to nothing for a screen reader.
ObjectFieldInspectorshows the intended shape: the prop exists and is used correctly there.How it surfaced
Writing the wire pins for objectui#4302 I reached for the obvious selector and testing-library refused it verbatim:
The test now selects that textarea by placeholder instead, with a comment pointing here. That is a workaround in a test, not a fix.
Why this is filed rather than fixed
Out of scope for objectui#4302, whose ruling limits the surface to the package-door slice merge and its pins. Same family as the already-fixed objectui#3994 (metadata-admin inspectors' shared field components had
Labelnext to the control without associating them) and objectui#3341 — this is the residue those two did not reach.Suggested shape
Pass an
idat the three call sites (the RLS facet has a policy index available:rls-{i}-using/rls-{i}-check), or haveCelPredicateFieldfall back to a generated id (React.useId()) when the prop is absent, so a call site cannot silently produce an unlabelled control. The second is the "hard to get wrong" direction — the label is rendered by the component itself, so the component can guarantee the association rather than trusting every caller to remember.Unassigned, for triage.
Generated by Claude Code