use List Navigation
Adds arrow key-based navigation of a list of items, either using real DOM focus or virtual focus.
This is useful for creating floating elements that contain a list of items (such as a menu, select, or combobox) to ensure that keyboard usage can navigate the list.
- See
FloatingList
for creating composable children API components. - See
Composite
for list navigation outside of floating element contexts.
Usage
This Hook returns event handler props and ARIA attribute props.
To use it, pass it the context
object returned from
useFloating()
, and then feed its result into the
useInteractions()
array. The returned prop getters are
then spread onto the elements for rendering.
getItemProps()
is spread to each list item.
The listRef
holds an array of HTML elements. The
activeIndex
determines which index of the list is
currently active (focused or highlighted).
When using real DOM focus (default), the list items must be
focusable and should have an appropriate role
prop
based on the role of the floating element.
Examples
Using with FloatingFocusManager
useListNavigation()
and <FloatingFocusManager>
both
manage focus but in different ways. To ensure they work together
properly, the initial point of focus needs to be considered.
The focus manager by default focuses the first tabbable (not focusable) element inside of the floating element. If none are, it falls back to the floating element itself. This allows keydown events to work for pointer input (e.g. open with mouse, then start navigating with arrow keys).
- For a combobox, where the input should keep focus, set it
to
-1
so focus doesn’t move at all:
- For other types of components, like a menu or a
select, where you want focus to move inside the floating
element, the default value works, but make sure your list
items aren’t tabbable if the
activeIndex
isnull
.
A roving tabIndex is the recommended strategy:
Props
listRef
default: empty list
A ref that holds an array of list items. You can assign each item in the array by its index like so:
activeIndex
default: null
The currently active (i.e. highlighted or focused) item index, which may or may not be selected.
onNavigate
default: no-op
Callback invoked when the user navigates, passed in the current
activeIndex
.
enabled
default: true
Conditionally enable/disable the Hook.
selectedIndex
default: null
The currently selected item index, which may or may not be active.
This is the item shown in the trigger button/input.
loop
default: false
Determines whether focus should loop around when navigating past the first or last item.
nested
default: false
If the list is nested within another one (e.g. a nested submenu), the navigation semantics change.
rtl
default: false
Whether the direction of the floating element’s navigation is in RTL layout.
virtual
default: false
Whether the focus is virtual (using
aria-activedescendant
).
Use this if you need focus to remain on the reference element (such as an input), but allow arrow keys to navigate list items. This is common in autocomplete listbox components.
virtualItemRef
default: undefined
When using virtual focus management, this holds a ref to the virtually-focused item.
This allows nested virtual navigation to be enabled, and lets you know when a nested element is virtually focused from the root reference handling the events.
allowEscape
Determines whether focus can escape the list, such that nothing is selected after navigating beyond the boundary of the list. In some autocomplete/combobox components, this may be desired, as screen readers will return to the input.
orientation
default: 'vertical'
The orientation in which navigation occurs.
cols
default: 1
Specifies how many columns the list has (i.e., it’s a grid).
Use an orientation of 'horizontal'
(e.g. for an emoji
picker/date picker, where pressing ArrowRight or ArrowLeft can
change rows), or 'both'
(where the current row cannot be
escaped with ArrowRight or ArrowLeft, only ArrowUp and
ArrowDown).
focusItemOnOpen
default: 'auto'
Whether to focus the item upon opening the floating element.
'auto'
infers what to do based on the input type (keyboard
vs. pointer), while a boolean value will force the value.
focusItemOnHover
default: true
Whether hovering an item synchronizes the focus.
openOnArrowKeyDown
default: true
Whether pressing an arrow key on the navigation’s main axis opens the floating element.
disabledIndices
default: undefined
By default elements with either a disabled
or
aria-disabled
attribute are skipped in the list
navigation — however, this requires the items to be rendered.
This prop allows you to manually specify indices which should be disabled, overriding the default logic.
For Windows-style select menus, where the menu does not open when navigating via arrow keys, specify an empty array.
scrollItemIntoView
default: true
| ScrollIntoViewOptions
Whether to scroll the active item into view when navigating. The
default value uses nearest
options.
itemSizes
default: undefined
Only for grid navigation, an array of Dimensions
objects, which
specify the width (number of columns) and height (number of rows)
of each item, so the navigation algorithm can take the variable
sizes into account. If not specified, every item will be treated
as if it has a size of 1 row and 1 column.
dense
default: false
Only for grid navigation, determines if the grid positioning
algorithm should follow CSS Grid’s auto-flow
dense
algorithm.