Skip to content

Commit

Permalink
Accept tabIndex on <RadioGroup> component (#3646)
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
RobinMalfait authored Feb 21, 2025
1 parent 466bb07 commit 20f46dd
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 11 deletions.
11 changes: 6 additions & 5 deletions packages/@headlessui-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Accept `tabIndex` on the `Checkbox` component ([#3645](https://github.com/tailwindlabs/headlessui/pull/3645))
- Accept `tabIndex` on the `RadioGroup` component ([#3646](https://github.com/tailwindlabs/headlessui/pull/3646))

### Fixed

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

### Added

- Accept `tabIndex` on `Checkbox` component ([#3645](https://github.com/tailwindlabs/headlessui/pull/3645))

## [2.2.0] - 2024-10-25

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ let RadioGroupDataContext = createContext<
containsCheckedOption: boolean
disabled: boolean
compare(a: unknown, z: unknown): boolean
tabIndex: number
} & StateDefinition)
| null
>(null)
Expand Down Expand Up @@ -178,6 +179,7 @@ function RadioGroupFn<TTag extends ElementType = typeof DEFAULT_RADIO_GROUP_TAG,
by,
disabled = providedDisabled || false,
defaultValue: _defaultValue,
tabIndex = 0,
...theirProps
} = props
let compare = useByComparator(by)
Expand Down Expand Up @@ -285,8 +287,8 @@ function RadioGroupFn<TTag extends ElementType = typeof DEFAULT_RADIO_GROUP_TAG,
})

let radioGroupData = useMemo<_Data>(
() => ({ value, firstOption, containsCheckedOption, disabled, compare, ...state }),
[value, firstOption, containsCheckedOption, disabled, compare, state]
() => ({ value, firstOption, containsCheckedOption, disabled, compare, tabIndex, ...state }),
[value, firstOption, containsCheckedOption, disabled, compare, tabIndex, state]
)
let radioGroupActions = useMemo<_Actions>(
() => ({ registerOption, change: triggerChange }),
Expand Down Expand Up @@ -424,8 +426,8 @@ function OptionFn<
'aria-disabled': disabled ? true : undefined,
tabIndex: (() => {
if (disabled) return -1
if (checked) return 0
if (!data.containsCheckedOption && isFirstOption) return 0
if (checked) return data.tabIndex
if (!data.containsCheckedOption && isFirstOption) return data.tabIndex
return -1
})(),
onClick: disabled ? undefined : handleClick,
Expand Down Expand Up @@ -547,8 +549,8 @@ function RadioFn<
'aria-disabled': disabled ? true : undefined,
tabIndex: (() => {
if (disabled) return -1
if (checked) return 0
if (!data.containsCheckedOption && isFirstOption) return 0
if (checked) return data.tabIndex
if (!data.containsCheckedOption && isFirstOption) return data.tabIndex
return -1
})(),
autoFocus,
Expand Down

0 comments on commit 20f46dd

Please sign in to comment.