Skip to content

Commit 20f46dd

Browse files
authored
Accept tabIndex on <RadioGroup> component (#3646)
This PR allows you to pass a `tabIndex` to the `<RadioGroup>` component and it will internally pass it down to the correct `<Radio />` or `<RadioGroupOption>` component. The reason we do it this way is because only a single radio should be focusable (moving between radios can be done via the arrow keys instead of the tab key).
1 parent 466bb07 commit 20f46dd

File tree

2 files changed

+14
-11
lines changed

2 files changed

+14
-11
lines changed

packages/@headlessui-react/CHANGELOG.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Accept `tabIndex` on the `Checkbox` component ([#3645](https://github.com/tailwindlabs/headlessui/pull/3645))
13+
- Accept `tabIndex` on the `RadioGroup` component ([#3646](https://github.com/tailwindlabs/headlessui/pull/3646))
14+
1015
### Fixed
1116

12-
- Use correct `ownerDocument` when using internal `<Portal/>` element ([#3594](https://github.com/tailwindlabs/headlessui/pull/3594))
17+
- Use correct `ownerDocument` when using internal `Portal` component ([#3594](https://github.com/tailwindlabs/headlessui/pull/3594))
1318
- Bump `@tanstack/react-virtual` to be fix warnings in React 19 projects ([#3588](https://github.com/tailwindlabs/headlessui/pull/3588))
1419
- Fix `aria-invalid` attributes to have a valid `'true'` value ([#3639](https://github.com/tailwindlabs/headlessui/pull/3639))
1520

16-
### Added
17-
18-
- Accept `tabIndex` on `Checkbox` component ([#3645](https://github.com/tailwindlabs/headlessui/pull/3645))
19-
2021
## [2.2.0] - 2024-10-25
2122

2223
### Added

packages/@headlessui-react/src/components/radio-group/radio-group.tsx

+8-6
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ let RadioGroupDataContext = createContext<
100100
containsCheckedOption: boolean
101101
disabled: boolean
102102
compare(a: unknown, z: unknown): boolean
103+
tabIndex: number
103104
} & StateDefinition)
104105
| null
105106
>(null)
@@ -178,6 +179,7 @@ function RadioGroupFn<TTag extends ElementType = typeof DEFAULT_RADIO_GROUP_TAG,
178179
by,
179180
disabled = providedDisabled || false,
180181
defaultValue: _defaultValue,
182+
tabIndex = 0,
181183
...theirProps
182184
} = props
183185
let compare = useByComparator(by)
@@ -285,8 +287,8 @@ function RadioGroupFn<TTag extends ElementType = typeof DEFAULT_RADIO_GROUP_TAG,
285287
})
286288

287289
let radioGroupData = useMemo<_Data>(
288-
() => ({ value, firstOption, containsCheckedOption, disabled, compare, ...state }),
289-
[value, firstOption, containsCheckedOption, disabled, compare, state]
290+
() => ({ value, firstOption, containsCheckedOption, disabled, compare, tabIndex, ...state }),
291+
[value, firstOption, containsCheckedOption, disabled, compare, tabIndex, state]
290292
)
291293
let radioGroupActions = useMemo<_Actions>(
292294
() => ({ registerOption, change: triggerChange }),
@@ -424,8 +426,8 @@ function OptionFn<
424426
'aria-disabled': disabled ? true : undefined,
425427
tabIndex: (() => {
426428
if (disabled) return -1
427-
if (checked) return 0
428-
if (!data.containsCheckedOption && isFirstOption) return 0
429+
if (checked) return data.tabIndex
430+
if (!data.containsCheckedOption && isFirstOption) return data.tabIndex
429431
return -1
430432
})(),
431433
onClick: disabled ? undefined : handleClick,
@@ -547,8 +549,8 @@ function RadioFn<
547549
'aria-disabled': disabled ? true : undefined,
548550
tabIndex: (() => {
549551
if (disabled) return -1
550-
if (checked) return 0
551-
if (!data.containsCheckedOption && isFirstOption) return 0
552+
if (checked) return data.tabIndex
553+
if (!data.containsCheckedOption && isFirstOption) return data.tabIndex
552554
return -1
553555
})(),
554556
autoFocus,

0 commit comments

Comments
 (0)