Skip to content

useFloating

库的主 Hook,充当所有其他 Hook 和组件的控制器。

¥The main Hook of the library that acts as a controller for all other Hooks and components.

用法

¥Usage

在组件内调用 Hook。

¥Call the Hook inside a component.

function App() {
  const {refs, floatingStyles} = useFloating();
  return (
    <>
      <div ref={refs.setReference} />
      <div ref={refs.setFloating} style={floatingStyles} />
    </>
  );
}

选项

¥Options

Hook 接受选项对象来配置其行为。

¥The Hook accepts an object of options to configure its behavior.

useFloating({
  // options
});

placement

默认:'bottom'

¥default: 'bottom'

浮动元素相对于参考元素的放置。

¥The placement of the floating element relative to the reference element.

useFloating({
  placement: 'left',
});

12 个字符串可用:

¥12 strings are available:

type Placement =
  | 'top'
  | 'top-start'
  | 'top-end'
  | 'right'
  | 'right-start'
  | 'right-end'
  | 'bottom'
  | 'bottom-start'
  | 'bottom-end'
  | 'left'
  | 'left-start'
  | 'left-end';

-start-end 对齐方式是 logical,并将按预期适应写入方向(例如 RTL)。

¥The -start and -end alignments are logical and will adapt to the writing direction (e.g. RTL) as expected.

strategy

默认:'absolute'

¥default: 'absolute'

这是要使用的 CSS 位置属性的类型。有两个字符串可用:

¥This is the type of CSS position property to use. Two strings are available:

type Strategy = 'absolute' | 'fixed';
useFloating({
  strategy: 'fixed',
});

这些策略的区别如下:

¥These strategies are differentiated as follows:

  • 'absolute' — 浮动元素相对于其最近的定位祖级进行定位。对于大多数布局,这通常要求浏览器在更新位置时执行最少的工作。

    ¥'absolute' — the floating element is positioned relative to its nearest positioned ancestor. With most layouts, this usually requires the browser to do the least work when updating the position.

  • 'fixed' — 浮动元素相对于其最近的包含块(通常是视口)定位。当参考元素也被固定以减少滚动时定位的跳跃时,这非常有用。在很多情况下它也会 “break” 裁剪祖级中的浮动元素

    ¥'fixed' — the floating element is positioned relative to its nearest containing block (usually the viewport). This is useful when the reference element is also fixed to reduce jumpiness with positioning while scrolling. It will in many cases also “break” the floating element out of a clipping ancestor.

transform

默认:true

¥default: true

是否使用 CSS 变换而不是布局来定位浮动元素(topleft CSS 属性)。

¥Whether to use CSS transforms to position the floating element instead of layout (top and left CSS properties).

useFloating({
  transform: false,
});

CSS 变换的性能更高,但可能会导致与变换动画发生冲突。在这种情况下,你可以将定位的浮动元素设置为封装器以避免冲突:

¥CSS transforms are more performant, but can cause conflicts with transform animations. In that case, you can make the positioned floating element a wrapper to avoid the conflict:

<div ref={refs.setFloating} style={floatingStyles}>
  <div style={transitionStyles}>Content</div>
</div>

middleware

默认:[]

¥default: []

更改浮动元素位置的中间件对象数组。

¥An array of middleware objects that change the positioning of the floating element.

useFloating({
  middleware: [
    // ...
  ],
});

当你想要精确控制浮动元素的定位方式时,可以使用中间件。它们读取当前坐标,可以选择更改它们,和/或提供用于渲染的数据。它们组合并共同产生 floatingStyles 对象中的最终坐标。

¥When you want granular control over how the floating element is positioned, middleware are used. They read the current coordinates, optionally alter them, and/or provide data for rendering. They compose and work together to produce the final coordinates which are in the floatingStyles object.

封装中包含以下物品:

¥The following are included in the package:

位置修饰符

¥Placement modifiers

这些中间件改变基本放置坐标。

¥These middleware alter the base placement coordinates.

  • offset 修改放置以添加参考元素和浮动元素之间的距离或边距。

    ¥offset modifies the placement to add distance or margin between the reference and floating elements.

  • inline 相对于各个客户端矩形而不是边界框定位浮动元素,以获得更好的精度。

    ¥inline positions the floating element relative to individual client rects rather than the bounding box for better precision.

可见性优化器

¥Visibility optimizers

这些中间件改变坐标以确保浮动元素以最佳状态停留在屏幕上。

¥These middleware alter the coordinates to ensure the floating element stays on screen optimally.

  • shift 通过移动浮动元素使其保持在视野中,防止浮动元素溢出剪切容器。

    ¥shift prevents the floating element from overflowing a clipping container by shifting it to stay in view.

  • flip 通过将浮动元素翻转到相反的位置以保持在视图中,防止浮动元素溢出剪切容器。

    ¥flip prevents the floating element from overflowing a clipping container by flipping it to the opposite placement to stay in view.

  • autoPlacement 使用 “大部分空间” 策略自动为你选择展示位置。

    ¥autoPlacement automatically chooses a placement for you using a “most space” strategy.

  • size 调整浮动元素的大小,例如使其不会溢出剪切容器,或匹配参考元素的宽度。

    ¥size resizes the floating element, for example so it will not overflow a clipping container, or to match the width of the reference element.

数据提供者

¥Data providers

这些中间件仅提供数据,并不改变坐标。

¥These middleware only provide data and do not alter the coordinates.

  • arrow 提供数据来定位浮动元素的内部元素,使其以其参考元素为中心。

    ¥arrow provides data to position an inner element of the floating element such that it is centered to its reference element.

  • 当由于不同的剪切上下文而不再显示附加到其参考元素时,hide 提供了在适用情况下隐藏浮动元素的数据。

    ¥hide provides data to hide the floating element in applicable situations when it no longer appears attached to its reference element due to different clipping contexts.

选项反应性

¥Option reactivity

当使用 React 状态和中间件时,函数选项内的状态值(从中间件状态派生时有用)不是新鲜的或反应性的。

¥When using React state and middleware, stateful values inside function options (useful when deriving from middleware state) aren’t fresh or reactive.

const [value, setValue] = useState(0);
// Reactive and fresh:
offset(value);
// Not reactive or fresh:
offset(() => value);

调用中间件函数会返回一个带有 options 键的对象。这些键可以保存选项对象的依赖,从而允许进行深度比较以实现反应性。

¥Calling a middleware function returns an object with an options key. These keys can hold the dependencies of the options object, allowing deep comparison to enable reactivity.

这是一个例子:

¥Here’s an example:

import {offset} from '@floating-ui/react';
 
function App() {
  const [value, setValue] = useState(0);
 
  useFloating({
    middleware: [
      // Updates when `value` changes ✅
      offset(value),
 
      // Does not update when `value` changes ❌
      offset(() => value),
 
      // Updates when `value` changes ✅
      {
        ...offset(() => value),
        options: [value],
      },
    ],
  });
}

作为封装器:

¥As a wrapper:

const reactiveOffset = (options, deps) => ({
  ...offset(options),
  options: deps,
});
 
reactiveOffset(() => value, [value]);

elements

默认:undefined

¥default: undefined

传递给 Hook 的元素对象,对于外部传递它们非常有用,作为 refs 对象设置器的替代方案。

¥An object of elements passed to the Hook, which is useful for externally passing them, as an alternative to the refs object setters.

元素必须保持状态(而不是普通引用)以确保它们是反应性的。

¥The elements must be held in state (not plain refs) to ensure that they are reactive.

const [reference, setReference] = useState(null);
 
const {refs} = useFloating({
  elements: {
    reference,
  },
});
 
return (
  <>
    <div ref={setReference} />
    <div ref={refs.setFloating} />
  </>
);

你也可以执行与上述相反的操作,或者从外部传递两者。

¥You can also do the inverse of the above, or pass both externally.

whileElementsMounted

默认:undefined

¥default: undefined

在安装引用元素和浮动元素时调用的函数,并返回在卸载它们时调用的清理函数。

¥A function that is called when the reference and floating elements are mounted, and returns a cleanup function called when they are unmounted.

useFloating({
  whileElementsMounted: (reference, floating, update) => {
    // ...
    return () => {
      // ...
    };
  },
});

这允许你传递签名与选项匹配的 autoUpdate,以确保浮动元素保持锚定到参考元素:

¥This allows you to pass autoUpdate whose signature matches the option, to ensure the floating element remains anchored to the reference element:

import {autoUpdate} from '@floating-ui/react';
 
useFloating({
  whileElementsMounted: autoUpdate,
});

open

默认:false

¥default: false

浮动元素是否打开,可以判断浮动元素是否已经定位。

¥Whether the floating element is open or not, which allows you to determine if the floating element has been positioned yet.

const [isOpen, setIsOpen] = useState(false);
 
const {isPositioned} = useFloating({
  open: isOpen,
});
 
// Once `isOpen` flips to `true`, `isPositioned` will switch to `true`
// asynchronously. We can use an Effect to determine when it has
// been positioned.
useEffect(() => {
  if (isPositioned) {
    // ...
  }
}, [isPositioned]);

