Skip to content

fix: ask_user panel commits the answer on radio selection, making later options unreachable by keyboard #223

Description

@ThalynLabs

What happens

In the plan-mode ask_user question panel, selecting a radio option immediately submits the answer. The panel's own submit control is not what commits it — activating an option is.

This makes the options unreviewable for anyone using a keyboard or a screen reader.

Radio groups implement selection follows focus — per the ARIA Authoring Practices radio group pattern (and native HTML radio behaviour), arrow keys move focus and check the option landed on. Combined with submit-on-select, that means:

  • Pressing the first arrow key submits the answer.
  • Options after the first are effectively unreachable without committing to them.
  • The option description text — the most useful part of the panel — is never heard, because the turn has already resumed.

I use VoiceOver on macOS. In practice I cannot browse the choices at all; I can only take whichever option focus lands on first.

Why this is a conformance problem, not just friction

WCAG 2.2 SC 3.2.2 On Input (Level A) — "Changing the setting of any user interface component does not automatically cause a change of context unless the user has been advised of the behavior before using the component." Checking a radio is a setting change; submitting the answer and resuming the agent turn is a change of context. No advisory precedes it.

It also undermines SC 2.1.1 Keyboard (Level A) in effect: the functionality of choosing among options 2..n is not operable via keyboard without irreversibly selecting the options passed through on the way.

Worth noting the radio behaviour on its own is correct and specified — the defect is the coupling of selection to submission.

Suggested fix

Either would resolve it:

  1. Decouple selection from submission. Radios set the pending answer; the existing submit control commits it. Smallest change, keeps native radio semantics and the current markup.
  2. Use the listbox pattern (role="listbox" / role="option", roving tabindex or aria-activedescendant), where selection does not follow focus and Enter/Space commits. The APG recommends this specifically when a user needs to review options before choosing.

Option 1 is likely a few lines and preserves everything else about the component.

Environment

  • cptr 0.9.21
  • macOS, VoiceOver
  • Panel markup renders as <label><input class="sr-only" type="radio"> …</label> — the visually-hidden-radio pattern itself is fine; the change handler is where the submit happens.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions