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

MWPW-146129 App Launcher overlaps the menu in Unav in the devices #2123

Merged
merged 12 commits into from
Apr 23, 2024

Conversation

sharmrj
Copy link
Contributor

@sharmrj sharmrj commented Apr 9, 2024

Description

In non dekstop viewports, if the user clicks on one of the unav buttons while the menu is open, the popovers and the menu overlap. This PR brings the behavior in line with what happens on AEM.

Related Issue

Resolves: MWPW-146129

Testing instructions

See the JIRA ticket

URL for testing:

Before: https://main--milo--adobecom.hlx.live
After: https://unav-mobile--milo--sharmrj.hlx.live

…the user interacts with the universal nav (Notifications, app switcher, and profile/sign in button)
Copy link
Contributor

aem-code-sync bot commented Apr 9, 2024

Page Scores Audits Google
/ PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI

@sharmrj sharmrj added bug Something isn't working trivial PR doesn't require E2E testing by a reviewer labels Apr 9, 2024
Copy link
Contributor

This pull request is not passing all required checks. Please see this discussion for information on how to get all checks passing. Inconsistent checks can be manually retried. If a test absolutely can not pass for a good reason, please add a comment with an explanation to the PR.

@@ -280,6 +280,9 @@ class Gnav {
if (this.useUniversalNav) {
delete this.blocks.profile;
this.blocks.universalNav = toFragment`<div class="feds-utilities"></div>`;
this.blocks.universalNav.addEventListener('click', () => {
document.querySelector('.feds-toggle[aria-expanded=true]')?.click();
Copy link
Contributor

Choose a reason for hiding this comment

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

There's a closeAllDropdowns method that you can call

@@ -280,6 +280,9 @@ class Gnav {
if (this.useUniversalNav) {
delete this.blocks.profile;
this.blocks.universalNav = toFragment`<div class="feds-utilities"></div>`;
this.blocks.universalNav.addEventListener('click', () => {
Copy link
Contributor

@mokimo mokimo Apr 10, 2024

Choose a reason for hiding this comment

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

Suggested change
this.blocks.universalNav.addEventListener('click', () => {
this.blocks.universalNav.addEventListener('click', () => closeAllDropdowns());

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This seems not to work in adobe.com due to the following line (line 289 in utilities.js) in closeAllDropDowns()

    if ('fedsPreventautoclose' in el.dataset) return;

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you have a test link? Why does the element have the fedsPreventautoclose ?

Copy link
Contributor

Choose a reason for hiding this comment

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

IMO emulating a click on the open element is not the right path. You should investigate why fedsPreventautoclose exists to begin with (might be related to the keyboard navigation using arrow keys, escape, etc.) and otherwise look into adapting the closeAllDropdowns() method

Copy link
Contributor Author

@sharmrj sharmrj Apr 10, 2024

Choose a reason for hiding this comment

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

I don't have a test link. The test links don't load the unav because the request for the JS file 403s. Since it's a one liner, I tested it by adding a breakpoint in the Gnav Constructor and adding in the line manually (you need to do cmd + s for it to work).

Copy link
Contributor Author

@sharmrj sharmrj Apr 10, 2024

Choose a reason for hiding this comment

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

AFAICT it is, as you pointed out, related somewhat to the keyboard navigation files. It's difficult to say just from reading the code, but it seems that it makes somewhat of a distinction between specifically a dropdown and the menu as it opens in mobile and tablet viewports.
IMO closeAllDropdowns isn't what we're looking for here. What we're looking for specifically is inside the decorateToggle method:

    const onToggleClick = async () => {
      const isExpanded = toggle.getAttribute('aria-expanded') === 'true';
      toggle.setAttribute('aria-expanded', !isExpanded);
      this.elements.navWrapper.classList.toggle('feds-nav-wrapper--expanded', !isExpanded);
      closeAllDropdowns();
      setCurtainState(!isExpanded);
      toggle.setAttribute('daa-ll', `hamburgermenu|${isExpanded ? 'open' : 'close'}`);

      if (this.blocks?.search?.instance) {
        this.blocks.search.instance.clearSearchForm();
      } else {
        await this.loadSearch();
      }

      if (isExpanded) setHamburgerPadding();
    };

The most expedient way to call this function without a fairly significant refactor is by clicking on the element it's attached to. Furthermore it ties the behavior we want to the behavior of the actual html elements the end user interacts with, and not to the abstract way it is done in the code, which is liable to churn. In other words clicking on the toggle element decouples the implementation of the behavior (close the menu when we click on feds-utilities) from the implementation of how exactly clicking on the toggle hides/shows the menu.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that we should generally avoid emulating click events, but in this scenario, it might be a reasonable approach. The closeAllDropdowns function is checking for open elements and whether they have the dataset fedsPreventautoclose before closing. However, in this particular case, we need to overlook that and ensure that all menus close when someone clicks on the navigation.
Another way would be for us to check open elements again, remove their dataset fedsPreventautoclose, and then call closeAllDropdowns, but in my opinion, that's not the right path to take. Therefore, using the click event seems fair in this scenario.

Copy link
Contributor

@overmyheadandbody overmyheadandbody left a comment

Choose a reason for hiding this comment

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

I agree that this might not be the best approach. My hunch - this should actually work if it wasn't for the desktop viewport check here. We want to keep the behaviors between desktop and mobile separate, though, so I'd try adding an if/else. If the viewport is desktop, execute the current logic. If the viewport is mobile, close the hamburger menu. There's likely already logic that closes it (see the decorateToggle method), you might have to expose it to be able to simply re-use is where needed.

@sharmrj
Copy link
Contributor Author

sharmrj commented Apr 17, 2024

I'm not sure why unit tests are failing. The global-navigation tests seem to be passing (and global-navigation is the only modue I've touched).

Comment on lines 299 to 308
export const toggleMenuMobile = (toggle) => {
if (!toggle) return;
const isExpanded = toggle.getAttribute('aria-expanded') === 'true';
toggle.setAttribute('aria-expanded', !isExpanded);
document.querySelector(selectors.navWrapper)?.classList?.toggle('feds-nav-wrapper--expanded', !isExpanded);
closeAllDropdowns();
setCurtainState(!isExpanded);
toggle.setAttribute('daa-ll', `hamburgermenu|${isExpanded ? 'open' : 'close'}`);
};

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd argue that since this isn't used in multiple files, it can be left in the global-navigation.js one. You would then have direct access to this.elements.navWrapper and toggle and you'd keep the logic close to where it's being used.

@sigadamvenkata sigadamvenkata added the verified PR has been E2E tested by a reviewer label Apr 18, 2024
@sigadamvenkata
Copy link

Verified the changes and we done see overlap issue now. PF below screenshots
image

Copy link
Contributor

@overmyheadandbody overmyheadandbody left a comment

Choose a reason for hiding this comment

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

Let's add some relevant pages to the PR body where the hamburger menu interactions can actually be tested.

@@ -615,6 +619,16 @@ class Gnav {
});
};

toggleMenuMobile = () => {
const toggle = this.elements.mobileToggle;
const isExpanded = toggle?.getAttribute('aria-expanded') === 'true';
Copy link
Contributor

Choose a reason for hiding this comment

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

Same exact code is used on L284 & L656, might be worth turning it into a function

const isToggleExpanded = () => this.elements.mobileToggle?.getAttribute('aria-expanded') === 'true';

Copy link
Contributor

@overmyheadandbody overmyheadandbody left a comment

Choose a reason for hiding this comment

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

You could trim down a couple more lines, added comments, otherwise looks good.

Personally, I would have still integrated this into the closeOnClickOutside logic, which would have also covered the use-case where a user clicks anywhere outside the hamburger menu area, but maybe that can happen in the future.

setCurtainState(!isExpanded);
toggle.setAttribute('daa-ll', `hamburgermenu|${isExpanded ? 'open' : 'close'}`);
this.toggleMenuMobile();
const isExpanded = this.isToggleExpanded();
Copy link
Contributor

Choose a reason for hiding this comment

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

You're just using the value of this variable once, you could simply use the function call on L666, where it's used.

Comment on lines 284 to 285
const isExpanded = this.isToggleExpanded();
if (isExpanded) this.toggleMenuMobile();
Copy link
Contributor

Choose a reason for hiding this comment

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

This could be just one line, since isExpanded is not used anywhere else, if (this.isToggleExpanded()) this.toggleMenuMobile();

@sharmrj
Copy link
Contributor Author

sharmrj commented Apr 23, 2024

Personally, I would have still integrated this into the closeOnClickOutside logic, which would have also covered the use-case where a user clicks anywhere outside the hamburger menu area, but maybe that can happen in the future.

The issue with that is that it changes the current behavior in mobile viewports where tapping in the thin area outside the menu (when it's open) does nothing. I'm not sure if the current behavior should change.

@drashti1712 drashti1712 merged commit 743ce09 into adobecom:stage Apr 23, 2024
12 checks passed
vladen pushed a commit that referenced this pull request Apr 23, 2024
…in the devices (#2184)

* Closes the global nav expanded wrapper in non desktop viewports when the user interacts with the universal nav (Notifications, app switcher, and profile/sign in button)

* We no longer use element.click

* made toggleMenuMobile a method of the Gnav class

* Extracted the toggle expanded check into its own function

* a little cleanup
joaquinrivero added a commit to joaquinrivero/milo that referenced this pull request Apr 25, 2024
* stage:
  MWPW-146999: kodiak CVE 25883 (adobecom#2183)
  MWPW-144549 CTA alignment for Text, Icon, and Media Blocks (adobecom#2098)
  MWPW-146494-keep gnav sticky when branch banner is displayed (adobecom#2175)
  MWPW-135821 introduce mep custom action & use it for card collection (adobecom#2152)
  MWPW-146129 [Original: adobecom#2123] App Launcher overlaps the menu in Unav in the devices (adobecom#2184)
  Revert "MWPW-146129 App Launcher overlaps the menu in Unav in the devices" (adobecom#2182)
  MWPW-146129 App Launcher overlaps the menu in Unav in the devices (adobecom#2123)
  MWPW-139842 [Revert] Fill button style (adobecom#2181)
  Mwpw 142003: Mini Compare Chart card fixes (adobecom#2093)
  MWPW-146756] Add support for RTL in aside notifications, horizontal cards"" (adobecom#2178)
  Revert "[MWPW-146756] Add support for RTL in aside notifications, horizontal cards" (adobecom#2177)
  [MWPW-146756] Add support for RTL in aside notifications, horizontal cards (adobecom#2167)
  Revert "MWPW-142590 - [Share] enhancement - ability to edit text above icons" (adobecom#2172)
mokimo pushed a commit to mokimo/milo that referenced this pull request Apr 30, 2024
…obecom#2123)

* Closes the global nav expanded wrapper in non desktop viewports when the user interacts with the universal nav (Notifications, app switcher, and profile/sign in button)

* We no longer use element.click

* made toggleMenuMobile a method of the Gnav class

* Extracted the toggle expanded check into its own function

* a little cleanup
mokimo pushed a commit to mokimo/milo that referenced this pull request Apr 30, 2024
…in Unav in the devices (adobecom#2184)

* Closes the global nav expanded wrapper in non desktop viewports when the user interacts with the universal nav (Notifications, app switcher, and profile/sign in button)

* We no longer use element.click

* made toggleMenuMobile a method of the Gnav class

* Extracted the toggle expanded check into its own function

* a little cleanup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Ready for Stage trivial PR doesn't require E2E testing by a reviewer verified PR has been E2E tested by a reviewer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants