From b23b649de60be4f010ab162380f1cdc2b7ae5143 Mon Sep 17 00:00:00 2001 From: Dean Schulz Date: Thu, 16 May 2024 16:07:46 -0500 Subject: [PATCH 1/4] Update mobile-menu-toggle.js Adds focus trapping for mobile nav dropdown --- assets/js/theme/global/mobile-menu-toggle.js | 42 ++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/assets/js/theme/global/mobile-menu-toggle.js b/assets/js/theme/global/mobile-menu-toggle.js index df1c03be26..b973cf2986 100644 --- a/assets/js/theme/global/mobile-menu-toggle.js +++ b/assets/js/theme/global/mobile-menu-toggle.js @@ -37,6 +37,9 @@ export class MobileMenuToggle { this.$subMenus = this.$navList.find('.navPages-action'); this.$toggle = $toggle; this.mediumMediaQueryList = mediaQueryListFactory('medium'); + this.$outsideEls = $('.body, .footer'); + this.$preModalFocusedEl = null; + this.focusTrap = null; // Auto-bind this.onToggleClick = this.onToggleClick.bind(this); @@ -77,6 +80,32 @@ export class MobileMenuToggle { } } + setupFocusTrap() { + if (!this.$preModalFocusedEl) this.$preModalFocusedEl = $(document.activeElement); + + if (!this.focusTrap) { + this.focusTrap = focusTrap.createFocusTrap(this.$header[0], { + escapeDeactivates: false, + returnFocusOnDeactivate: false, + allowOutsideClick: true, + fallbackFocus: () => { + const fallbackNode = this.$preModalFocusedEl && this.$preModalFocusedEl.length + ? this.$preModalFocusedEl[0] + : $('[data-mobile-menu-toggle="menu"]')[0]; + + return fallbackNode; + }, + }); + } + + this.focusTrap.deactivate(); + this.focusTrap.activate(); + + $('.header-logo__link').attr('tabindex', 0); + $('.mobileMenu-toggle').attr('tabindex', 1); + $('.navPages-action, .button', this.$menu).attr('tabindex', 2); + } + toggle() { if (this.isOpen) { this.hide(); @@ -98,6 +127,9 @@ export class MobileMenuToggle { this.$scrollView.scrollTop(0); this.resetSubMenus(); + + this.setupFocusTrap(); + this.$outsideEls.attr({ tabindex: '-1', 'aria-hidden': true }); } hide() { @@ -112,6 +144,16 @@ export class MobileMenuToggle { this.$header.removeClass('is-open'); this.resetSubMenus(); + + if (this.focusTrap) this.focusTrap.deactivate(); + + this.$outsideEls.removeAttr('tabindex').removeAttr('aria-hidden'); + $('.header-logo__link, .mobileMenu-toggle').removeAttr('tabindex'); + $('.navPages-action, .button', this.$menu).removeAttr('tabindex'); + + if (this.$preModalFocusedEl) this.$preModalFocusedEl.focus(); + + this.$preModalFocusedEl = null; } // Private From f10a92dc8f98e353ee59910829b2e4f13c3aa6c2 Mon Sep 17 00:00:00 2001 From: Dean Schulz Date: Thu, 16 May 2024 16:11:23 -0500 Subject: [PATCH 2/4] Adding focusTrap import --- assets/js/theme/global/mobile-menu-toggle.js | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/js/theme/global/mobile-menu-toggle.js b/assets/js/theme/global/mobile-menu-toggle.js index b973cf2986..001e286fe9 100644 --- a/assets/js/theme/global/mobile-menu-toggle.js +++ b/assets/js/theme/global/mobile-menu-toggle.js @@ -1,3 +1,4 @@ +import * as focusTrap from 'focus-trap'; import _ from 'lodash'; import mediaQueryListFactory from '../common/media-query-list'; import { CartPreviewEvents } from './cart-preview'; From fc03561049967b4b8c5a1c2abba58d5f41f2c070 Mon Sep 17 00:00:00 2001 From: Dean Schulz Date: Thu, 16 May 2024 16:40:52 -0500 Subject: [PATCH 3/4] mobile focustrap update --- assets/js/theme/global/mobile-menu-toggle.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/assets/js/theme/global/mobile-menu-toggle.js b/assets/js/theme/global/mobile-menu-toggle.js index 001e286fe9..4f35ac98af 100644 --- a/assets/js/theme/global/mobile-menu-toggle.js +++ b/assets/js/theme/global/mobile-menu-toggle.js @@ -101,10 +101,6 @@ export class MobileMenuToggle { this.focusTrap.deactivate(); this.focusTrap.activate(); - - $('.header-logo__link').attr('tabindex', 0); - $('.mobileMenu-toggle').attr('tabindex', 1); - $('.navPages-action, .button', this.$menu).attr('tabindex', 2); } toggle() { @@ -130,6 +126,7 @@ export class MobileMenuToggle { this.resetSubMenus(); this.setupFocusTrap(); + this.$outsideEls.attr({ tabindex: '-1', 'aria-hidden': true }); } @@ -149,8 +146,6 @@ export class MobileMenuToggle { if (this.focusTrap) this.focusTrap.deactivate(); this.$outsideEls.removeAttr('tabindex').removeAttr('aria-hidden'); - $('.header-logo__link, .mobileMenu-toggle').removeAttr('tabindex'); - $('.navPages-action, .button', this.$menu).removeAttr('tabindex'); if (this.$preModalFocusedEl) this.$preModalFocusedEl.focus(); From 2bd645aae6384f9f118eb1098c387b3f52f5676b Mon Sep 17 00:00:00 2001 From: Dean Schulz Date: Wed, 5 Jun 2024 04:09:33 +0000 Subject: [PATCH 4/4] remove related code --- CHANGELOG.md | 1 + assets/js/theme/global/mobile-menu-toggle.js | 5 ----- package-lock.json | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e62b92f43..00459c4260 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Draft +- Adding mobile nav dropdown focusTrap [#2465](https://github.com/bigcommerce/cornerstone/pull/2465) ## 6.14.0 (05-15-2024) - Account.php is inside of a list item [#2457](https://github.com/bigcommerce/cornerstone/pull/2457) diff --git a/assets/js/theme/global/mobile-menu-toggle.js b/assets/js/theme/global/mobile-menu-toggle.js index 4f35ac98af..09ea7ef563 100644 --- a/assets/js/theme/global/mobile-menu-toggle.js +++ b/assets/js/theme/global/mobile-menu-toggle.js @@ -38,7 +38,6 @@ export class MobileMenuToggle { this.$subMenus = this.$navList.find('.navPages-action'); this.$toggle = $toggle; this.mediumMediaQueryList = mediaQueryListFactory('medium'); - this.$outsideEls = $('.body, .footer'); this.$preModalFocusedEl = null; this.focusTrap = null; @@ -126,8 +125,6 @@ export class MobileMenuToggle { this.resetSubMenus(); this.setupFocusTrap(); - - this.$outsideEls.attr({ tabindex: '-1', 'aria-hidden': true }); } hide() { @@ -145,8 +142,6 @@ export class MobileMenuToggle { if (this.focusTrap) this.focusTrap.deactivate(); - this.$outsideEls.removeAttr('tabindex').removeAttr('aria-hidden'); - if (this.$preModalFocusedEl) this.$preModalFocusedEl.focus(); this.$preModalFocusedEl = null; diff --git a/package-lock.json b/package-lock.json index bee3012fb1..a72a734299 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "bigcommerce-cornerstone", - "version": "6.12.0", + "version": "6.14.0", "license": "MIT", "dependencies": { "@bigcommerce/stencil-utils": "6.15.1",