返回值

¥Return value

Hook 返回以下类型:

¥The Hook returns the following type:

interface UseFloatingReturn {
  context: FloatingContext;
  placement: Placement;
  strategy: Strategy;
  x: number;
  y: number;
  middlewareData: MiddlewareData;
  isPositioned: boolean;
  update(): void;
  floatingStyles: React.CSSProperties;
  refs: {
    reference: React.MutableRefObject<ReferenceElement | null>;
    floating: React.MutableRefObject<HTMLElement | null>;
    domReference: React.MutableRefObject<Element | null>;
    setReference(node: RT | null): void;
    setFloating(node: HTMLElement | null): void;
    setPositionReference(node: ReferenceElement): void;
  };
  elements: {
    reference: RT | null;
    floating: HTMLElement | null;
  };
}

placement

浮动元素相对于参考元素的最终放置。与选项中传递的那个不同,这个可以被像 flip() 这样的中间件改变。这是确定浮动元素的实际侧面以进行样式设置所必需的。

¥The final placement of the floating element relative to the reference element. Unlike the one passed in the options, this one can be mutated by middleware like flip(). This is necessary to determine the actual side of the floating element for styling.

const {placement} = useFloating();

strategy

浮动元素的定位策略。

¥The positoning strategy of the floating element.

const {strategy} = useFloating();

x

浮动元素的最终 x 坐标。这可以用作 floatingStyles 的替代方案,通过自定义 CSS 手动定位浮动元素。

¥The final x-coordinate of the floating element. This can be used as an alternative to floatingStyles to manually position the floating element with custom CSS.

const {x} = useFloating();

y

浮动元素的最终 y 坐标。这可以用作 floatingStyles 的替代方案,通过自定义 CSS 手动定位浮动元素。

¥The final y-coordinate of the floating element. This can be used as an alternative to floatingStyles to manually position the floating element with custom CSS.

const {y} = useFloating();

middlewareData

使用的任何中间件提供的数据。

¥The data provided by any middleware used.

const {middlewareData} = useFloating();

isPositioned

在效果内部使用时(不是在渲染期间)浮动元素是否已经定位。需要传递 open 选项。

¥Whether the floating element has been positioned yet when used inside an Effect (not during render). Requires the open option to be passed.

const {isPositioned} = useFloating();

update

手动更新浮动元素位置的函数。

¥A function that updates the floating element’s position manually.

const {update} = useFloating();

floatingStyles

应应用于浮动元素的样式。

¥The styles that should be applied to the floating element.

const {floatingStyles} = useFloating();

refs

应用于引用和浮动元素的 refs。

¥The refs that should be applied to the reference and floating elements.

const {refs} = useFloating();

reference

参考元素的 ref。你可以在事件处理程序或效果中访问它。

¥A ref for the reference element. You can access this inside an event handler or in an Effect.

const {refs} = useFloating();
useEffect(() => {
  console.log(refs.reference.current);
}, [refs]);

floating

浮动元素的引用。你可以在事件处理程序中访问它。

¥A ref for the floating element. You can access this inside an event handler.

对于在效果中使用,更喜欢使用 elements.floating,因为不能保证浮动元素在第一次传递时可用。

¥For usage in Effects, prefer using elements.floating, since it’s not guaranteed the floating element will be available on the first pass.

const {refs} = useFloating();
// Inside an event handler:
console.log(refs.floating.current);

setReference

设置参考元素的函数。

¥A function that sets the reference element.

const {refs} = useFloating();
return <div ref={refs.setReference} />;

setFloating

设置浮动元素的函数。

¥A function that sets the floating element.

const {refs} = useFloating();
return <div ref={refs.setFloating} />;

elements

由 refs 设置的元素,对于渲染期间的访问或需要被动检查元素是否存在时非常有用。

¥The elements as set by the refs, useful for access during rendering or when needing to reactively check if the element exists.

const {elements} = useFloating();

reference

参考元素。可能是虚拟的。

¥The reference element. May be virtual.

const {elements} = useFloating();
console.log(elements.reference);

floating

浮动元素。使你能够被动地检查浮动元素是否存在于 Effects 中,在使用 <FloatingPortal> 时值得注意,因为它在第一次传递时不可用。

¥The floating element. Enables you to reactively check if the floating element exists inside Effects, notable when using <FloatingPortal>, as it won’t be available on the first pass.

const {elements} = useFloating();
React.useEffect(() => {
  if (!elements.floating) return;
  // ...
}, [elements.floating]);