Skip to content

Automatic binding of required input in custom checkbox controls #70147

Description

@quentinderoubaix

Which @angular/* package(s) are the source of the bug?

forms

Is this a regression?

No

Description

Probably not a bug, but requires discussion...

In one line

The required input from a custom checkbox component implementing FormCheckboxControl is binded using Validators.required instead of Validators.requiredTrue.

In details

The context is the following:

  • a design system team is making a new version of a custom checkbox component
  • the old version supported ControlValueAccessor and users were setting this up with ReactiveFormsModule as usual
  • the design system wishes to make the new version of that component implement FormCheckboxControl for signal-based templating
  • the new version should still suport being used with ReactiveFormsModule

A simple implementation of that new component could like this:

@Component({
  selector: 'app-checkbox',
  template: `
    <label [id]="checkboxLabelId">
      {{ label() }}{{ required() ? '*' : ''}}
    </label>
    <input type="checkbox" class="classes" [attr.aria-labelledby]="checkboxLabelId" [required]="required()"/>
  `
})
export class CustomCheckbox implements FormCheckboxControl {
  readonly checked = model(false);

  readonly label = input.required<string>();
  readonly required = input(false, { transform: booleanAttribute });

  readonly checkboxLabelId = `custom-checkbox-label-${++idCount}`;
}

However, when using it with ReactiveFormsModule, setting the Validators.required validator would bind the required input to true, while the Validators.requiredTrue would have zero effect...

You may check the stackblitz link to see the behavior showcased.

Question

Should this automatic binding be different for checkboxes?

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/stackblitz-starters-c43njprg?file=src%2Fmain.ts

Please provide the exception or error you saw


Please provide the environment you discovered this bug in (run ng version)

Angular CLI       : 22.1.3
Angular           : 22.1.1
Node.js           : 22.22.3
Package Manager   : npm 10.8.2
Operating System  : linux x64

┌───────────────────────────┬───────────────────┬───────────────────┐
│ Package                   │ Installed Version │ Requested Version │
├───────────────────────────┼───────────────────┼───────────────────┤
│ @angular/build            │ 22.1.3            │ ^22.0.0           │
│ @angular/cli              │ 22.1.3            │ ^22.0.0           │
│ @angular/common           │ 22.1.1            │ ^22.0.0           │
│ @angular/compiler         │ 22.1.1            │ ^22.0.0           │
│ @angular/compiler-cli     │ 22.1.1            │ ^22.0.0           │
│ @angular/core             │ 22.1.1            │ ^22.0.0           │
│ @angular/forms            │ 22.1.1            │ ^22.0.0           │
│ @angular/platform-browser │ 22.1.1            │ ^22.0.0           │
│ @angular/router           │ 22.1.1            │ ^22.0.0           │
│ rxjs                      │ 7.8.2             │ ^7.8.1            │
│ typescript                │ 6.0.3             │ ~6.0.3            │
└───────────────────────────┴───────────────────┴───────────────────┘

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status
    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions