diff --git a/packages/ui/src/radio.js b/packages/ui/src/radio.js
index 2fe20a47f..f01280865 100644
--- a/packages/ui/src/radio.js
+++ b/packages/ui/src/radio.js
@@ -106,8 +106,8 @@ function handleRoot(el, Alpine) {
__focusOptionNext() {
let option = this.__active
let all = this.__optionValues.filter(i => !this.__disabledOptions.has(i))
- let next = all[this.__optionValues.indexOf(option) + 1]
- next = next || all[0]
+ let index = all.indexOf(option)
+ let next = all[(index + 1 + all.length) % all.length]
this.__optionElsByValue.get(next).focus()
this.__change(next)
@@ -115,8 +115,8 @@ function handleRoot(el, Alpine) {
__focusOptionPrev() {
let option = this.__active
let all = this.__optionValues.filter(i => !this.__disabledOptions.has(i))
- let prev = all[all.indexOf(option) - 1]
- prev = prev || all.slice(-1)[0]
+ let index = all.indexOf(option)
+ let prev = all[(index - 1 + all.length) % all.length]
this.__optionElsByValue.get(prev).focus()
this.__change(prev)
diff --git a/tests/cypress/integration/plugins/ui/radio.spec.js b/tests/cypress/integration/plugins/ui/radio.spec.js
index 7106ee610..138eeb1e0 100644
--- a/tests/cypress/integration/plugins/ui/radio.spec.js
+++ b/tests/cypress/integration/plugins/ui/radio.spec.js
@@ -253,6 +253,49 @@ test('keyboard navigation works',
},
)
+test('keyboard navigation works when first option has null as value',
+ [html`
+
+
+
+
+
+ `],
+ ({ get }) => {
+ get('[option="option-1"]').focus().type('{downarrow}')
+ get('[option="option-2"]').should(haveFocus()).type('{uparrow}')
+ get('[option="option-1"]').should(haveFocus()).type('{uparrow}')
+ get('[option="option-null"]').should(haveFocus()).type('{uparrow}')
+ get('[option="option-2"]').should(haveFocus()).type('{downarrow}')
+ get('[option="option-null"]').should(haveFocus())
+ },
+)
+
+test('keyboard navigation works when last option has null as value',
+ [html`
+
+
+
+
+
+ `],
+ ({ get }) => {
+ get('[option="option-1"]').focus().type('{downarrow}')
+ get('[option="option-2"]').should(haveFocus()).type('{downarrow}')
+ get('[option="option-null"]').should(haveFocus()).type('{downarrow}')
+ get('[option="option-1"]').should(haveFocus()).type('{uparrow}')
+ get('[option="option-null"]').should(haveFocus())
+ },
+)
+
test('has accessibility attributes',
[html`