Skip to main content

Roving Focus

Arrow key navigation within a group of focusable items.

import * as RovingFocusGroup from '@gentleduck/primitives/roving-focus'
import * as RovingFocusGroup from '@gentleduck/primitives/roving-focus'

Usage

<RovingFocusGroup.Root orientation="horizontal" loop>
  <RovingFocusGroup.Item asChild>
    <button>Item 1</button>
  </RovingFocusGroup.Item>
  <RovingFocusGroup.Item asChild>
    <button>Item 2</button>
  </RovingFocusGroup.Item>
  <RovingFocusGroup.Item asChild>
    <button>Item 3</button>
  </RovingFocusGroup.Item>
</RovingFocusGroup.Root>
<RovingFocusGroup.Root orientation="horizontal" loop>
  <RovingFocusGroup.Item asChild>
    <button>Item 1</button>
  </RovingFocusGroup.Item>
  <RovingFocusGroup.Item asChild>
    <button>Item 2</button>
  </RovingFocusGroup.Item>
  <RovingFocusGroup.Item asChild>
    <button>Item 3</button>
  </RovingFocusGroup.Item>
</RovingFocusGroup.Root>

Props (Root)

PropTypeDefaultDescription
orientation'horizontal' | 'vertical'-Arrow key direction
dir'ltr' | 'rtl'-Text direction. Resolved with useDirection (dir prop -> DirectionProvider -> 'ltr').
loopbooleanfalseWrap at boundaries
currentTabStopIdstring | null-Controlled active tab stop ID
defaultCurrentTabStopIdstring-Initial active tab stop ID (uncontrolled)
onCurrentTabStopIdChange(tabStopId: string | null) => void-Called when the active tab stop changes
onEntryFocus(event: Event) => void-Called when focus enters the group. Call event.preventDefault() to prevent auto-focus.
preventScrollOnEntryFocusbooleanfalsePrevent scroll when focus enters the group

How it works