Popper-core: hide popper when it scrolls outside of its boundaries

Created on 6 Jun 2016  路  23Comments  路  Source: popperjs/popper-core

What is the expected behavior?

I would expect popper to disappear when element is not visible

Demo

overflow

To reproduce this you just need to change height on .example2__scroll-box from 200% to 10000px
image

Solution

I'll try to do something with a custom modifier. But I think this should be fixed in the core.

modifier

Most helpful comment

@FezVrasta hide is enabled by default isn't it? 馃槅

https://popper.js.org/popper-documentation.html#modifiers..hide.enabled

@ericsakmar you need to use something like

.popper[x-out-of-boundaries] {
  display: none;
}

All 23 comments

Yes probably we should add a "hide when reference is not visible" modifier (maybe with a shorter name ahah).

If you create one please send a PR, it would be a nice addition!

What is the best why to hide popper? I mean. With a modifier you just past data object modified. What should I pass to hide the popper?

I think the applyStyle modifier should be edited a bit to allow custom CSS properties.

Hi, I'm not sure I have time to do the PR now. But this is what I did:

I defined a modifier called hideOnReferenceNotVisibleOnBoundaries and if boundaries is defined check their visibility. Be aware that this code use jQuery dependent and ES6 syntax :)

      /**
       * Check if reference is visible inside boundaries
       *
       * @param {Object} data
       * @param {Object} boundariesElement
       * @return {Boolean}
       */
      function isVisible(data, boundariesElement) {
        const { boundaries, offsets } = data;
        const { top, bottom } = offsets.reference;
        const { height: boundariesHeight} = boundaries;
        const boundariesOffsetTop = $(boundariesElement).offset().top;
        const boundariesBottom = boundariesOffsetTop + boundariesHeight;

        return ((top <= boundariesBottom) && (bottom >= boundariesOffsetTop));
      }

      /**
       * Modifier to hide popper if is outside boundaries
       * If boundaries is not defined we skip the check
       *
       * @param {Object} data
       * @return {Object}
       */
      const hideOnReferenceNotVisibleOnBoundaries = (data) => {
        const boundariesElement = data.instance._options.boundariesElement;

        if (boundariesElement === 'viewport') return data;

        const visible = isVisible(data, boundariesElement);

        // Hide popper
        $(data.instance._popper).toggleClass('js-hide', !visible);

        return data;
      };

That's a bit too hacky to be included in Popper.js... Thanks anyway for your attempt. If someone else is interested please let me know. I can help with it.

What's the hacky part? Just to improve my version :)

We don't use jQuery with Popper.js, and modifiers should never access the DOM to write to it in any way.

Your modifier should edit only the data object, adding maybe a data.hidden property, then, applyStyle modifier should read the value and then hide or not the popper.

Ok, thanks @FezVrasta

@andresgutgon check out #53, it should help with this modifier.

I think we can close this one

Why? The enhancement is not implemented yet

I thought is a user decision to implement that. That you only provide the styles in data to change visibility.

Of you want this modifier/whatever be in the core?

I think it's a feature that would be nice to have in the core.

I've implemented this feature in the v1-dev branch, if someone wants to backport it to the v0 version please use the modifier below and include it before the applyStyles modifier:

function hide(data) {
    var refRect = data.offsets.reference;
    var bound = data.boundaries;

    if (
        refRect.bottom < bound.top ||
        refRect.left > bound.right ||
        refRect.top > bound.bottom ||
        refRect.right < bound.left
    ) {
        data.styles.display = 'none';
    } else {
        data.styles.display = '';
    }

    return data;
}

I'm still seeing the popover after it scrolls outside of the boundaries. Is there anything I need to do to enable this feature?

You have to enable it, it's disabled by default

Cool. How would I enable it? I'm not quite sure I understand. Thanks!

new Popper(ref, pop, {
  modifiers: {
    hide: { enabled: true }
  }
})

@FezVrasta hide is enabled by default isn't it? 馃槅

https://popper.js.org/popper-documentation.html#modifiers..hide.enabled

@ericsakmar you need to use something like

.popper[x-out-of-boundaries] {
  display: none;
}

oh, right, thanks

is this really working?
I use Popper.js 1.15.0 and my popper containers never gets the x-out-of-boundaries attribute when they are not inside the viewport.

nvm, some kind of npm issue... works fine after refreshing node_modules 馃槃

Its not working properly @FezVrasta

Hi, @FezVrasta, I tried using the modifier you suggested, and like @nmanikumar5, I am not able to get it to work either.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Sawtaytoes picture Sawtaytoes  路  5Comments

cixonline picture cixonline  路  5Comments

FezVrasta picture FezVrasta  路  5Comments

skitterm picture skitterm  路  5Comments

memboc picture memboc  路  3Comments