<PageCard>

# React Native

This package provides React Native bindings for
`@floating-ui/core` — a library that provides anchor positioning
for a floating element to position it next to a given reference
element.

```bash
npm install @floating-ui/react-native
```

</PageCard>

## Usage

The `useFloating(){:js}` hook accepts all of
[`computePosition`'s options](/docs/computePosition#options)
excluding `strategy{:.key}`.

```jsx
import {View, Text} from 'react-native';
import {useFloating, shift} from '@floating-ui/react-native';

function App() {
  const {refs, floatingStyles} = useFloating({
    middleware: [shift()],
  });

  return (
    <View>
      <View ref={refs.setReference} collapsable={false}>
        <Text>Reference</Text>
      </View>
      <View
        ref={refs.setFloating}
        collapsable={false}
        style={floatingStyles}
      >
        <Text>Floating</Text>
      </View>
    </View>
  );
}
```

This will position the floating element at the **bottom center**
of the reference element by default.

Positioning is relative to the parent by default, see
[ScrollView](/docs/react-native#scrollview) or
[offsetParent](/docs/react-native#offsetparent) to adjust this.

- `refs.setReference{:js}` is the reference (or anchor) element
  that is being referred to for positioning.
- `refs.setFloating{:js}` is the floating element that is being
  positioned relative to the reference element.
- `floatingStyles{:js}` is an object of positioning styles to
  apply to the floating element's `style{:.keyword}` prop.

The refs are functions to make them **reactive** — this ensures
changes to the reference or floating elements, such as with
conditional rendering, are handled correctly by updating the
position.

<Notice gap="above">
  `<View collapsable={false} />{:js}` allows measurements to work
  on Android. [More info here](https://github.com/facebook/react-native/issues/29712).
</Notice>

## ScrollView

When your floating element is portaled to the app root, while the
reference element is inside a `<ScrollView />{:jsx}`, pass the
`sameScrollView{:.key}` option, and spread `scrollProps{:.const}`
to the component:

```jsx /scrollProps/ {6}
import {View, Text, ScrollView} from 'react-native';
import {useFloating} from '@floating-ui/react-native';

function App() {
  const {refs, floatingStyles, scrollProps} = useFloating({
    sameScrollView: false,
  });

  return (
    <View>
      <ScrollView {...scrollProps}>
        <View ref={refs.setReference} collapsable={false}>
          <Text>Reference</Text>
        </View>
      </ScrollView>

      <View
        ref={refs.setFloating}
        collapsable={false}
        style={floatingStyles}
      >
        <Text>Floating</Text>
      </View>
    </View>
  );
}
```

## Anchoring

`useFloating(){:js}` only calculates the position **once** on
render, or when the reference/floating elements changed.
Depending on the context in which the floating element lives, you
may need to update its position in an Effect.

The Hook returns an `update(){:js}` function to update the
position at will:

```js
const {update} = useFloating();
```

## Refs

To access the elements, you can either access the refs:

```js
const {refs} = useFloating();

// Inside an Effect or event handler:
refs.reference.current;
refs.floating.current;
```

Or the elements directly:

```js
const {elements} = useFloating();

// During render, unlike the refs:
elements.reference;
elements.floating;
```

External elements can be synchronized like so, if they live
outside the component:

```js
function MyComponent({referenceEl, floatingEl}) {
  const {refs} = useFloating({
    elements: {
      reference: referenceEl,
      floating: floatingEl,
    },
  });
}
```

## Arrow

A plain `ref{:.const}` can be passed as the `element{:.key}`
value:

```jsx /arrowRef/1-2 {11}
import {useRef} from 'react';
import {useFloating, arrow} from '@floating-ui/react-native';

function App() {
  const arrowRef = useRef();
  const {
    refs,
    floatingStyles,
    middlewareData: {arrow: {x: arrowX, y: arrowY} = {}},
  } = useFloating({
    middleware: [arrow({element: arrowRef})],
  });

  // Pass the `arrowRef` to the element
}
```

## offsetParent

Pass this to the floating element's `offsetParent`, if required
for positioning:

```jsx /offsetParent/
import {View, Text, ScrollView} from 'react-native';
import {useFloating} from '@floating-ui/react-native';

function App() {
  const {refs, floatingStyles} = useFloating({
    sameScrollView: false,
  });

  return (
    <View>
      <ScrollView>
        <View ref={refs.setReference} collapsable={false}>
          <Text>Reference</Text>
        </View>
      </ScrollView>

      <View ref={refs.setOffsetParent} collapsable={false}>
        <View
          ref={refs.setFloating}
          collapsable={false}
          style={floatingStyles}
        >
          <Text>Floating</Text>
        </View>
      </View>
    </View>
  );
}
```
