Skip to main content
RovingFocusGroup provides a robust implementation of the roving tabindex pattern, allowing users to navigate through a group of focusable items using arrow keys while maintaining a single tab stop.

Installation

Components

RovingFocusGroup

The root component that manages focus state for all items within the group.

RovingFocusGroupItem

Represents a focusable item within the group.

Props

RovingFocusGroup

'horizontal' | 'vertical' | 'both'
The orientation of the group, which determines which arrow keys navigate between items:
  • horizontal: Left/Right arrows
  • vertical: Up/Down arrows
  • both: All arrow keys
'ltr' | 'rtl'
The reading direction. Affects horizontal keyboard navigation.
boolean
Whether keyboard navigation should wrap around when reaching the first or last item.Default: false
string | null
The controlled tab stop id. Use with onCurrentTabStopIdChange for controlled mode.
string
The default tab stop id for uncontrolled mode.
(tabStopId: string | null) => void
Callback fired when the current tab stop changes.
(event: Event) => void
Event handler called when focus enters the group. Can be prevented.
boolean
Whether to prevent scrolling when focus enters the group.Default: false

Usage

Basic Example - Horizontal Navigation

Vertical List with Looping

Controlled Focus State

Grid Navigation (2D)

With Disabled Items

RTL Support

Keyboard Interactions

Moves focus to the current tab stop (or first item if none is set).
vertical orientation
Moves focus to the next item.
vertical orientation
Moves focus to the previous item.
horizontal orientation
Moves focus to the next item (in LTR) or previous item (in RTL).
horizontal orientation
Moves focus to the previous item (in LTR) or next item (in RTL).
Moves focus to the first item.
Moves focus to the last item.

Accessibility

The roving tabindex pattern:
  • Maintains only one tab stop in the group
  • Uses arrow keys for navigation within the group
  • Follows WAI-ARIA best practices
  • Supports RTL languages
  • Respects disabled/non-focusable items

Notes

Only one item in the group has tabIndex={0} at a time. All other items have tabIndex={-1}. This ensures a single tab stop while allowing full keyboard navigation with arrow keys.
The component automatically handles focus management, including updating tab indices, focusing items, and managing keyboard navigation based on orientation and direction.
Items marked with focusable={false} are skipped during keyboard navigation but remain in the DOM.