Use the directive on native radio inputs and pair it with kui-field for group label, hint, and error wiring.

radio.ts
import { KuiFieldComponent, KuiRadioDirective } from '@kikita-labs/ui';

Share a native name across radio inputs to make the choice mutually exclusive. Keep a native label around each option.

Choose a billing plan

<kui-field label="Plan" hint="Choose a billing plan">
  <div role="radiogroup" class="radio-group" aria-label="Plan">
    <label class="radio-option">
      <input
        kuiRadio
        type="radio"
        name="plan"
        value="starter"
        [checked]="plan() === 'starter'"
        (change)="plan.set('starter')"
      />
      <span>Starter</span>
    </label>
    <label class="radio-option">
      <input
        kuiRadio
        type="radio"
        name="plan"
        value="pro"
        [checked]="plan() === 'pro'"
        (change)="plan.set('pro')"
      />
      <span>Pro</span>
    </label>
  </div>
</kui-field>

Match radio size to surrounding field density and text scale.

<div class="radio-size-example">
  <label class="radio-option">
    <input kuiRadio type="radio" name="radio-size-xs" size="xs" checked />
    <span>Extra small</span>
  </label>
  <label class="radio-option">
    <input kuiRadio type="radio" name="radio-size-sm" size="sm" checked />
    <span>Small</span>
  </label>
  <label class="radio-option">
    <input kuiRadio type="radio" name="radio-size-md" size="md" checked />
    <span>Medium</span>
  </label>
  <label class="radio-option">
    <input kuiRadio type="radio" name="radio-size-lg" size="lg" checked />
    <span>Large</span>
  </label>
</div>

Disable individual options inside a radio group with the native disabled attribute.

<div role="radiogroup" class="radio-group" aria-label="Delivery speed">
  <label class="radio-option">
    <input kuiRadio type="radio" name="delivery" value="standard" checked />
    <span>Standard</span>
  </label>
  <label class="radio-option">
    <input kuiRadio type="radio" name="delivery" value="express" />
    <span>Express</span>
  </label>
  <label class="radio-option radio-option--disabled">
    <input kuiRadio type="radio" name="delivery" value="same-day" disabled />
    <span>Same day (unavailable in this region)</span>
  </label>
</div>

Inside kui-field, setting error text marks projected radio inputs invalid automatically. Use the invalid input directly only when a radio is used outside a field.

<kui-field label="Payment method" error="Select a payment method to continue" required>
  <div role="radiogroup" class="radio-group" aria-label="Payment method">
    <label class="radio-option">
      <input kuiRadio type="radio" name="payment" value="card" />
      <span>Card</span>
    </label>
    <label class="radio-option">
      <input kuiRadio type="radio" name="payment" value="bank-transfer" />
      <span>Bank transfer</span>
    </label>
  </div>
</kui-field>

Bind each native radio input with [formField] on an Angular Signal Forms field.

html.html
<kui-field label="Plan" hint="Choose a billing plan">
  <label>
    <input kuiRadio type="radio" name="plan" value="pro" [formField]="billingForm.plan" />
    Pro
  </label>
</kui-field>

Inputs verified against @kikita-labs/ui v1.6.1 public typings.

NameTypeDefaultDescription
size'xs' | 'sm' | 'md' | 'lg'Radio size mapped to Kikita radio tokens.
invalidbooleanMarks the radio invalid outside a kui-field error state.
idstring | undefinedExplicit id override. Inside kui-field, the field id is used when omitted.

Radio keeps native input semantics and adds field-described state when used inside kui-field.

  • Use a native label for each radio option's text.
  • Share a native name across radio inputs in the same group so keyboard arrow navigation and mutual exclusion work without extra scripting.
  • Wrap the group in a role="radiogroup" element with an accessible name (an aria-label or a kui-field label) so assistive technology announces the set.
  • Use kui-field for group label, hint, error, and described-by wiring.
  • Use native checked and disabled states; do not replace the input with a custom role.
  • Use invalid only when the radio is outside a field error state.