Skip to content

useHover

Adds hover event listeners that change the open state, like CSS :hover.

import {
  useFloating,
  useInteractions,
  useHover,
} from '@floating-ui/react-dom-interactions';
 
// ...
const {context} = useFloating();
const {getReferenceProps, getFloatingProps} = useInteractions([
  useHover(context, {
    // props
  }),
]);

Props

interface Props {
  enabled?: boolean;
  mouseOnly?: boolean;
  delay?: number | Partial<{open: number, close: number}>;
  restMs?: number;
  handleClose?:
    | null
    | ((
        context: FloatingContext & {
          onClose: () => void,
          tree?: FloatingTreeType | null,
        }
      ) => (event: PointerEvent) => void);
}

enabled

default: true

Conditionally enable/disable the hook.

useHover(context, {
  enabled: false,
});

mouseOnly

default: false

Whether the logic only runs for mouse input, ignoring both touch and pen pointer inputs.

useHover(context, {
  mouseOnly: true,
});

delay

default: 0

Waits for the specified time when the event listener runs before changing the open state.

useHover(context, {
  // both open and close
  delay: 500,
 
  // configure them individually
  delay: {
    open: 500,
    close: 0,
  },
});

restMs

default: 0 (off)

Waits until the user's cursor is at "rest" over the reference element before changing the open state.

You can either:

  • Use this on its own, without delay (which must be set to 0 which is the default), or
  • Use this as a more eager version of delay, where delay will then act as a fallback value.
useHover(context, {
  // Waits 150ms once the user's cursor is at rest
  restMs: 150,
 
  delay: {open: 1000}, // 1000ms fallback open value
  delay: 0, // OR no fallback value
});

handleClose

default: null

Instead of closing the floating element when the cursor leaves its reference, we can leave it open until a certain condition is satisfied.

The package exports a safePolygon() handler which will only close the floating element if the pointer is outside a dynamically computed polygon area.

This allows the user to move the cursor off the reference element and towards the floating element without it closing (e.g. it has interactive content inside).

import {
  useHover,
  safePolygon,
} from '@floating-ui/react-dom-interactions';
 
// ...
useHover(context, {
  handleClose: safePolygon(),
});

This handler runs on pointermove.

safePolygon

A "safe" polygon is one that a pointer is safe to traverse as it moves off the reference element and toward the floating element after hovering it. If the pointer moves outside of this safe area, the floating element closes.

It is a dynamic 4-sided polygon (visually a triangle) originating from the cursor once it leaves a reference element. You can see what it looks like here.

This function takes options.

restMs

default: 0

Determines whether to close the floating once the cursor is at rest for the specified number of milliseconds mid-traversal. The default value (0) will never close it unless the pointer is outside the area.

Note: this applies only if the cursor is not close enough to the floating element to be within the offset() region, so it does not apply too eagerly.

useHover(context, {
  handleClose: safePolygon({
    restMs: 50,
  }),
});

buffer

default: 0

Determines the amount of buffer (in pixels) there is around the the polygon.

While the default value should handle the vast majority of cases correctly, if you find your floating element is closing unexpectedly as the pointer tries to move toward the floating element, try increasing this value.

useHover(context, {
  handleClose: safePolygon({
    buffer: 1,
  }),
});