Description
When value doesn't match an enabled item — initial '' state, a stale server value, or the selected item disabled — no radio has tabIndex=0, so useListFocus.syncTabStops promotes the first enabled item to the tab stop. handleContainerFocus then applies selection-follows-focus and fires onChange(firstValue).
Net effect: a keyboard user mutates the form value just by tabbing past the control (verified by execution: focus a button before the control, press Tab once → onChange('grid')). Shift-Tab backwards over it does the same. Native radio groups never check a radio on Tab-in.
The code comment assumes "an initial Tab-in … is a no-op" because focus lands on the already-selected radio — which is false exactly when value is unmatched or the selected item is disabled.
Suggested fix
In handleContainerFocus, skip selection when focus is entering the group from outside:
if (!e.currentTarget.contains(e.relatedTarget as Node)) return;
Arrow/Home/End navigation still selects (focus moves within the group, so relatedTarget is inside — APG selection-follows-focus preserved), and clicks are unaffected (SegmentedControlItem.handleClick selects independently). Happy to send the PR.
Astryx Version
main (73bcac9)
Description
When
valuedoesn't match an enabled item — initial''state, a stale server value, or the selected item disabled — no radio hastabIndex=0, souseListFocus.syncTabStopspromotes the first enabled item to the tab stop.handleContainerFocusthen applies selection-follows-focus and firesonChange(firstValue).Net effect: a keyboard user mutates the form value just by tabbing past the control (verified by execution: focus a button before the control, press Tab once →
onChange('grid')). Shift-Tab backwards over it does the same. Native radio groups never check a radio on Tab-in.The code comment assumes "an initial Tab-in … is a no-op" because focus lands on the already-selected radio — which is false exactly when
valueis unmatched or the selected item is disabled.Suggested fix
In
handleContainerFocus, skip selection when focus is entering the group from outside:Arrow/Home/End navigation still selects (focus moves within the group, so
relatedTargetis inside — APG selection-follows-focus preserved), and clicks are unaffected (SegmentedControlItem.handleClickselects independently). Happy to send the PR.Astryx Version
main (73bcac9)