Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hide popper when it scrolls outside of its boundaries #52

Closed
andresgutgon opened this issue Jun 6, 2016 · 24 comments
Closed

hide popper when it scrolls outside of its boundaries #52

andresgutgon opened this issue Jun 6, 2016 · 24 comments
Labels
TARGETS: modifier Related to a modifier.
Milestone

Comments

@andresgutgon
Copy link

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.

@FezVrasta
Copy link
Member

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!

@FezVrasta FezVrasta added feature This would be nice to have. IDEA labels Jun 6, 2016
@andresgutgon
Copy link
Author

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?

@FezVrasta
Copy link
Member

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

@andresgutgon
Copy link
Author

andresgutgon commented Jun 6, 2016

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;
      };

@FezVrasta
Copy link
Member

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.

@andresgutgon
Copy link
Author

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

@FezVrasta
Copy link
Member

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.

@andresgutgon
Copy link
Author

Ok, thanks @FezVrasta

@FezVrasta
Copy link
Member

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

@andresgutgon
Copy link
Author

I think we can close this one

@FezVrasta
Copy link
Member

Why? The enhancement is not implemented yet

@andresgutgon
Copy link
Author

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?

@FezVrasta
Copy link
Member

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

@FezVrasta FezVrasta reopened this Jul 8, 2016
@FezVrasta FezVrasta changed the title Visible popper of not visible element on a large scrollabe area Modifier: hide popper when it scrolls outside of its boundaries Aug 6, 2016
@FezVrasta FezVrasta changed the title Modifier: hide popper when it scrolls outside of its boundaries hide popper when it scrolls outside of its boundaries Aug 6, 2016
@FezVrasta FezVrasta added TARGETS: modifier Related to a modifier. and removed feature This would be nice to have. labels Aug 6, 2016
@FezVrasta FezVrasta modified the milestone: v1.0.0 Aug 11, 2016
FezVrasta added a commit that referenced this issue Aug 11, 2016
@FezVrasta
Copy link
Member

FezVrasta commented Aug 11, 2016

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;
}

@ericsakmar
Copy link

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

@FezVrasta
Copy link
Member

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

@ericsakmar
Copy link

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

@FezVrasta
Copy link
Member

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

@atomiks
Copy link
Collaborator

atomiks commented Mar 13, 2019

@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;
}

@FezVrasta
Copy link
Member

oh, right, thanks

@larsbo
Copy link

larsbo commented Apr 8, 2019

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 😄

@nmanikumar5
Copy link

Its not working properly @FezVrasta

@JLiu1272
Copy link

JLiu1272 commented Dec 6, 2019

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

@dparker2
Copy link

For future readers, this is exactly what I added to get this to work (with v2 of popper):

  &[data-popper-reference-hidden='true'] {
    opacity: 0;
    pointer-events: none;
  }

I found that opacity worked better than visibility, which was causing a weird lag for some reason. The docs also don't include the ='true' part in the selector even though that's needed here, since the attribute changes to false instead of actually being removed when the reference is in view.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
TARGETS: modifier Related to a modifier.
Projects
None yet
Development

No branches or pull requests

8 participants