Skip to content

arrow

为浮动元素内的箭头元素(三角形或插入符号)提供定位数据,使其看起来指向参考元素的中心。

¥Provides positioning data for an arrow element (triangle or caret) inside the floating element, such that it appears to be pointing toward the center of the reference element.

Data Provider
import {arrow} from '@floating-ui/dom';

这对于向浮动元素添加关于它所引用的元素的附加视觉提示非常有用。

¥This is useful to add an additional visual cue to the floating element about which element it is referring to.

Scroll horizontally

用法

¥Usage

箭头元素的布局框应该是宽度和高度相等的正方形。内部或伪元素可能具有不同的纵横比。

¥The layout box of the arrow element should be a square with equal width and height. Inner or pseudo-elements may have a different aspect ratio.

给定浮动元素内的箭头元素:

¥Given an arrow element inside your floating element:

<div>
  Floating element
  <div id="arrow"></div>
</div>
#arrow {
  position: absolute;
}

element 传递给 arrow() 中间件,并使用 middlewareData.arrow 中可用的坐标数据分配动态样式:

¥Pass the element to the arrow() middleware and assign the dynamic styles using the coordinates data available in middlewareData.arrow:

const arrowEl = document.querySelector('#arrow');
 
computePosition(referenceEl, floatingEl, {
  middleware: [arrow({element: arrowEl})],
}).then(({middlewareData}) => {
  if (middlewareData.arrow) {
    const {x, y} = middlewareData.arrow;
 
    Object.assign(arrowEl.style, {
      left: x != null ? `${x}px` : '',
      top: y != null ? `${y}px` : '',
    });
  }
});

该中间件仅设计用于将箭头定位在一个轴上(x 用于 'top''bottom' 放置)。另一个轴被认为是 “static”,这意味着它不需要动态定位。

¥This middleware is designed only to position the arrow on one axis (x for 'top' or 'bottom' placements). The other axis is considered “static”, which means it does not need to be positioned dynamically.

但是,你可能希望在以下情况下静态定位两个轴:

¥You may however want to position both axes statically in the following scenario:

  • 参考元素比浮动元素更宽或更高;

    ¥The reference element is either wider or taller than the floating element;

  • 浮动元素使用边缘对齐(-start-end 放置)。

    ¥The floating element is using an edge alignment (-start or -end placement).

可视化

¥Visualization

为了帮助你了解这个中间件的工作原理,这里有一个 CodeSandbox 可视化教程

¥To help you understand how this middleware works, here is a visualization tutorial on CodeSandbox.

排序

¥Order

arrow() 通常应放置在中间件数组的末尾,在 shift() 之后(如果使用)。

¥arrow() should generally be placed toward the end of your middleware array, after shift() (if used).

位置

¥Placement

要了解浮动元素实际放置在箭头的静态轴偏移的哪一侧,将返回放置位置:

¥To know which side the floating element is actually placed at for the static axis offset of the arrow, the placement is returned:

computePosition(referenceEl, floatingEl, {
  placement: 'top',
  middleware: [flip(), arrow({element: arrowEl})],
}).then((data) => {
  // The final placement can be 'bottom' or 'top'
  const placement = data.placement;
});

选项

¥Options

这些是你可以传递给 arrow() 的选项。

¥These are the options you can pass to arrow().

interface ArrowOptions {
  element: Element;
  padding?: Padding;
}

element

默认:undefined

¥default: undefined

这是要定位的箭头元素,它必须是浮动元素的子元素。

¥This is the arrow element to be positioned, which must be a child of the floating element.

arrow({
  element: document.querySelector('#arrow'),
});

padding

默认:0

¥default: 0

这描述了箭头和浮动元素边缘之间的填充。如果你的浮动元素有 border-radius,这将防止它溢出角落。

¥This describes the padding between the arrow and the edges of the floating element. If your floating element has border-radius, this will prevent it from overflowing the corners.

arrow({
  padding: 5, // stop 5px from the edges of the floating element
});

从状态导出选项

¥Deriving options from state

你可以从 中间件生命周期状态 导出选项:

¥You can derive the options from the middleware lifecycle state:

arrow((state) => ({
  padding: state.rects.reference.width,
}));

数据

¥Data

middlewareData.arrow 中有以下数据:

¥The following data is available in middlewareData.arrow:

interface Data {
  x?: number;
  y?: number;
  centerOffset: number;
}

x

如果箭头应在 x 轴上偏移,则存在此属性。

¥This property exists if the arrow should be offset on the x-axis.

y

如果箭头应在 y 轴上偏移,则存在此属性。

¥This property exists if the arrow should be offset on the y-axis.

centerOffset

此属性描述了箭头实际相对于它可能所在的位置(如果允许它溢出浮动元素以保持以参考元素为中心)。

¥This property describes where the arrow actually is relative to where it could be if it were allowed to overflow the floating element in order to stay centered to the reference element.

这可以实现两个有用的功能:

¥This enables two useful things:

  • 如果箭头无法保持在参考(即 centerOffset !== 0)的中心,你可以隐藏箭头。

    ¥You can hide the arrow if it can’t stay centered to the reference, i.e. centerOffset !== 0.

  • 你可以插入箭头的形状(例如倾斜它),使其尽可能保持居中。

    ¥You can interpolate the shape of the arrow (e.g. skew it) so it stays centered as best as possible.