Skip to content

[CheckboxGroup] Multiple required child checkboxes are not all validated #4952

@nami8824

Description

@nami8824

Bug report

Current behavior

When multiple Checkbox.Root components inside a CheckboxGroup are marked as required, validation can incorrectly pass after only one of the required checkboxes is checked.

As a result, the Field.Root can be considered valid even while another required checkbox in the same group is still unchecked.

Expected behavior

Each required child checkbox inside a CheckboxGroup should continue to enforce its own required constraint.

For example, if two child checkboxes are marked as required, checking only one of them should not make the Field.Root valid while the other required checkbox remains unchecked.

Reproducible example

A failing test case reproduces the issue:

packages/react/src/checkbox-group/CheckboxGroup.test.tsx

it('does not clear the required error when another required child checkbox is unchecked', async () => {
  const { user } = render(
    <Form>
      <Field.Root name="apple">
        <Fieldset.Root render={<CheckboxGroup defaultValue={[]} />}>
          <Fieldset.Legend>Allowed network protocols</Fieldset.Legend>
          <Field.Item>
            <Field.Label>
              <Checkbox.Root value="one" data-testid="checkbox" required />
              HTTP
            </Field.Label>
          </Field.Item>
          <Field.Item>
            <Field.Label>
              <Checkbox.Root value="two" data-testid="checkbox" required />
              HTTPS
            </Field.Label>
          </Field.Item>
        </Fieldset.Root>
        <Field.Error match="valueMissing" data-testid="error">
          required
        </Field.Error>
      </Field.Root>
      <button type="submit">submit</button>
    </Form>,
  );

  const checkboxes = screen.getAllByTestId('checkbox');

  await user.click(screen.getByText('submit'));
  expect(screen.getByTestId('error')).toHaveTextContent('required');

  await user.click(checkboxes[1]);
  await user.click(screen.getByText('submit'));

  expect(screen.getByTestId('error')).toHaveTextContent('required');
});

The test fails with TestingLibraryElementError: Unable to find an element by: [data-testid="error"] on the final assertion, because Field.Error is removed after only the second required checkbox is checked.

Base UI version

v1.5.0

Which browser are you using?

Reproduced in the test environment.

Which OS are you using?

macOS

Which assistive tech are you using (if applicable)?

N/A

Additional context

The issue seems related to how Field.Root tracks a single validation input ref. Multiple checkbox inputs inside the same field can register with that ref, but only one input ultimately becomes the active validation target.

Metadata

Metadata

Assignees

No one assigned

    Labels

    component: checkbox groupChanges related to the checkbox group component.has workaroundThere’s a bug, but users have a complete workaround, so no urgent fix or release is needed.
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions