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

Fix for sticky menu close #1171

Merged
merged 4 commits into from
Jan 14, 2022
Merged

Fix for sticky menu close #1171

merged 4 commits into from
Jan 14, 2022

Conversation

tyleralsbury
Copy link
Contributor

Why are these changes introduced?

Fixes #896.

What approach did you take?

I added a class that resets the transform to 0 if the menu is open. This accounts for the issue with the sticky header.

Other considerations

Technically, if you have sticky header disabled, you can focus the hamburger and then scroll and hit enter, which opens the menu and the close button is not visible... but that is expected since the close button is part of the header. If you hit enter again, it will close.

Also, I wasn't really able to reproduce the bug the way it was described in the issue. Instead, I just scrolled the header out of view while the menu open button was focused and then hit enter. Will need to be tested with the conditions of the original issue to ensure this fix solves it - I think it will.

Demo links

Checklist

assets/global.js Show resolved Hide resolved
assets/global.js Outdated
Comment on lines 422 to 434
closeMenuDrawer(event, elementToFocus = false) {
if (event !== undefined) {
this.mainDetailsToggle.classList.remove('menu-opening');
this.mainDetailsToggle.querySelectorAll('details').forEach(details => {
details.removeAttribute('open');
details.classList.remove('menu-opening');
});
document.body.classList.remove(`overflow-hidden-${this.dataset.breakpoint}`);
removeTrapFocus(elementToFocus);
this.closeAnimation(this.mainDetailsToggle);
document.querySelector('#shopify-section-header').classList.remove('menu-open');
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
closeMenuDrawer(event, elementToFocus = false) {
if (event !== undefined) {
this.mainDetailsToggle.classList.remove('menu-opening');
this.mainDetailsToggle.querySelectorAll('details').forEach(details => {
details.removeAttribute('open');
details.classList.remove('menu-opening');
});
document.body.classList.remove(`overflow-hidden-${this.dataset.breakpoint}`);
removeTrapFocus(elementToFocus);
this.closeAnimation(this.mainDetailsToggle);
document.querySelector('#shopify-section-header').classList.remove('menu-open');
}
}
closeMenuDrawer(event, elementToFocus = false) {
super.closeMenuDrawer(event);
if (event !== undefined) {
document.querySelector('#shopify-section-header').classList.remove('menu-open');
}
}

Not sure if you need to pass elementToFocus = false to it as well 🤔

MDN docs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe we just need to pass elementToFocus since that will be defined in the child instance of the method - whether it's the default (false) or something else.

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 catch, by the way. I assumed there was a way to do this but never actually looked into it. This is very useful.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah Lucas brought it up to me on the Slideshow PR and it was exactly what I needed there as well.

@@ -1974,6 +1974,10 @@ input[type='checkbox'] {
transform: translateY(-100%);
}

.shopify-section-header-hidden.menu-open {
Copy link
Contributor

Choose a reason for hiding this comment

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

It kinda sounds weird that both of those classes would be on at the same time 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed - but consider it an "override" in a sense.

It allows us to do this without needing to do any wacky logic with the JS. It should only happen when one of two things are done:

  1. A user has the menu focused and then scrolls and hits enter
  2. A browser triggers a small scroll as the menu opens (probably happens due to a scrollbar rendering / disappearing which causes some reflow).

@KaichenWang
Copy link
Contributor

For context, there was a similar fix for predictive search - https://github.com/Shopify/dawn/pull/660/files
The difference is that instead of a user scrolling and causing the header to hide, the culprit in this case is:

document.body.classList.remove(`overflow-hidden-${this.dataset.breakpoint}`);

Which triggers the onScroll() function of StickyHeader

I'm ok with the approach in this PR, but the #660 approach is another option

@tyleralsbury
Copy link
Contributor Author

For context, there was a similar fix for predictive search - https://github.com/Shopify/dawn/pull/660/files The difference is that instead of a user scrolling and causing the header to hide, the culprit in this case is:

document.body.classList.remove(`overflow-hidden-${this.dataset.breakpoint}`);

Which triggers the onScroll() function of StickyHeader

I'm ok with the approach in this PR, but the #660 approach is another option

We can consolidate the approaches if we want to at some point. Thanks for the context.

@tyleralsbury
Copy link
Contributor Author

Ready for another round.

Great find on the super.method() thing, @ludoboludo . I wonder if there are other places where this would work.

@KaichenWang - I think I'd like to keep this approach for now. I think it's clear and simple. We can revisit and consolidate at some point if we decide we want to.

Copy link
Contributor

@ludoboludo ludoboludo left a comment

Choose a reason for hiding this comment

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

Just found an issue which is likely to happen.

It's pretty likely that people will try and click on the body/outside of the menu drawer to close it. Which at the moment it doesn't.
When you scroll down the page, then up a little again to show the sticky header, click the menu icon, then click the body/outside of the drawer and the header will disappear.

video

@tyleralsbury
Copy link
Contributor Author

Just found an issue which is likely to happen.

It's pretty likely that people will try and click on the body/outside of the menu drawer to close it. Which at the moment it doesn't. When you scroll down the page, then up a little again to show the sticky header, click the menu icon, then click the body/outside of the drawer and the header will disappear.

video

How are you managing to scroll like that? It should be blocked... I can't scroll when the menu is open at all. What are the exact steps to reproduce that?

Copy link
Contributor

@martinamarien martinamarien left a comment

Choose a reason for hiding this comment

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

I can replicate what Ludo shared.
The menu is supposed to close if you click outside of the drawer, and it used to. I think when the animation work was implemented, the "click to dismiss" was broken somehow.

Similarly, if you have the menu open and click on search, it's supposed to close the drawer and open the search drawer.

I think this is a separate issue from this PR and wasn't introduced here. We can definitely address more thoroughly in a separate PR.

assets/global.js Outdated Show resolved Hide resolved
assets/global.js Outdated Show resolved Hide resolved
Copy link
Contributor

@melissaperreault melissaperreault left a comment

Choose a reason for hiding this comment

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

Thanks Tyler! The original bug to fix works well! 🎉

As for the outside click to dismiss, it is best practices to give users different ways to escape by giving them a way to close the drawer like we would for modals with; Close button, Escape key and Click outside the window.

@KaichenWang
Copy link
Contributor

The menu is supposed to close if you click outside of the drawer, and it used to. I think when the animation work was implemented, the "click to dismiss" was broken somehow.

I think the issue is that closeMenuDrawer() requires the event param to be not undefined
https://github.com/Shopify/dawn-internal/pull/466/commits/1a3165755e83f79ae9ec28ad9d61b03c921c810e

And agreed that this should be its own separate issue.

Copy link
Contributor

@KaichenWang KaichenWang left a comment

Choose a reason for hiding this comment

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

Looks good. Will be able to take another look when other reviewer's feedback is addressed

assets/global.js Outdated Show resolved Hide resolved
@tyleralsbury
Copy link
Contributor Author

Should be ready for another review - let's address the click to close separately.

Copy link
Contributor

@ludoboludo ludoboludo left a comment

Choose a reason for hiding this comment

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

Tackling the click to close will also resolve the weird click issue I noticed. Good to go for me 👍

Copy link
Contributor

@martinamarien martinamarien left a comment

Choose a reason for hiding this comment

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

Looks good. Thanks Tyler.

@tyleralsbury tyleralsbury merged commit ee22e30 into main Jan 14, 2022
@tyleralsbury tyleralsbury deleted the menu-close-fix branch January 14, 2022 18:55
phapsidesGT pushed a commit to Gravytrain-UK/gt-shopify-dawn-theme that referenced this pull request Sep 3, 2024
* Fix for sticky menu close
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Drawer menu hard to close when open from sticky header
5 participants