## radio_group (`poetry_radio_group`)

A set of options where only one can be selected at a time.

Class: Poetry::Ui::RadioGroup::Component - BEM block `poetry-ui-radio_group`.
Slot REQUIRED: with_item (at least one radio item) - a call without it raises.
- `disabled:` (boolean) - default false - Disables every item (root-level).
- `invalid:` (boolean) - default false - aria-invalid on the items (the destructive ring) - set by Field/FormBuilder from model errors.
- `label:` (string) - The group accessible name -> aria-label (or wire aria-labelledby yourself) - REQUIRED: an unlabelled radiogroup fails the audit.
- `loop:` (boolean) - default true - Arrow-key navigation wraps at the ends.
- `name:` (string) - required - The shared form name for every hidden radio (FormBuilder derives object[method]).
- `orientation:` (symbol) - one of both|vertical|horizontal, default "both" - Keyboard axis: :both allows all four arrows (the standard radio pattern); :vertical/:horizontal restrict the axis. No visual effect.
- `required:` (boolean) - default false - aria-required on the ROOT only - never native required on the hidden inputs (constraint-validation focus would land on an aria-hidden input).
- `value:` (string) - The checked item's value; nil = nothing checked (pre-selection).
Slots: items (One item per option: a real button[role=radio] carrying its own hidden native radio; label: renders the dot beside a paired Label. variant: :card renders the choice-card row instead - title (+ optional description:) inside a selectable bordered label, the radio pinned to the right.; many).
- PART `radio-group` - The role=radiogroup root - one Tab stop; items (and their label-pairing rows) render as direct children | states: data-disabled (disabled: is set on the root - every item disables with it)
- PART `radio-group-item` - A button[role=radio] per item - carries its own hidden native radio as a sibling | states: data-checked (the checked item (the controller writes the pair and aria-checked together on every item)); data-unchecked (every other item); data-disabled (the item (or the whole group) is disabled - also the roving-focus collection filter); data-value (always - the item's value (keys the checked-value machine))
- PART `radio-group-indicator` - The theme-sized centering box holding the checked dot (the dot itself is the themed .cn-radio-group-indicator-icon span) - hidden (the native attribute, toggled by the controller) while unchecked
- PART `radio-group-card` - The choice-card row (variant: :card) - a <label> for= the radio button, so the whole card toggles; the checked treatments key on data-checked inside it
- PART `radio-group-card-content` - Text column of a choice-card item (variant: :card) - title and description stack inside the card label
- PART `radio-group-card-title` - The choice card's title line (the item label:)
- PART `radio-group-card-description` - Muted copy under the choice card's title (description:)
- WIRING root: `poetry--core--radio-group` registers; values value (if value?); actions entryCheck on poetry--core--roving-focus:entry | `poetry--core--roving-focus` registers; values orientation, loop; actions keydown on keydown
- WIRING item: `poetry--core--radio-group` actions check on click
- WIRING input: `poetry--core--radio-group` targets input
- RULE: Use poetry_radio_group / form.radio_group - never hand-roll role=radio buttons.
- RULE: Every item MUST have a unique value: (ArgumentError on duplicates).
- RULE: The GROUP must be labelled - label: (or aria-labelledby) - an unlabelled radiogroup is an APG violation (ArgumentError).
- RULE: Pair every item with a visible label (item label: renders the Label for= pairing) - a bare dot is not an option.
- RULE: variant: :card renders the choice-card row (title + description: inside a selectable bordered label) - the pick-a-plan pattern; the whole card toggles the radio.
- RULE: NEVER write the checked attributes (data-checked/data-unchecked) without aria-checked (the controller writes both; agents patching DOM must too).
- RULE: Do not use RadioGroup for navigation or immediate actions; checking must not submit or navigate by itself.
- RULE: 7+ options: use Select instead.
- RULE: Wire errors through Field/FormBuilder (invalid: + describedby on the root) - never a bare red ring.
