<PageCard>

# FloatingList

Provides the ability to create composable children APIs for list
components

```js
import {FloatingList, useListItem} from '@floating-ui/react';
```

This is useful to prevent the need to keep track of a list item's
index for [`useListNavigation`](/docs/useListNavigation) or
[`useTypeahead`](/docs/useTypeahead).

<ShowFor packages={['react-dom']}>

<PackageLimited>@floating-ui/react only</PackageLimited>

</ShowFor>

</PageCard>

Manually specifying an index poses problems when wrapper tags
surround list items, such as with grouping.

An example of a composable children API looks like the following,
where `<Select>{:jsx}` does not receive an array prop but rather
children:

```js
<Select>
  <OptionGroup label="Fruits">
    <Option>Apple</Option>
    <Option>Strawberry</Option>
    <Option>Banana</Option>
  </OptionGroup>
  <OptionGroup label="Vegetables">
    <Option>Carrot</Option>
    <Option>Green Peas</Option>
    <Option>Cauliflower</Option>
  </OptionGroup>
</Select>
```

## Examples

- [Select with Composable Children](https://codesandbox.io/s/floating-ui-react-select-with-composable-children-qsuw76?file=/src/App.tsx)

## Usage

### `FloatingList{:.class}`

This component is a context provider that receives two props:

- <WordHighlight id="a">elementsRef</WordHighlight> — `useListNavigation(){:js}`'s `listRef{:.key}` prop (array of elements).
- <WordHighlight id="b">labelsRef</WordHighlight> — `useTypeahead(){:js}`'s `listRef{:.key}` prop (array of strings; **optional**).

```js /elementsRef/1,2,4#a /labelsRef/1,2,4#b
const elementsRef = useRef([]);
const labelsRef = useRef([]);

const listNav = useListNavigation(context, {
  listRef: elementsRef,
});
const typeahead = useTypeahead(context, {
  listRef: labelsRef,
});

return (
  <FloatingList elementsRef={elementsRef} labelsRef={labelsRef}>
    {/* floating element with list item children */}
  </FloatingList>
);
```

### `useListItem(){:js}`

This Hook is used to register a list item and its index (DOM
position) in the `FloatingList`. It returns two properties:

<WordHighlight id="a">ref</WordHighlight> and
<WordHighlight id="b">index</WordHighlight>.

```js {3} /ref/1,3#a /index/#b
function Option() {
  const {activeIndex} = useSelectContext();
  const {ref, index} = useListItem();

  const isActive = activeIndex === index;

  return <div ref={ref} tabIndex={isActive ? 0 : -1} />;
}
```

The Hook optionally accepts a `label` prop, which is used to
determine the string that can be matched with typeahead:

```js /label/
function Option({label}) {
  const {activeIndex} = useSelectContext();
  const {ref, index} = useListItem({
    label,
  });

  // ...
}
```

The `label` can be `null{:js}` for disabled items, which will be
ignored for typeahead.
