Radio Group
Radio group for selecting a single option from a list.
Import
import { AvRadioGroupImports } from '@avesra/angular';Usage
Choose the plan that suits you best
Includes 100 messages per month
Includes 200 messages per month
Unlimited messages
import { Component } from '@angular/core';
import {
AvDescriptionComponent,
AvLabelComponent,
AvRadioGroupImports,
} from '@avesra/angular';
@Component({
selector: 'app-radio-group-basic-demo',
imports: [
AvRadioGroupImports,
AvLabelComponent,
AvDescriptionComponent,
],
template: `<av-radio-group default-value="premium" name="plan">
<label av-label>Plan selection</label>
<p av-description>Choose the plan that suits you best</p>
<div av-radio value="basic">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Basic Plan
<p av-description>Includes 100 messages per month</p>
</span>
</div>
<div av-radio value="premium">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Premium Plan
<p av-description>Includes 200 messages per month</p>
</span>
</div>
<div av-radio value="business">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Business Plan
<p av-description>Unlimited messages</p>
</span>
</div>
</av-radio-group>`,
})
export class RadioGroupBasicDemo {}Anatomy
Import the RadioGroup parts and compose them with attribute selectors. Compose with shared av-label, av-description, and av-field-error for group chrome and validation.
<av-radio-group>
<label av-label></label>
<p av-description></p> <!-- Optional -->
<div av-radio value="option1">
<span av-radio-control>
<span av-radio-indicator>
<span>✓</span> <!-- Custom indicator (optional) -->
</span>
</span>
<span av-radio-content>
Label <!-- plain text — the clickable label -->
<p av-description></p> <!-- Optional per-radio help text -->
</span>
</div>
<p av-field-error></p> <!-- Optional — group-level validation -->
</av-radio-group>Horizontal Orientation
Set orientation="horizontal" to lay out radio options in a row.
For side projects
Advanced reporting
Up to 10 teammates
import { Component } from '@angular/core';
import {
AvDescriptionComponent,
AvLabelComponent,
AvRadioGroupImports,
} from '@avesra/angular';
@Component({
selector: 'app-radio-group-horizontal-demo',
imports: [
AvRadioGroupImports,
AvLabelComponent,
AvDescriptionComponent,
],
template: `<div class="flex flex-col gap-4">
<label av-label>Subscription plan</label>
<av-radio-group
default-value="pro"
name="plan-orientation"
orientation="horizontal"
>
<div av-radio value="starter">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Starter
<p av-description>For side projects</p>
</span>
</div>
<div av-radio value="pro">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Pro
<p av-description>Advanced reporting</p>
</span>
</div>
<div av-radio value="teams">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Teams
<p av-description>Up to 10 teammates</p>
</span>
</div>
</av-radio-group>
</div>`,
})
export class RadioGroupHorizontalDemo {}Variants
The RadioGroup component supports two visual variants:
primary(default) — Standard styling with default background, suitable for most use casessecondary— Lower emphasis variant, suitable for use in Surface components
Primary variant
Standard styling with default background
Another option with primary styling
Secondary variant
Lower emphasis variant for use in surfaces
Another option with secondary styling
import { Component } from '@angular/core';
import {
AvDescriptionComponent,
AvRadioGroupImports,
} from '@avesra/angular';
@Component({
selector: 'app-radio-group-variants-demo',
imports: [
AvRadioGroupImports,
AvDescriptionComponent,
],
template: `<div class="flex flex-col gap-8">
<div class="flex flex-col gap-2">
<p class="text-sm font-medium text-muted">Primary variant</p>
<av-radio-group default-value="option1" name="primary-plan" variant="primary">
<div av-radio value="option1">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Option 1
<p av-description>Standard styling with default background</p>
</span>
</div>
<div av-radio value="option2">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Option 2
<p av-description>Another option with primary styling</p>
</span>
</div>
</av-radio-group>
</div>
<div class="flex flex-col gap-2">
<p class="text-sm font-medium text-muted">Secondary variant</p>
<av-radio-group
default-value="option1"
name="secondary-plan"
variant="secondary"
>
<div av-radio value="option1">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Option 1
<p av-description>Lower emphasis variant for use in surfaces</p>
</span>
</div>
<div av-radio value="option2">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Option 2
<p av-description>Another option with secondary styling</p>
</span>
</div>
</av-radio-group>
</div>
</div>`,
})
export class RadioGroupVariantsDemo {}In Surface
When used inside a av-surface component, use variant="secondary" to apply the lower emphasis variant suitable for surface backgrounds.
Choose the plan that suits you best
Includes 100 messages per month
Includes 200 messages per month
Unlimited messages
import { Component } from '@angular/core';
import {
AvDescriptionComponent,
AvLabelComponent,
AvRadioGroupImports,
AvSurfaceComponent,
} from '@avesra/angular';
@Component({
selector: 'app-radio-group-on-surface-demo',
imports: [
AvSurfaceComponent,
AvRadioGroupImports,
AvLabelComponent,
AvDescriptionComponent,
],
template: `<div av-surface class="w-full rounded-3xl p-6">
<av-radio-group
default-value="premium"
name="plan-on-surface"
variant="secondary"
>
<label av-label>Plan selection</label>
<p av-description>Choose the plan that suits you best</p>
<div av-radio value="basic">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Basic Plan
<p av-description>Includes 100 messages per month</p>
</span>
</div>
<div av-radio value="premium">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Premium Plan
<p av-description>Includes 200 messages per month</p>
</span>
</div>
<div av-radio value="business">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Business Plan
<p av-description>Unlimited messages</p>
</span>
</div>
</av-radio-group>
</div>`,
})
export class RadioGroupOnSurfaceDemo {}Disabled
Plan changes are temporarily paused while we roll out updates.
For side projects and small teams
Advanced reporting and analytics
Share access with up to 10 teammates
import { Component } from '@angular/core';
import {
AvDescriptionComponent,
AvLabelComponent,
AvRadioGroupImports,
} from '@avesra/angular';
@Component({
selector: 'app-radio-group-disabled-demo',
imports: [
AvRadioGroupImports,
AvLabelComponent,
AvDescriptionComponent,
],
template: `<av-radio-group disabled default-value="pro" name="plan-disabled">
<label av-label>Subscription plan</label>
<p av-description>
Plan changes are temporarily paused while we roll out updates.
</p>
<div av-radio value="starter">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Starter
<p av-description>For side projects and small teams</p>
</span>
</div>
<div av-radio value="pro">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Pro
<p av-description>Advanced reporting and analytics</p>
</span>
</div>
<div av-radio value="teams">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Teams
<p av-description>Share access with up to 10 teammates</p>
</span>
</div>
</av-radio-group>`,
})
export class RadioGroupDisabledDemo {}Controlled
Bind the selected value with [(value)] for fully controlled usage.
For side projects and small teams
Advanced reporting and analytics
Share access with up to 10 teammates
Selected plan: pro
import { Component, signal } from '@angular/core';
import {
AvDescriptionComponent,
AvLabelComponent,
AvRadioGroupImports,
} from '@avesra/angular';
@Component({
selector: 'app-radio-group-controlled-demo',
imports: [
AvRadioGroupImports,
AvLabelComponent,
AvDescriptionComponent,
],
template: `<div class="flex flex-col gap-4">
<av-radio-group name="plan-controlled" [(value)]="value">
<label av-label>Subscription plan</label>
<div av-radio value="starter">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Starter
<p av-description>For side projects and small teams</p>
</span>
</div>
<div av-radio value="pro">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Pro
<p av-description>Advanced reporting and analytics</p>
</span>
</div>
<div av-radio value="teams">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Teams
<p av-description>Share access with up to 10 teammates</p>
</span>
</div>
</av-radio-group>
<p class="text-sm text-muted">
Selected plan: <span class="font-medium">{{ value() }}</span>
</p>
</div>`,
})
export class RadioGroupControlledDemo {
readonly value = signal<string | null>('pro');
}Uncontrolled
Combine default-value with (valueChange) when you only need to react to updates.
For side projects and small teams
Advanced reporting and analytics
Share access with up to 10 teammates
Last chosen plan: pro
import { Component, signal } from '@angular/core';
import {
AvDescriptionComponent,
AvLabelComponent,
AvRadioGroupImports,
} from '@avesra/angular';
@Component({
selector: 'app-radio-group-uncontrolled-demo',
imports: [
AvRadioGroupImports,
AvLabelComponent,
AvDescriptionComponent,
],
template: `<div class="flex flex-col gap-4">
<av-radio-group
default-value="pro"
name="plan-uncontrolled"
(valueChange)="selection.set($event)"
>
<label av-label>Subscription plan</label>
<div av-radio value="starter">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Starter
<p av-description>For side projects and small teams</p>
</span>
</div>
<div av-radio value="pro">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Pro
<p av-description>Advanced reporting and analytics</p>
</span>
</div>
<div av-radio value="teams">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Teams
<p av-description>Share access with up to 10 teammates</p>
</span>
</div>
</av-radio-group>
<p class="text-sm text-muted">
Last chosen plan: <span class="font-medium">{{ selection() }}</span>
</p>
</div>`,
})
export class RadioGroupUncontrolledDemo {
readonly selection = signal<string | null>('pro');
}Validation
import { Component, computed, signal } from '@angular/core';
import {
AvButtonComponent,
AvDescriptionComponent,
AvFieldErrorComponent,
AvFormComponent,
AvLabelComponent,
AvRadioGroupImports,
} from '@avesra/angular';
@Component({
selector: 'app-radio-group-validation-demo',
imports: [
AvFormComponent,
AvRadioGroupImports,
AvLabelComponent,
AvDescriptionComponent,
AvFieldErrorComponent,
AvButtonComponent,
],
template: `<form
av-form
class="flex flex-col gap-4"
(submit)="onSubmit($event)"
>
<av-radio-group
name="plan-validation"
[(value)]="selected"
[invalid]="isInvalid()"
>
<label av-label required [invalid]="isInvalid()">Subscription plan</label>
<div av-radio value="starter">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Starter
<p av-description>For side projects and small teams</p>
</span>
</div>
<div av-radio value="pro">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Pro
<p av-description>Advanced reporting and analytics</p>
</span>
</div>
<div av-radio value="teams">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Teams
<p av-description>Share access with up to 10 teammates</p>
</span>
</div>
<p av-field-error [visible]="isInvalid()">
Choose a subscription before continuing.
</p>
</av-radio-group>
<button av-button class="mt-2 w-fit" type="submit">Submit</button>
@if (message(); as msg) {
<p class="text-sm text-muted">{{ msg }}</p>
}
</form>`,
})
export class RadioGroupValidationDemo {
readonly selected = signal<string | null>(null);
readonly submitted = signal(false);
readonly message = signal<string | null>(null);
readonly isInvalid = computed(
() => this.submitted() && this.selected() === null,
);
onSubmit(event: Event): void {
event.preventDefault();
this.submitted.set(true);
this.message.set(null);
if (this.selected() === null) {
return;
}
const form = event.target as HTMLFormElement;
const formData = new FormData(form);
const value = formData.get('plan-validation');
this.message.set(`Your chosen plan is: ${value}`);
}
}Delivery & Payment
4-10 business days
2-5 business days
1 business day
Exp. on 01/2026
Exp. on 01/2026
Pay with PayPal
import { Component } from '@angular/core';
import {
AvDescriptionComponent,
AvLabelComponent,
AvRadioGroupImports,
} from '@avesra/angular';
import { AppIconComponent } from '../../components/app-icon/app-icon.component';
@Component({
selector: 'app-radio-group-delivery-and-payment-demo',
imports: [
AvRadioGroupImports,
AvLabelComponent,
AvDescriptionComponent,
AppIconComponent,
],
template: `<div class="flex w-full flex-col items-center gap-10 px-4 py-4">
<section class="flex w-full max-w-lg flex-col gap-4">
<av-radio-group class="gap-3" default-value="express" name="delivery" variant="secondary">
<label av-label>Delivery method</label>
<div class="grid items-stretch gap-4 md:grid-cols-3">
@for (option of deliveryOptions; track option.value) {
<div av-radio [value]="option.value" class="group mt-0 h-full w-full items-stretch">
<span
av-radio-content
class="relative flex h-full w-full flex-col gap-6 rounded-xl border border-transparent bg-surface px-5 py-4 pe-12 transition-all group-data-[selected=true]:border-accent group-data-[selected=true]:bg-accent/10"
>
<span av-radio-control class="absolute top-3 end-4 mt-0 size-5">
<span av-radio-indicator></span>
</span>
<div class="flex flex-col gap-1">
<span>{{ option.title }}</span>
<p av-description>{{ option.description }}</p>
</div>
<span class="mt-auto text-sm font-semibold">{{ option.price }}</span>
</span>
</div>
}
</div>
</av-radio-group>
</section>
<section class="flex w-full max-w-lg flex-col gap-4">
<av-radio-group class="gap-3" default-value="visa" name="payment" variant="secondary">
<label av-label>Payment method</label>
<div class="grid items-stretch gap-4 md:grid-cols-2">
@for (option of paymentOptions; track option.value) {
<div av-radio [value]="option.value" class="group mt-0 h-full w-full items-stretch">
<span
av-radio-content
class="relative flex h-full w-full flex-row items-start justify-start gap-4 rounded-xl border border-transparent bg-surface px-5 py-4 pe-12 transition-all group-data-[selected=true]:border-accent group-data-[selected=true]:bg-accent/10"
>
<span av-radio-control class="absolute top-3 end-4 mt-0 size-5">
<span av-radio-indicator></span>
</span>
<app-icon
[icon]="option.icon"
size="24"
class="size-6 shrink-0 text-accent-soft-foreground"
/>
<div class="flex min-w-0 flex-col gap-1">
<span>{{ option.title }}</span>
<p av-description>{{ option.description }}</p>
</div>
</span>
</div>
}
</div>
</av-radio-group>
</section>
</div>`,
})
export class RadioGroupDeliveryAndPaymentDemo {
readonly deliveryOptions = [
{
description: '4-10 business days',
price: '$5.00',
title: 'Standard',
value: 'standard',
},
{
description: '2-5 business days',
price: '$16.00',
title: 'Express',
value: 'express',
},
{
description: '1 business day',
price: '$25.00',
title: 'Super Fast',
value: 'super-fast',
},
];
readonly paymentOptions = [
{
description: 'Exp. on 01/2026',
icon: 'solar:card-linear',
title: '**** 8304',
value: 'mastercard',
},
{
description: 'Exp. on 01/2026',
icon: 'solar:card-2-linear',
title: '**** 0123',
value: 'visa',
},
{
description: 'Pay with PayPal',
icon: 'solar:wallet-money-linear',
title: 'PayPal',
value: 'paypal',
},
];
}Custom Indicator
Choose the plan that suits you best
Includes 100 messages per month
Includes 200 messages per month
Unlimited messages
import { Component, signal } from '@angular/core';
import {
AvDescriptionComponent,
AvLabelComponent,
AvRadioGroupImports,
} from '@avesra/angular';
@Component({
selector: 'app-radio-group-custom-indicator-demo',
imports: [
AvRadioGroupImports,
AvLabelComponent,
AvDescriptionComponent,
],
template: `<av-radio-group
default-value="premium"
name="plan-custom-indicator"
[(value)]="selected"
>
<label av-label>Plan selection</label>
<p av-description>Choose the plan that suits you best</p>
<div av-radio value="basic">
<span av-radio-control>
<span av-radio-indicator>
@if (selected() === 'basic') {
<span class="text-xs leading-none text-accent-foreground">✓</span>
}
</span>
</span>
<span av-radio-content>
Basic Plan
<p av-description>Includes 100 messages per month</p>
</span>
</div>
<div av-radio value="premium">
<span av-radio-control>
<span av-radio-indicator>
@if (selected() === 'premium') {
<span class="text-xs leading-none text-accent-foreground">✓</span>
}
</span>
</span>
<span av-radio-content>
Premium Plan
<p av-description>Includes 200 messages per month</p>
</span>
</div>
<div av-radio value="business">
<span av-radio-control>
<span av-radio-indicator>
@if (selected() === 'business') {
<span class="text-xs leading-none text-accent-foreground">✓</span>
}
</span>
</span>
<span av-radio-content>
Business Plan
<p av-description>Unlimited messages</p>
</span>
</div>
</av-radio-group>`,
})
export class RadioGroupCustomIndicatorDemo {
readonly selected = signal<string | null>('premium');
}Reactive form
Integrate with Angular reactive forms using [formControl] or formControlName on av-radio-group.
For side projects and small teams
Advanced reporting and analytics
Share access with up to 10 teammates
Form value: pro
import { Component } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import {
AvDescriptionComponent,
AvLabelComponent,
AvRadioGroupImports,
} from '@avesra/angular';
@Component({
selector: 'app-radio-group-reactive-form-demo',
imports: [
ReactiveFormsModule,
AvRadioGroupImports,
AvLabelComponent,
AvDescriptionComponent,
],
template: `<div class="flex flex-col gap-4">
<av-radio-group class="min-w-[320px]" [formControl]="planControl">
<label av-label>Subscription plan</label>
<div av-radio value="starter">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Starter
<p av-description>For side projects and small teams</p>
</span>
</div>
<div av-radio value="pro">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Pro
<p av-description>Advanced reporting and analytics</p>
</span>
</div>
<div av-radio value="teams">
<span av-radio-control>
<span av-radio-indicator></span>
</span>
<span av-radio-content>
Teams
<p av-description>Share access with up to 10 teammates</p>
</span>
</div>
</av-radio-group>
<p class="text-sm text-muted">
Form value: <span class="font-medium">{{ planControl.value }}</span>
</p>
</div>`,
})
export class RadioGroupReactiveFormDemo {
readonly planControl = new FormControl<string | null>('pro');
}Styling
Passing Tailwind CSS classes
Pass utility classes on av-radio-group, av-radio, and part hosts such as av-radio-control.
import { Component } from '@angular/core';
import { AvRadioGroupImports } from '@avesra/angular';
@Component({
selector: 'app-radio-group-custom-styling-demo',
imports: [AvRadioGroupImports],
template: `<av-radio-group default-value="premium" name="plan" class="gap-3">
<div
av-radio
value="basic"
class="group cursor-pointer rounded-xl border-2 border-border p-4 hover:border-blue-300 data-[selected=true]:border-blue-500 data-[selected=true]:bg-blue-500/10"
>
<span
av-radio-control
class="border-2 border-border group-hover:border-blue-400 group-data-[selected=true]:border-blue-500 group-data-[selected=true]:bg-blue-500"
>
<span av-radio-indicator></span>
</span>
Basic Plan
</div>
<div
av-radio
value="premium"
class="group cursor-pointer rounded-xl border-2 border-border p-4 hover:border-purple-300 data-[selected=true]:border-purple-500 data-[selected=true]:bg-purple-500/10"
>
<span
av-radio-control
class="border-2 border-border group-hover:border-purple-400 group-data-[selected=true]:border-purple-500 group-data-[selected=true]:bg-purple-500"
>
<span av-radio-indicator></span>
</span>
Premium Plan
</div>
<div
av-radio
value="business"
class="group cursor-pointer rounded-xl border-2 border-border p-4 hover:border-emerald-300 data-[selected=true]:border-emerald-500 data-[selected=true]:bg-emerald-500/10"
>
<span
av-radio-control
class="border-2 border-border group-hover:border-emerald-400 group-data-[selected=true]:border-emerald-500 group-data-[selected=true]:bg-emerald-500"
>
<span av-radio-indicator></span>
</span>
Business Plan
</div>
</av-radio-group>`,
})
export class RadioGroupCustomStylingDemo {}Customizing the component classes
To customize the RadioGroup classes, use the @layer components directive. Learn more.
@layer components {
.av-radio-group {
@apply gap-2;
}
.av-radio {
@apply gap-4 rounded-lg border border-border p-3 hover:bg-surface-hovered;
}
.av-radio__control {
@apply border-2 border-accent;
}
.av-radio__indicator {
@apply bg-accent;
}
.av-radio__content {
@apply gap-1;
}
}Avesra follows the BEM methodology so component variants and states stay reusable and easy to customize.
CSS Classes
The RadioGroup component uses these CSS classes:
Base & Element Classes
.av-radio-group— Base radio group container.av-radio— Individual radio item.av-radio__content— Content wrapper for label and description.av-radio__control— Radio control (circular button).av-radio__indicator— Radio indicator (inner dot)
Modifier Classes
.av-radio-group--primary— Primary visual variant.av-radio-group--secondary— Secondary visual variant (inherited by children).av-radio-group--vertical— Vertical layout (default).av-radio-group--horizontal— Horizontal layout.av-radio--primary/.av-radio--secondary— Per-radio variants
Interactive States
The radio supports both CSS pseudo-classes and data attributes for flexibility:
- Selected:
[aria-checked="true"]or[data-selected="true"](indicator appears) - Hover:
:hoveror[data-hovered="true"] - Focus:
:focus-visibleor[data-focus-visible="true"] - Pressed:
:activeor[data-pressed="true"] - Disabled:
:disabled,[data-disabled="true"], or[aria-disabled="true"] - Invalid:
[data-invalid="true"]or[aria-invalid="true"]
API
RadioGroup
Props for av-radio-group. Implements ControlValueAccessor for Angular forms.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'primary' | 'secondary' | 'primary' | Visual variant of the group. `primary` is the default style with shadow. `secondary` is a lower emphasis variant without shadow, suitable for use in surfaces. |
orientation | 'vertical' | 'horizontal' | 'vertical' | The orientation of the radio group. |
disabled | boolean | false | Whether the radio group is disabled. Cascades to all child radios. |
invalid | boolean | false | Whether the radio group is in an invalid state. Cascades to all child radios. |
name | string | — | The name of the radio group, used when submitting an HTML form. |
default-value | string | null | null | The default value (uncontrolled). |
value | string | null | null | The current value (controlled). Supports two-way binding with `[(value)]`. |
valueChange | EventEmitter<string | null> | — | Emits when the selected value changes. |
Radio
Props for div[av-radio]. span[av-radio-control], span[av-radio-indicator], and span[av-radio-content] project content and have no inputs.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Option value when used inside `av-radio-group`. Required in groups. |
variant | 'primary' | 'secondary' | — | Visual style variant. Inherits from `av-radio-group` when omitted. |
disabled | boolean | false | Disables interaction. Also set by reactive forms or parent group. |
invalid | boolean | false | Marks the radio as invalid. Inherits from parent group when omitted. |
name | string | — | Form field name for native form submission. Inherits from parent group when omitted. |
aria-label | string | — | Accessible label when no visible label is provided. |