-
-
Notifications
You must be signed in to change notification settings - Fork 356
Description
Bug report
Current behavior
When composing CheckboxGroup with Field.Root and Fieldset.Root (using render={<CheckboxGroup ... />} as recommended by docs), the hidden <input type="checkbox"> elements created by Checkbox.Root end up with the same id across multiple checkboxes.
This also leads to label[for] collisions when using Field.Label (same for and same label id reused across multiple items).
This violates HTML id uniqueness rules and breaks label → control associations (and can confuse assistive tech and testing tools).
Reproducible example
import * as React from "react";
import { Field } from "@base-ui/react/field";
import { Fieldset } from "@base-ui/react/fieldset";
import { CheckboxGroup } from "@base-ui/react/checkbox-group";
import { Checkbox } from "@base-ui/react/checkbox";
export default function Repro() {
return (
<Field.Root name="allowedNetworkProtocols">
<Fieldset.Root render={<CheckboxGroup defaultValue={["https"]} />}>
<Fieldset.Legend>Allowed network protocols</Fieldset.Legend>
{/* Version A: native label */}
<label>
<Checkbox.Root value="http" />
HTTP
</label>
<label>
<Checkbox.Root value="https" />
HTTPS
</label>
<label>
<Checkbox.Root value="ssh" />
SSH
</label>
{/* Version B: Field.Label (also shows duplicate ids/for) */}
{/*
<Field.Label>
<Checkbox.Root value="http" />
HTTP
</Field.Label>
<Field.Label>
<Checkbox.Root value="https" />
HTTPS
</Field.Label>
<Field.Label>
<Checkbox.Root value="ssh" />
SSH
</Field.Label>
*/}
</Fieldset.Root>
</Field.Root>
);
}Actual Results
Inspecting the DOM shows:
Version A (native )
All hidden inputs share the same id, e.g.:
<input id="base-ui-_r_1or_" ... name="allowedNetworkProtocols" />
<input id="base-ui-_r_1or_" ... name="allowedNetworkProtocols" />
<input id="base-ui-_r_1or_" ... name="allowedNetworkProtocols" />(IDs differ per run, but within the same render they are duplicated.)
Version B (<Field.Label>)
Multiple labels share the same for and the same label element id is reused:
<label for="base-ui-_r_1s7_" id="base-ui-_r_1sh_">...</label>
<label for="base-ui-_r_1s7_" id="base-ui-_r_1sh_">...</label>
<label for="base-ui-_r_1s7_" id="base-ui-_r_1sh_">...</label>
<input id="base-ui-_r_1s7_" ... />
<input id="base-ui-_r_1s7_" ... />
<input id="base-ui-_r_1s7_" ... />So multiple checkboxes end up referencing the same id.
Expected result
Each checkbox’s hidden <input> should have a unique id, and each label should reference the correct control.
At minimum:
no duplicate id values in the subtree
Field.Label should not generate duplicated for/id across sibling items
Why this matters
- HTML validity: duplicate IDs are invalid.
- Accessibility: label associations can be incorrect/ambiguous.
- Testing: getByLabelText, Playwright label selectors, etc. can become flaky.
- Potential UX: clicking a label may toggle the wrong checkbox depending on how associations resolve.
Base UI version
v1.1.0
Which browser are you using?
Chrome
Which OS are you using?
Windows
Additional context
Environment
- react: 19.2.0
- react-dom: 19.2.0
- @base-ui/react: 1.1.0 (please fill exact)
Notes / suspicion
This looks like an ID generation / context bug where the Field.Root name="..." + Fieldset.Root composition causes the same generated ID to be reused for multiple checkbox inputs, rather than generating per-checkbox IDs.