Radio buttons allow users to select from a set of mutually exclusive, related options.

Normal
Big
Normal
Error
Text
Text with Caption
Field label

To show a validation error, bind the group to a form control, apply required or Validators.required, and put the error text in a kbq-error inside the group.

To show the error at another moment, pass a matcher to the errorStateMatcher input: the example below shows the error only after the form is submitted. The matchers are described in the Validation guide.

Second sign-in factor
Save without choosing to see the error

The component installs no key handlers of its own. The options are real <input type="radio"> elements sharing a name, so the browser supplies the whole interaction:

  • A group is a single tab stop. Tab enters it at the checked option — or at the first enabled one when nothing is checked — and the next Tab leaves the group entirely.
  • The arrow keys move between options and select as they move, so a group cannot be traversed without changing its value. Disabled options are skipped.
  • Space selects the focused option.

Grouping follows name rather than the markup: buttons sharing a name are one tab stop even when they sit in different containers, and a button used outside a group is named uniquely to itself and is therefore its own tab stop.

A kbq-radio-group is announced as a radiogroup, which does not take its name from the options inside it. Point it at the visible group label instead — write aria-labelledby (or aria-label) directly on the element, the way you would on any other host:

<div id="delivery-label" class="kbq-form__label">Delivery</div>
<kbq-radio-group aria-labelledby="delivery-label">
<kbq-radio-button [value]="'pickup'">Pickup</kbq-radio-button>
<kbq-radio-button [value]="'courier'">Courier</kbq-radio-button>
</kbq-radio-group>

A kbq-hint projected into a button is exposed as its description, not as part of its name, so an option is announced by its own text and the caption is left for assistive technology to defer.

[required] on the group reaches the radiogroup as aria-required, and a group colored with the error palette or in the error state reaches it as aria-invalid. The error and the hint of the group are announced as its description, together with an aria-describedby you set on the group yourself.

focus() on a button — or on the group, which forwards to the checked option — accepts a FocusOrigin. Pass 'keyboard' when you move focus in response to a keyboard action, so the focus ring is visible; the default 'program' moves focus without one.

Every group generates a unique name, and its buttons inherit it, so nothing has to be named by hand. A button used outside a group falls back to an id unique to itself and is therefore independent of every other ungrouped radio in the application.

Name the group explicitly when it has to participate in a native <form> submission: that name is the field name in the payload, and a generated one changes between application loads. The button's value is submitted as a string, so only string-like values round-trip.

  • By default, it is recommended to use up to 7 options in a Radio Group.
  • Use Button Toggle for short options when there is sufficient horizontal space.
  • If more than 7 options need to be displayed, it is better to use Select.
  • If the selection involves two values and can be classified as boolean, use Toggle. Toggle applies changes instantly, without additional data saving.
Suggestions for improvement
If you found a mistake or want to improve the article, create an issue on GitHub.