react-popper icon indicating copy to clipboard operation
react-popper copied to clipboard

How to size popper dynamically with detectOverflow

Open mhanley00 opened this issue 2 years ago • 3 comments

Reproduction demo

Steps to reproduce the problem

  1. Create a popper with no outside CSS (other than the attribute positioning)
  2. Create a memoized detectOverflow modifier that attempts to modify the size of the popper if overflow is detected (ie if right/left/top/bottom > 0):
const preventOverflow = React.useMemo(
    () => ({
      name: 'detectOverflow',
      enabled: true,
      phase: 'main',
      requiresIfExists: ['offset'],
      fn: (data) => {
        
        const overflow = detectOverflow(data.state);
        /*If the number is positive, the popper is overflowing by that number of pixels.
        When 0, or negative, the popper is within its boundaries. */
        if (
          overflow.right >= 0 ||
          overflow.left >= 0 ||
          overflow.top >= 0 ||
          overflow.bottom >= 0
        ) {
          const width = 220;
          const height = 200;
         /* Manually update the popper object*/
          const popper = {
            ...data.state.rects,
            popper: { ...data.state.rects.popper, width, height },
          };
          
          const state = { ...data.state, rects: popper };
          
          return { ...data, state, instance: { ...data.instance, state } };
        }
      },
    }),
    [],
  );

What is the expected behavior?

Based on this response: https://github.com/floating-ui/react-popper/issues/73 I would expect to be able to manually update the size of the popper when overflow is detected.

What went wrong?

I'm unsuccessful in trying to update the height and width of the popper based on available screen size. Previously I had done this outside of the modifier in a useEffect based on screen size, but because we don't always have the popper attributes available (ie position, sometimes they're null when it hasn't initialized yet) to know how much available space we actually have, then we have to make it smaller based on width so we can eventually fit the popper over top of the anchor, when there's really plenty of space, say, to the left.

Any other comments?

Please let me know if you need anything else from me! Thank you so much for making this Popper.js free, it's one of my all-time favorites libs.

Packages versions

  • Popper.js: 2.11.6
  • react-popper: 2.3.0

mhanley00 avatar Dec 07 '22 15:12 mhanley00

Did you try the https://www.npmjs.com/package/popper-max-size-modifier package?

FezVrasta avatar Dec 07 '22 17:12 FezVrasta

I deprecated that and pointed to https://floating-ui.com/docs/size as it was buggy in a couple ways — I recommend just switching to Floating UI as it's getting full support and the size modifier is much more reliable and easier to use

atomiks avatar Dec 07 '22 22:12 atomiks

Thank you both so much for your help! @atomiks awesome, Floating-UI looks like the way to go 💯

mhanley00 avatar Dec 12 '22 23:12 mhanley00