diff --git a/src/event/behavior/keydown.ts b/src/event/behavior/keydown.ts index 6927deef..1305ca0c 100644 --- a/src/event/behavior/keydown.ts +++ b/src/event/behavior/keydown.ts @@ -28,7 +28,7 @@ const keydownBehavior: { ArrowDown: (event, target, instance) => { /* istanbul ignore else */ if (isElementType(target, 'input', {type: 'radio'} as const)) { - return () => walkRadio(instance, target, -1) + return () => walkRadio(instance, target, 1) } }, ArrowLeft: (event, target, instance) => { @@ -46,7 +46,7 @@ const keydownBehavior: { ArrowUp: (event, target, instance) => { /* istanbul ignore else */ if (isElementType(target, 'input', {type: 'radio'} as const)) { - return () => walkRadio(instance, target, 1) + return () => walkRadio(instance, target, -1) } }, Backspace: (event, target, instance) => { diff --git a/src/event/radio.ts b/src/event/radio.ts index 9c31098a..8d3fa284 100644 --- a/src/event/radio.ts +++ b/src/event/radio.ts @@ -15,18 +15,26 @@ export function walkRadio( : `input[type="radio"][name=""], input[type="radio"]:not([name])`, ), ) - for (let i = group.findIndex(e => e === el) + direction; ; i += direction) { - if (!group[i]) { - i = direction > 0 ? 0 : group.length - 1 - } - if (group[i] === el) { - return + + let indexOfRadiogroup = group.findIndex(e => e === el) + do { + // move to the next element + indexOfRadiogroup += direction + if (!group[indexOfRadiogroup]) { + indexOfRadiogroup = direction > 0 ? 0 : group.length - 1 } - if (isDisabled(group[i])) { + const element = group[indexOfRadiogroup] + + if (isDisabled(element)) { continue } - focusElement(group[i]) - instance.dispatchUIEvent(group[i], 'click') - } + if (element === el) { + // If there is only one available radiobutton element, do nothing + } else { + focusElement(element) + instance.dispatchUIEvent(element, 'click') + } + break + } while (true) } diff --git a/tests/event/behavior/keydown.ts b/tests/event/behavior/keydown.ts index 42feb6c0..deb5f6a6 100644 --- a/tests/event/behavior/keydown.ts +++ b/tests/event/behavior/keydown.ts @@ -317,6 +317,8 @@ cases( + + `, @@ -360,14 +362,14 @@ cases( expectedTarget: '//input[@value="a"]', }, 'forward around the corner': { - focus: '//input[@value="d"]', + focus: '//input[@value="f"]', key: 'ArrowRight', expectedTarget: '//input[@value="a"]', }, 'backward around the corner': { focus: '//input[@value="a"]', key: 'ArrowUp', - expectedTarget: '//input[@value="d"]', + expectedTarget: '//input[@value="f"]', }, 'do nothing on single radio': { focus: '//input[@name="solo"]',