AvesraAvesrabeta

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

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.

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 cases
  • secondary — Lower emphasis variant, suitable for use in Surface components

Primary variant

Secondary variant

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

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.

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.

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.

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

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

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.

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: :hover or [data-hovered="true"]
  • Focus: :focus-visible or [data-focus-visible="true"]
  • Pressed: :active or [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.

PropTypeDefaultDescription
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.
disabledbooleanfalseWhether the radio group is disabled. Cascades to all child radios.
invalidbooleanfalseWhether the radio group is in an invalid state. Cascades to all child radios.
namestring—The name of the radio group, used when submitting an HTML form.
default-valuestring | nullnullThe default value (uncontrolled).
valuestring | nullnullThe current value (controlled). Supports two-way binding with `[(value)]`.
valueChangeEventEmitter<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.

PropTypeDefaultDescription
valuestring—Option value when used inside `av-radio-group`. Required in groups.
variant'primary' | 'secondary'—Visual style variant. Inherits from `av-radio-group` when omitted.
disabledbooleanfalseDisables interaction. Also set by reactive forms or parent group.
invalidbooleanfalseMarks the radio as invalid. Inherits from parent group when omitted.
namestring—Form field name for native form submission. Inherits from parent group when omitted.
aria-labelstring—Accessible label when no visible label is provided.

Made with ❤ by SyntaxHertz. Open source and available on GitHub.