Prototype Library

Radio Group

Single-select from an options list; the value is the chosen string. Vertical or horizontal orientation, per-option disabled, Space/Enter selection, pure-CSS dot. The options attribute accepts a JSON string. Emits a composed change event.

Inherited wc import '@esa/ecology/esa-radio-group';

Preview

<esa-radio-group
  label="Priority"
  options='[{"label":"Low","value":"low"}, …]'
  value="medium"
></esa-radio-group>

Orientation

vertical is the default; switch to horizontal to lay options out in a row.

<esa-radio-group label="Priority" orientation="horizontal" options="…" value="low"></esa-radio-group>

Sizes

<esa-radio-group label="Extra small" size="xs" orientation="horizontal" options="…" value="low"></esa-radio-group>
<esa-radio-group label="Small" size="sm" orientation="horizontal" options="…" value="low"></esa-radio-group>
<esa-radio-group label="Medium" size="md" orientation="horizontal" options="…" value="medium"></esa-radio-group>
<esa-radio-group label="Large" size="lg" orientation="horizontal" options="…" value="high"></esa-radio-group>

Form participation

The selected value is submitted under name. Submitting logs the priority entry.

<form>
  <esa-radio-group label="Priority" name="priority" options="…" value="low"></esa-radio-group>
  <button type="submit">Submit</button>
</form>

API

PropTypeDefaultDescription
options EsaOption[] [] Array of {'{ label, value, disabled? }'}, or a JSON string of the same when set as an attribute.
label string '' Group label rendered above the options.
size 'xs' | 'sm' | 'md' | 'lg' 'md' Circle and label size.
orientation 'vertical' | 'horizontal' 'vertical' Stacking direction of the options.
name string | undefined — Form field name — the key this control submits under.
value string | null null The single selected option value.
required boolean false Whether an option must be chosen. Marked on the GROUP, never on each radio — putting `aria-required` on every option announces "required" per option, which reads as "you must select all of these". The group is the thing that is required.
help-text string '' Property: `helpText`.
error-text string '' Validation message below the group; reddens the legend and renders the error line. Property: `errorText`.
live-error boolean false Announce the error the moment it appears rather than only when the group is entered. Off by default — see the long note on `esa-text-field.liveError`. Property: `liveError`.

Events

EventTypeDefaultDescription
change CustomEvent<{ value: string }> — Fired when a new option is selected. Composed and bubbling; detail.value is the chosen string.
Binding these events from Angular

Every one of these is a CustomEvent, so the payload is on $event.detail — $event.target.value reads empty, with no error. The names are lowercase and Angular passes them to addEventListener verbatim, so camel-casing one means it never fires.

  • (change)="onChange($event.detail)"

Accessibility

  • The options container has role="radiogroup", named by aria-label from the label attribute — so leaving label unset leaves the group unnamed. Always set it, including inside an esa-form-field.
  • Each option has role="radio" with aria-checked and selects on Space or Enter.
  • Known gaps. Arrow keys do not move selection, and every option is a tab stop rather than one roving tab stop — the WAI-ARIA radiogroup pattern expects the reverse. The option text also sits in a sibling <span>: the wrapping <label> cannot name a <span role="radio">, so options currently announce without their text.
  • Disabled options carry aria-disabled and a -1 tabindex.
  • The whole option row is the click target, not just the circle.
  • The change event is composed and bubbles, so it can be caught on the host or an ancestor.