Skip to content

PopoverNext: expose autoUpdateOptions prop to configure floating-ui autoUpdate behavior #7842

@kajtzu

Description

@kajtzu

Problem

usePopover.ts hardcodes whileElementsMounted: autoUpdate with no options:

const data = useFloating({
    // ...
    whileElementsMounted: autoUpdate,
});

This enables all default autoUpdate behaviors: ancestorScroll, ancestorResize, elementResize, and layoutShift. There is no way for consumers to customize this.

The layoutShift detection (which uses IntersectionObserver to track reference element drift) can create a positioning feedback loop in certain layouts — for example, when a PopoverNext opens near a live-resizing element like a MapLibre GL canvas that uses ResizeObserver to call map.resize(). The cycle is:

  1. Popover opens → autoUpdate positions it → sub-pixel layout shift
  2. Adjacent element's ResizeObserver fires → triggers resize/relayout
  3. autoUpdate's layoutShift observer detects the reference moved → repositions
  4. Goto 2 — visible as screen "vibration"

This was not an issue with the legacy Popover (Popper.js) because it used scheduleUpdate on demand rather than continuous observation.

Proposed solution

Add an optional autoUpdateOptions prop to PopoverNextProps:

interface PopoverNextProps {
    /** Options forwarded to floating-ui's autoUpdate. All enabled by default. */
    autoUpdateOptions?: AutoUpdateOptions;
    // ...
}

And in usePopover.ts:

const data = useFloating({
    // ...
    whileElementsMounted: autoUpdateOptions
        ? (reference, floating, update) => autoUpdate(reference, floating, update, autoUpdateOptions)
        : autoUpdate,
});

This lets consumers disable specific behaviors when needed:

<PopoverNext autoUpdateOptions={{ layoutShift: false }}>

Workaround

We're currently using a yarn patch to disable layoutShift globally in usePopover.ts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions