Skip to content
This repository was archived by the owner on Aug 11, 2021. It is now read-only.

Hide dropdown on scroll#223

Open
vincaslt wants to merge 1 commit intomasterfrom
fix/dropdown-scroll
Open

Hide dropdown on scroll#223
vincaslt wants to merge 1 commit intomasterfrom
fix/dropdown-scroll

Conversation

@vincaslt
Copy link
Contributor

@vincaslt vincaslt commented Aug 26, 2019

Related: ProtonMail/design-system#206

If dropdown is supposed to be closed when clicking outside, it's removed on scroll also. Should fix: https://github.com/ProtonMail/protonvpn-settings/issues/69

document.addEventListener('touchstart', handleClickOutside);
document.addEventListener('keydown', handleKeydown);

const scrollContainer = document.getElementsByClassName(scrollContainerClass)[0] || document.body;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a big fan of using getElementsByClassName to select an element in the DOM with React. I prefer if we use a ref from the main body or just use document.body.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also to get the first one querySelector > * ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Me too. However, in this case, my thinking is that - we mostly use the same layout components, so the main container is usually <main className="main main-area>, and I really don't want to have to pass ref of that container to every dropdown we create. Getting the main element by query/className I can set the default to main so that we don't need to specify that prop most of the time.
document.body is not really our scroll container, and querySelector is just syntactic sugar in this case.

Any thoughts?

Copy link
Contributor Author

@vincaslt vincaslt Aug 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another more explicit way I've been thinking about, but which requires a little more effort is to have a wrapper that basically marks the component as scroll container for dropdowns and use it from context as ref.

Maybe something like:

// PublicLayout.js
<PopperScrollContainer>
    {(ref) => <main ref={ref} className="main main-area">{children}</main>}
</PopperScrollContainer>

// Dropdown.js
const { placement, position } = usePopper(popperRef, anchorRef, isOpen, {
    scrollContainer
});

// usePopper.js
const scrollContainer = usePopperScrollContainer()
[...]
const contentArea = scrollContainer.current || document.body;
[...]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We did something similar to get the sticky title more easily in the settings app, where a ref to the main element is being provided:

https://github.com/ProtonMail/protonmail-settings/blob/master/src/app/components/layout/PrivateLayout.js#L30

https://github.com/ProtonMail/react-components/blob/master/components/container/SettingsTitle.js

It's not super pretty either, but for now it's ok I guess. To use that in the dropdown we would need to enforce all apps to provide a ref to the main element.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, didn't know we had that. It's pretty much what I've described, so I'll use it. This will make it more consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a couple of complicated things though with context. It's value would have to be re-defined in several places:

  • in most apps it's just main-area, but for instance header, is outside the main area, so it's not part of the context.
  • in contacts, we have several scrollable areas - contacts list and contact view.
  • modals are outside of any context, so they can't even re-define the ref to be ContentModal (at least I couldn't)
  • it affects also tooltips

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I see.

I think it could make sense to redefine the context for each situation. It should be possible to redefine it for modals also, but I'll investigate that.

Maybe let's wait with this PR a bit.

@EpokK EpokK self-assigned this Aug 26, 2019
@EpokK EpokK added the Blocked label Aug 28, 2019
nico3333fr added a commit that referenced this pull request Sep 12, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dropdown button in the pagination can be positioned above the page title

4 participants