Skip to content

FloatingArrow

在自动定位的浮动元素内渲染可自定义的 <svg> 指向箭头三角形。

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

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

用法

¥Usage

  • 创建一个 arrowRef 并将其传递给 箭头中间件element 选项和 <FloatingArrow /> 组件。这样可以测量箭头以进行定位。

    ¥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.

  • context 传递给 <FloatingArrow /> 组件。这让组件读取定位数据。

    ¥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>
    </>
  );
}

默认情况下,箭头将与参考元素重叠。箭头的 height 会将其偏移所需的量。

¥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

箭头接受 <svg> 元素的所有属性,以及一些额外的属性:

¥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

useFloating() 返回的 context 对象。

¥The context object returned from useFloating().

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

width

默认:14

¥default: 14

箭头的宽度。

¥The width of the arrow.

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

height

默认:7

¥default: 7

箭头的高度。

¥The height of the arrow.

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

tipRadius

默认:0(锋利的)

¥default: 0 (sharp)

箭头提示的半径(圆角)。

¥The radius (rounding) of the arrow tip.

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

staticOffset

默认:undefined(使用动态位置)

¥default: undefined (use dynamic position)

箭头相对于浮动元素边缘的静态偏移覆盖。如果浮动元素沿相关轴小于参考元素并且具有边缘对齐 ('start'/'end'),则通常是理想的。

¥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

默认:undefined(使用动态路径)

¥default: undefined (use dynamic path)

箭头的自定义路径。如果你想要花式舍入,则很有用。路径应位于方形 SVG 内并放置在其底部。该路径是为 'bottom' 放置而设计的,该路径将针对其他放置进行轮换。

¥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

默认:"black"(浏览器默认)

¥default: "black" (browser default)

箭头的颜色。

¥The color of the arrow.

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

stroke

默认:"none"

¥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

默认:0

¥default: 0

箭头的描边(边框)宽度。

¥The stroke (border) width of the arrow.

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

Tailwind 和实用 CSS 样式

¥Tailwind and utility CSS styling

  • fill-* 设置箭头的填充颜色。

    ¥fill-* sets the arrow’s fill color.

  • [&>path:first-of-type] 以 “stroke” 路径为目标。

    ¥[&>path:first-of-type] targets the “stroke” path.

  • [&>path:last-of-type] 针对 “fill” 路径的额外行程,以减少间隙。

    ¥[&>path:last-of-type] targets the “fill” path’s extra stroke, to reduce gaps.

strokeWidth 仍应手动指定为 prop。

¥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

当对浮动元素的比例进行动画处理时,浮动元素的 transform-origin 位于箭头的提示看起来效果最好。arrow 中间件提供了实现此目的的数据。

¥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.

在 CodeSandbox 上查看

¥View on CodeSandbox

故障排除

¥Troubleshooting

描边不可见

¥Stroke is not visible

确保你至少指定了 1strokeWidth

¥Ensure you’ve specified at least a strokeWidth of 1.

存在间隙

¥A gap is present

  • 直接使用原生 CSS 属性(如 fillstroke)对顶层 <svg> 进行样式设置将无法正常工作。例如,如果你使用 styled(FloatingArrow) 进行样式设置,则可能会发生这种情况。相反,使用 fillstroke 属性,或定位子路径元素,如 Tailwind 和实用 CSS 样式 所示。

    ¥Styling the top-level <svg> using native CSS properties like fill and stroke directly won’t work correctly. This can happen if you’re styling using styled(FloatingArrow) for example. Instead, use the fill and stroke props, or target the child path elements as shown in Tailwind and utility CSS styling.

  • 如果将边框应用于浮动元素的内部元素,请确保箭头位于内部元素内,并且内部元素具有 position: relative CSS。这可确保箭头与边框正确对齐。

    ¥If a border is applied to an inner element of the floating element, make sure arrow is inside the inner element and that the inner element has position: relative CSS. This ensures the arrow will align with the border correctly.

  • 确保箭头的 strokeWidth 与浮动元素的边框宽度相同。

    ¥Ensure the strokeWidth of the arrow is the same as the floating element’s border width.

  • 间隙可能与某些浏览器或操作系统中的缩放级别有关。要支持透明度并防止浮动和箭头元素的颜色重叠,无法避免此问题。如果你的浮动元素和箭头不是部分透明的,而是纯色,则可以使用以下解决方法:

    ¥The gap may be related to zoom levels in some browsers or the OS. To support transparency and prevent overlapping of colors of the floating and arrow element, this problem cannot be avoided. If your floating element and arrow are not partially transparent and are instead solid colors, you can use the following workaround:

<FloatingArrow style={{ transform: 'translateY(-1px)' }}>

箭头未避开圆角

¥Arrow does not avoid rounded corners

当箭头移动时,它不会自动避开浮动元素的圆角。为了确保它不会溢出角落,你可以在调用 useFloating() 时使用 arrow() 中间件中的 padding 属性来解决这个问题。

¥The arrow doesn’t automatically avoid rounded corners of the floating element when it’s shifted. To ensure it doesn’t overflow the corners, you can use the padding prop in the arrow() middleware when calling useFloating() to account for this.