Choice & selection

AppRadioGroup

A labelled set of radios that lines up like any other field, with the hint or error below.

<app-radio-group label="Billing cycle" name="billing"><app-option value="monthly">Monthly</app-option></app-radio-group>

<app-radio-group> is a labelled set of radios. The label sits where every other field's label sits, above the options or beside them inside a form section. The hint or error goes below, in the same place as on a text field.

It is a role="radiogroup" named by its label, not a fieldset with a legend. A legend renders at heading size and cannot join the field grid, so the label would sit apart from the other fields on the form. Selection is the native radio, so arrow keys, the single tab stop and posting in a plain form all work without JavaScript. Bind it to a model with asp-for and it takes the name, the selected value, the label, the required mark and the validation message from the property.

Playground

Every attribute, live. Each change re-renders the real tag helper on the server. The selected value comes from clicking the preview itself, the same as a real screen. The markup underneath is the exact call that produced the group above it.

Billing cycle
<app-radio-group name="billing" label="Billing cycle" value="monthly">
    <app-option value="monthly">Monthly</app-option>
    <app-option value="quarterly">Quarterly</app-option>
    <app-option value="yearly">Yearly</app-option>
</app-radio-group>

Basic

A label, a name, the selected value, and one <app-option> child per radio. The options stack in a column by default.

A stacked group
The option's text is its label. Its value is what posts.
Delivery speed
Show code
<app-radio-group label="Delivery speed" name="delivery" value="standard">
    <app-option value="standard">Standard (3 to 5 days)</app-option>
    <app-option value="express">Express (1 to 2 days)</app-option>
    <app-option value="same-day">Same day (Mumbai, Delhi, Bengaluru)</app-option>
</app-radio-group>
Bind to a modelUse asp-for="Plan.BillingCycle" instead of name, value and label. The tag helper reads the name, the selected value, the display name, the required mark and the validation message from the property.

Inline

Set inline="true" to lay the options out in a row. They wrap onto the next line when the container is narrow.

A row of options
Best for short labels such as billing periods.
Billing cycle
Show code
<app-radio-group inline="true" label="Billing cycle" name="billing" value="monthly">…</app-radio-group>

States

A hint explains the choice. An error replaces the hint. required adds the star and marks the group for assistive tech. Disable one option or the whole group.

Hint, error, required and disabled
Billing cycle
Yearly billing saves two months.
Delivery speed
Choose a delivery speed.
Delivery speed (one option off)
Billing cycle (disabled)
Show code
<app-radio-group hint="You can change this later." …>…</app-radio-group>
<app-radio-group error="Choose a delivery speed." required="true" …>…</app-radio-group>
<app-option value="same-day" disabled="true">Same day</app-option>
<app-radio-group disabled="true" …>…</app-radio-group>
Error beats hintWhen both are set, only the error shows. The group is marked invalid and the error text is linked to it for screen readers. With asp-for, a model validation message shows in the same place.

When to use

Use it when

  • Two to five exclusive options, and the reader should see all of them before choosing.
  • The choice is a field in a form that sits in the same grid as the other fields.
  • You need a hint, an error or a required mark on the group as a whole.

Reach for something else when

  • There are six or more options. → app-select
  • It is a control strip that changes a view at once. → app-segmented
  • Each option needs an icon, an image or a description. → app-choice-card
  • You need one standalone radio, not a group. → app-radio

Every option

The whole surface of the component, one cell per value. Each group here has its own name, so the radios never interfere.

inline: column vs. row

inline="false"
Billing cycle
inline="true"
Billing cycle

required

required="true"
Billing cycle

disabled: whole group vs. one option

disabled="true"
Billing cycle
app-option disabled="true"
Delivery speed

error and hint

error="Choose a billing cycle."
Billing cycle
Choose a billing cycle.
hint="Yearly billing saves two months."
Billing cycle
Yearly billing saves two months.

Attributes

AttributeTypeDefaultDescription
asp-forModelExpression-The model property to bind to. Supplies the name, the selected value, the label, the required mark and the validation message.
labelstring-The visible group label. It is also the group's accessible name.
namestringgeneratedThe shared name of the radios, and what posts. Falls back to the group's id.
valuestring-The selected option's value. React has both value and defaultValue; Razor has this one.
inlineboolfalseLays the options out in a row that wraps, instead of a column.
requiredboolfalseAdds the required star and marks the group and its radios as required.
disabledboolfalseDisables every option. A single option: <app-option disabled="true">.
errorstring-Error text below the group. Replaces the hint and marks the group invalid.
hintstring-Helper text below the group.
helpstring-Content for the info-tip beside the label.
help-labelstringMore informationThe accessible name of the info-tip button.
idstringgeneratedThe id of the group. Options take {id}-0, {id}-1 and so on.
input-classstring-Extra classes on the group (the control). React's className. A style attribute lands here too.
classstring-A plain class lands on the .field wrapper. React's fieldClassName.
app-option valuestring-On an <app-option> child: the value that posts when this radio is chosen.
app-option disabledboolfalseOn an <app-option> child: keeps the option visible but unpickable. The element's content is its label.
defaultValuestring-React-only. Use value in Razor.
onChange(value) => void-React-only. Razor posts the chosen value with the form.