Skip to content

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.

Install

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

Usage

The useFloating()useFloating() hook accepts all of computePosition’s options excluding strategystrategy.

import {View, Text} from 'react-native';
import {useFloating, shift} from '@floating-ui/react-native';
 
function App() {
  const {x, y, refs} = useFloating({
    middleware: [shift()],
  });
 
  return (
    <View>
      <View ref={refs.setReference} collapsable={false}>
        <Text>Reference</Text>
      </View>
      <View
        ref={refs.setFloating}
        collapsable={false}
        style={{
          position: 'absolute',
          top: y ?? 0,
          left: x ?? 0,
        }}
      >
        <Text>Floating</Text>
      </View>
    </View>
  );
}
import {View, Text} from 'react-native';
import {useFloating, shift} from '@floating-ui/react-native';
 
function App() {
  const {x, y, refs} = useFloating({
    middleware: [shift()],
  });
 
  return (
    <View>
      <View ref={refs.setReference} collapsable={false}>
        <Text>Reference</Text>
      </View>
      <View
        ref={refs.setFloating}
        collapsable={false}
        style={{
          position: 'absolute',
          top: y ?? 0,
          left: x ?? 0,
        }}
      >
        <Text>Floating</Text>
      </View>
    </View>
  );
}

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

  • xx and yy are the positioning coordinates. These values are nullnull initially, before the layout effect has fired.
  • refs.setReferencerefs.setReference and refs.setFloatingrefs.setFloating are function refs that get called with the elements and update the position when they change (such as with conditional rendering), unlike with plain refs.

Updating

useFloating()useFloating() 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()update() function to update the position:

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

Refs

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

const {refs} = useFloating();
 
// Inside an effect or event handler:
refs.reference.current;
refs.floating.current;
const {refs} = useFloating();
 
// Inside an effect or event handler:
refs.reference.current;
refs.floating.current;

Or the elements directly:

const {elements} = useFloating();
 
// During render, unlike the refs:
elements.reference;
elements.floating;
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:

function MyComponent({referenceEl, floatingEl}) {
  const {refs} = useFloating();
 
  useLayoutEffect(() => {
    refs.setReference(referenceEl);
    refs.setFloating(floatingEl);
  }, [refs, referenceEl, floatingEl]);
}
function MyComponent({referenceEl, floatingEl}) {
  const {refs} = useFloating();
 
  useLayoutEffect(() => {
    refs.setReference(referenceEl);
    refs.setFloating(floatingEl);
  }, [refs, referenceEl, floatingEl]);
}

ScrollView

When your floating element is portaled to the app root, while the reference element is inside a <ScrollView /><ScrollView />, you pass the sameScrollViewsameScrollView option, and spread scrollPropsscrollProps to the component:

import {View, Text, ScrollView} from 'react-native';
import {useFloating} from '@floating-ui/react-native';
 
function App() {
  const {x, y, refs, 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={{
          position: 'absolute',
          top: y ?? 0,
          left: x ?? 0,
        }}
      >
        <Text>Floating</Text>
      </View>
    </View>
  );
}
import {View, Text, ScrollView} from 'react-native';
import {useFloating} from '@floating-ui/react-native';
 
function App() {
  const {x, y, refs, 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={{
          position: 'absolute',
          top: y ?? 0,
          left: x ?? 0,
        }}
      >
        <Text>Floating</Text>
      </View>
    </View>
  );
}

offsetParent

Pass this to the floating element’s `offsetParent“, if required:

import {View, Text, ScrollView} from 'react-native';
import {useFloating} from '@floating-ui/react-native';
 
function App() {
  const {x, y, refs} = 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={{
            position: 'absolute',
            top: y ?? 0,
            left: x ?? 0,
          }}
        >
          <Text>Floating</Text>
        </View>
      </View>
    </View>
  );
}
import {View, Text, ScrollView} from 'react-native';
import {useFloating} from '@floating-ui/react-native';
 
function App() {
  const {x, y, refs} = 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={{
            position: 'absolute',
            top: y ?? 0,
            left: x ?? 0,
          }}
        >
          <Text>Floating</Text>
        </View>
      </View>
    </View>
  );
}

Arrow

A refref can be passed as the elementelement:

import {useRef} from 'react';
import {useFloating, arrow} from '@floating-ui/react-native';
 
function App() {
  const arrowRef = useRef();
  const {
    x,
    y,
    middlewareData: {arrow: {x: arrowX, y: arrowY} = {}},
  } = useFloating({
    middleware: [arrow({element: arrowRef})],
  });
 
  // Pass the `arrowRef` to the element
}
import {useRef} from 'react';
import {useFloating, arrow} from '@floating-ui/react-native';
 
function App() {
  const arrowRef = useRef();
  const {
    x,
    y,
    middlewareData: {arrow: {x: arrowX, y: arrowY} = {}},
  } = useFloating({
    middleware: [arrow({element: arrowRef})],
  });
 
  // Pass the `arrowRef` to the element
}