Skip to content

FloatingArrow

Renders a customizable <svg> pointing arrow triangle inside the floating element that gets automatically positioned.

import {FloatingArrow} from '@floating-ui/react';

Usage

  • Create an arrowRef and pass it to the arrow middleware’s element option and the <FloatingArrow /> component. This lets the arrow be measured for positioning.
  • Pass the context to the <FloatingArrow /> component. This lets the component read the positioning data.
import {FloatingArrow, arrow} from '@floating-ui/react';
 
function App() {
  const arrowRef = useRef(null);
  const {refs, floatingStyles, context} = useFloating({
    middleware: [
      arrow({
        element: arrowRef,
      }),
    ],
  });
 
  return (
    <>
      <div ref={refs.setReference} />
      <div ref={refs.setFloating} style={floatingStyles}>
        <FloatingArrow ref={arrowRef} context={context} />
      </div>
    </>
  );
}

The arrow will, by default, overlap the reference element. The height of the arrow will offset it by the desired amount.

import {offset} from '@floating-ui/react';
 
const ARROW_HEIGHT = 7;
const GAP = 2;
 
useFloating({
  middleware: [offset(ARROW_HEIGHT + GAP)],
});

This does not take into account tip rounding or strokes.

Props

The arrow accepts all the props of an <svg> element, plus some additional props:

interface Props extends React.SVGAttributes<SVGSVGElement> {
  context: FloatingContext;
  width?: number;
  height?: number;
  tipRadius?: number;
  staticOffset?: number | string | null;
 
  // Inherited SVG props that are intercepted and passed
  // to the <path>s
  d?: string;
  fill?: string;
  stroke?: string;
  strokeWidth?: number;
}

ref

Required
<FloatingArrow ref={arrowRef} />

context

Required

The context object returned from useFloating().

const {context} = useFloating();
<FloatingArrow context={context} />;

width

default: 14

The width of the arrow.

<FloatingArrow ref={arrowRef} context={context} width={10} />

height

default: 7

The height of the arrow.

<FloatingArrow ref={arrowRef} context={context} height={10} />

tipRadius

default: 0 (sharp)

The radius (rounding) of the arrow tip.

<FloatingArrow ref={arrowRef} context={context} tipRadius={2} />

staticOffset

default: undefined (use dynamic position)

A static offset override of the arrow from the floating element edge. Often desirable if the floating element is smaller than the reference element along the relevant axis and has an edge alignment ('start'/'end').

<FloatingArrow
  ref={arrowRef}
  context={context}
  staticOffset={isEdgeAlignedAndSmaller ? '15%' : null}
/>

d

default: undefined (use dynamic path)

A custom path for the arrow. Useful if you want fancy rounding. The path should be inside a square SVG and placed at the bottom of it. The path is designed for the 'bottom' placement, which will be rotated for other placements.

<FloatingArrow
  ref={arrowRef}
  context={context}
  width={20}
  height={20}
  d="M0 20C0 20 2.06906 19.9829 5.91817 15.4092C7.49986 13.5236 8.97939 12.3809 10.0002 12.3809C11.0202 12.3809 12.481 13.6451 14.0814 15.5472C17.952 20.1437 20 20 20 20H0Z"
/>

fill

default: "black" (browser default)

The color of the arrow.

<FloatingArrow ref={arrowRef} context={context} fill="red" />

stroke

default: "none"

The stroke (border) color of the arrow. This must match (or be less than) the floating element’s border width.

<FloatingArrow ref={arrowRef} context={context} stroke="red" />

strokeWidth

default: 0

The stroke (border) width of the arrow.

<FloatingArrow
  ref={arrowRef}
  context={context}
  strokeWidth={2}
/>

Tailwind and utility CSS styling

  • fill-* sets the arrow’s fill color.
  • [&>path:first-of-type] targets the “stroke” path.
  • [&>path:last-of-type] targets the “fill” path’s extra stroke, to reduce gaps.

strokeWidth should still be manually specified as a prop.

<FloatingArrow
  ref={arrowRef}
  context={context}
  className="
    fill-white 
    [&>path:first-of-type]:stroke-pink-500
    [&>path:last-of-type]:stroke-white
  "
/>

Scale transforms

When animating the floating element’s scale, it looks best if the floating element’s transform-origin is at the tip of the arrow. The arrow middleware provides data to achieve this.

View on CodeSandbox