Founding price: $35, then $99 after 23:59 UTC on 4 November, then $99
Get ProOne tab stop for a group of items with arrow-key, Home and End movement, wrapping and RTL support, for toolbars, tab lists, radio groups and grids you build yourself.
Derived from this item’s props table, because it declares no controls of its own. This item has no standalone playground, so changes update the code, the share link and the AI prompt.
Use it for a custom toolbar, segmented control, radio group, menu bar or tab list so that Tab enters the group once and arrow keys move inside it, as the WAI-ARIA Authoring Practices describe.
Do not use it with Radix, Base UI or React Aria components from this library; they already manage focus. It is not for virtual focus (aria-activedescendant).
import { useRovingTabindex } from "@/hooks/use-roving-tabindex"const { getItemProps, activeIndex } = useRovingTabindex({
count: 3,
orientation: "horizontal",
})
{
items.map((item, index) => (
<button key={item} {...getItemProps(index)}>
{item}
</button>
))
}useRovingTabindex(options): { activeIndex, setActiveIndex, getItemProps }
| Option | Type | Default | Description |
|---|---|---|---|
count | number | - | Number of items. |
orientation | "horizontal" | "vertical" | "both" | "horizontal" | Which arrow keys move. |
loop | boolean | true | Wrap from last to first and back. |
initialIndex | number | 0 | The item that is the tab stop first. |
dir | "ltr" | "rtl" | read from the document | Flips Left and Right in right-to-left layouts. |
isDisabled | (index: number) => boolean | - | Items to skip. |
getItemProps(index) returns ref, tabIndex (0 for the active item, -1 for the rest), onKeyDown and onFocus (which makes a clicked or tabbed-to item the active one). Home and End jump to the first and last item.
This is the focus model the WAI-ARIA Authoring Practices use for toolbars, tab lists, radio groups and menu bars. Give the container the right role (toolbar, tablist, radiogroup) and a label, and keep disabled items focusable only where the pattern says so.
The hook ships with renderHook tests (use-roving-tabindex.test.ts) covering its behaviour, cleanup on unmount and server-safe defaults. It is safe to render on the server.