- Easy to use API
- Vertical and horizontal navigation
- Radix-UI like
asChildprop - 100% TypeScript
A roving focus improves the accessbility of your application. It allows users to navigate between items using Arrow keys.
Let's say you have a list of 10 items and then a button. Without a roving focus, the user needs to press the Tab key 10 times to focus the button.
With a roving focus, the user only needs press the Tab key twice. On the first press they focus the first item, on the second press they focus the button. Now, if the user want to focus the third item in the list, they first need to focus the first item and then can press the right arrow key twice.
Hey, I'm Nils. In my spare time I write about things I learned or I create open source packages, that help me (and hopefully you) to build better apps.
You can install this package with any package manager you like.
pnpm add @roving-focus/reactYou need two components:
RovingFocusGroupRovingFocusItem
<RovingFocusGroup>
<RovingFocusItem>Item 1</RovingFocusItem>
<RovingFocusItem>Item 2</RovingFocusItem>
<RovingFocusItem>Item 3</RovingFocusItem>
</RovingFocusGroup><RovingFocusGroup orientation="vertical">
<RovingFocusItem>Item 1</RovingFocusItem>
<RovingFocusItem>Item 2</RovingFocusItem>
<RovingFocusItem>Item 3</RovingFocusItem>
</RovingFocusGroup>Press ArrowUp or ArrowDown to navigate between items.
<RovingFocusGroup orientation="horizontal">
<RovingFocusItem>Item 1</RovingFocusItem>
<RovingFocusItem>Item 2</RovingFocusItem>
<RovingFocusItem>Item 3</RovingFocusItem>
</RovingFocusGroup>Press ArrowLeft or ArrowRight to navigate between items.
To make any item unfocusable, set the focusable prop to false.
<RovingFocusGroup>
<RovingFocusItem focusable={false}>Item 1</RovingFocusItem>
<RovingFocusItem>Item 2</RovingFocusItem>
<RovingFocusItem>Item 3</RovingFocusItem>
</RovingFocusGroup>Now you can only focus item 2 and 3.
By default the first item is focused. To change this, set the active prop to true on the item you want to be focused by default.
<RovingFocusGroup>
<RovingFocusItem>Item 1</RovingFocusItem>
<RovingFocusItem active>Item 2</RovingFocusItem>
</RovingFocusGroup>When looping is enabled and the user focuses the last item, if they then focus the next item, they will actually focus the first item. The same is true for the first item, it then focuses the last item.
By default looping is enabled. To disable it, set the loop prop to false.
<RovingFocusGroup loop={false}>
<RovingFocusItem>Item 1</RovingFocusItem>
<RovingFocusItem>Item 2</RovingFocusItem>
<RovingFocusItem>Item 3</RovingFocusItem>
</RovingFocusGroup>Props:
orientation:"vertical" | "horizontal"- The orientation of the group.loop:boolean- Whether the group should loop when the end or start of the group is reached.asChild:boolean- Uses the child element as the root element.as:React.ElementType- Allows you to pass a custom element as the root element.
Data attributes:
data-orientation:"vertical" | "horizontal"- The orientation of the group.
Props:
focusable:booleanactive:booleanasChild:boolean- Uses the child element as the root element.as:React.ElementType- Allows you to pass a custom element as the root element.
Data attributes:
data-active:"true"- The item is the active item.data-disabled:"true"- The item is unfocusable.
I highly appreceate your feedback! Please create an issue, if you've found any bugs or want to request a feature.