nsw-design-system 3.9.0 → 3.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/js/main.js CHANGED
@@ -141,16 +141,15 @@
141
141
  };
142
142
 
143
143
  class Navigation {
144
- constructor() {
144
+ constructor(element) {
145
+ this.nav = element;
146
+ this.navID = this.nav.id;
145
147
  this.openNavButton = document.querySelector('.js-open-nav');
146
- this.closeNavButtons = document.querySelectorAll('.js-close-nav');
147
- this.openSubNavButtons = document.querySelectorAll('.js-open-sub-nav');
148
- this.closeSubNavButtons = document.querySelectorAll('.js-close-sub-nav');
149
- this.mainNavElement = document.getElementById('main-nav');
150
- this.isMegaMenuElement = !!document.querySelector('.js-mega-menu');
148
+ this.closeNavButtons = this.nav.querySelectorAll('.js-close-nav');
149
+ this.closeSubNavButtons = this.nav.querySelectorAll('.js-close-sub-nav');
150
+ this.isMegaMenuElement = this.nav.classList.contains('js-mega-menu');
151
+ this.mainNavIsOpen = false;
151
152
  this.transitionEvent = whichTransitionEvent();
152
- this.mobileToggleMainNavEvent = e => this.mobileToggleMainNav(e);
153
- this.mobileToggleSubNavEvent = () => this.closeSubNav();
154
153
  this.mobileShowMainTransitionEndEvent = e => this.mobileShowMainNav(e);
155
154
  this.mobileHideMainTransitionEndEvent = e => this.mobileHideMainNav(e);
156
155
  this.showSubNavTransitionEndEvent = e => this.showSubNav(e);
@@ -159,48 +158,52 @@
159
158
  this.desktopButtonClickEvent = e => this.buttonClickDesktop(e);
160
159
  this.desktopButtonKeydownEvent = e => this.buttonKeydownDesktop(e);
161
160
  this.checkFocusEvent = e => this.checkIfContainsFocus(e);
162
- this.escapeCloseEvent = e => this.escapeClose(e);
163
- this.outsideClickEvent = e => this.handleOutsideClick(e);
164
161
  this.openSubNavElements = [];
165
162
  this.breakpoint = window.matchMedia('(min-width: 62em)');
166
- this.body = document.body;
167
163
  }
168
164
  init() {
169
- if (this.mainNavElement) {
170
- this.setUpMobileControls();
171
- this.responsiveCheck(this.breakpoint);
172
- this.breakpoint.addListener(e => this.responsiveCheck(e));
173
- this.addOutsideClickListener();
165
+ this.initEvents();
166
+ this.responsiveCheck(this.breakpoint);
167
+ if (this.nav) {
168
+ this.breakpoint.addEventListener('change', event => this.responsiveCheck(event));
174
169
  }
175
170
  }
176
- addOutsideClickListener() {
177
- document.addEventListener('click', this.outsideClickEvent, false);
178
- }
179
- removeOutsideClickListener() {
180
- document.removeEventListener('click', this.outsideClickEvent, false);
181
- }
182
- handleOutsideClick(event) {
183
- const isOutsideNav = !this.mainNavElement.contains(event.target);
184
- if (isOutsideNav) {
185
- this.saveElements(event);
186
- this.toggleSubNavDesktop(true);
187
- event.preventDefault();
171
+ initEvents() {
172
+ if (this.isMegaMenuElement) {
173
+ document.addEventListener('click', this.handleOutsideClick.bind(this), false);
174
+ document.addEventListener('keydown', this.escapeClose.bind(this), false);
188
175
  }
176
+ this.openNavButton.addEventListener('click', this.mobileToggleMainNav.bind(this), false);
177
+ this.closeNavButtons.forEach(element => {
178
+ element.addEventListener('click', this.mobileToggleMainNav.bind(this), false);
179
+ });
180
+ this.closeSubNavButtons.forEach(element => {
181
+ element.addEventListener('click', this.closeSubNav.bind(this), false);
182
+ });
189
183
  }
190
- responsiveCheck(e) {
184
+ responsiveCheck(event) {
191
185
  let megaMenuListItems = [];
192
- if (e.matches) {
193
- megaMenuListItems = [].slice.call(this.mainNavElement.querySelectorAll('ul > li'));
194
- this.body.classList.remove('main-nav-active');
186
+ if (event.matches) {
187
+ megaMenuListItems = [].slice.call(this.nav.querySelectorAll('ul > li'));
188
+ document.body.classList.remove('main-nav-active');
195
189
  } else {
196
- megaMenuListItems = [].slice.call(this.mainNavElement.querySelectorAll('li'));
190
+ megaMenuListItems = [].slice.call(this.nav.querySelectorAll('li'));
197
191
  }
198
192
  this.tearDownNavControls();
199
193
  this.setUpNavControls(megaMenuListItems);
200
194
  }
195
+ handleOutsideClick(event) {
196
+ // removes handleOutsideClick functionality from docs site
197
+ if (this.nav.closest('.nsw-docs')) return;
198
+ if (!this.mainNavIsOpen) return;
199
+ const isOutsideNav = !this.nav.contains(event.target);
200
+ if (isOutsideNav) {
201
+ this.toggleSubNavDesktop(true);
202
+ }
203
+ }
201
204
  tearDownNavControls() {
202
205
  if (this.isMegaMenuElement) {
203
- const listItems = [].slice.call(this.mainNavElement.querySelectorAll('li'));
206
+ const listItems = [].slice.call(this.nav.querySelectorAll('li'));
204
207
  listItems.forEach(item => {
205
208
  const submenu = item.querySelector('[id^=sub-nav-]');
206
209
  const link = item.querySelector('a');
@@ -214,19 +217,6 @@
214
217
  });
215
218
  }
216
219
  }
217
- setUpMobileControls() {
218
- this.openNavButton.addEventListener('click', this.mobileToggleMainNavEvent, false);
219
- this.closeNavButtons.forEach(element => {
220
- element.addEventListener('click', this.mobileToggleMainNavEvent, false);
221
- });
222
- this.closeSubNavButtons.forEach(element => {
223
- element.addEventListener('click', this.mobileToggleSubNavEvent, false);
224
- });
225
- }
226
- mobileMainNavTrapTabs(e) {
227
- const elemObj = getFocusableElementBySelector(this.mainNavElement.id, ['> div button', '> ul > li > a']);
228
- trapTabKey(e, elemObj);
229
- }
230
220
  setUpNavControls(listItems) {
231
221
  if (this.isMegaMenuElement) {
232
222
  listItems.forEach(item => {
@@ -238,29 +228,32 @@
238
228
  link.setAttribute('aria-controls', submenu.id);
239
229
  link.addEventListener('click', this.desktopButtonClickEvent, false);
240
230
  link.addEventListener('keydown', this.desktopButtonKeydownEvent, false);
241
- document.addEventListener('keydown', this.escapeCloseEvent, false);
242
231
  }
243
232
  });
244
233
  }
245
234
  }
235
+ mobileMainNavTrapTabs(e) {
236
+ const elemObj = getFocusableElementBySelector(this.navID, ['> div button', '> ul > li > a']);
237
+ trapTabKey(e, elemObj);
238
+ }
246
239
  mobileShowMainNav(_ref) {
247
240
  let {
248
241
  propertyName
249
242
  } = _ref;
250
- if (!propertyName === 'transform') return;
251
- getFocusableElementBySelector(this.mainNavElement.id, ['> div button', '> ul > li > a']).all[1].focus();
252
- this.mainNavElement.classList.add('active');
253
- this.mainNavElement.classList.remove('activating');
254
- this.mainNavElement.removeEventListener(this.transitionEvent, this.mobileShowMainTransitionEndEvent, false);
255
- this.mainNavElement.addEventListener('keydown', this.mobileTrapTabKeyEvent, false);
243
+ if (propertyName !== 'transform') return;
244
+ getFocusableElementBySelector(this.navID, ['> div button', '> ul > li > a']).all[1].focus();
245
+ this.nav.classList.add('active');
246
+ this.nav.classList.remove('activating');
247
+ this.nav.removeEventListener(this.transitionEvent, this.mobileShowMainTransitionEndEvent, false);
248
+ this.nav.addEventListener('keydown', this.mobileTrapTabKeyEvent, false);
256
249
  }
257
250
  mobileHideMainNav(_ref2) {
258
251
  let {
259
252
  propertyName
260
253
  } = _ref2;
261
- if (!propertyName === 'transform') return;
262
- this.mainNavElement.classList.remove('active');
263
- this.mainNavElement.classList.remove('closing');
254
+ if (propertyName !== 'transform') return;
255
+ this.nav.classList.remove('active');
256
+ this.nav.classList.remove('closing');
264
257
  while (this.openSubNavElements.length > 0) {
265
258
  const {
266
259
  submenu
@@ -270,8 +263,8 @@
270
263
  submenu.classList.remove('closing');
271
264
  this.openSubNavElements.pop();
272
265
  }
273
- this.mainNavElement.removeEventListener(this.transitionEvent, this.mobileHideMainTransitionEndEvent, false);
274
- this.mainNavElement.removeEventListener('keydown', this.mobileTrapTabKeyEvent, false);
266
+ this.nav.removeEventListener(this.transitionEvent, this.mobileHideMainTransitionEndEvent, false);
267
+ this.nav.removeEventListener('keydown', this.mobileTrapTabKeyEvent, false);
275
268
  }
276
269
  mobileToggleMainNav(e) {
277
270
  const {
@@ -279,29 +272,29 @@
279
272
  } = e;
280
273
  const isExpanded = currentTarget.getAttribute('aria-expanded') === 'true';
281
274
  if (isExpanded) {
282
- this.body.classList.remove('main-nav-active');
275
+ document.body.classList.remove('main-nav-active');
283
276
  this.openNavButton.focus();
284
- this.mainNavElement.classList.add('closing');
285
- this.mainNavElement.addEventListener(this.transitionEvent, this.mobileHideMainTransitionEndEvent, false);
277
+ this.nav.classList.add('closing');
278
+ this.nav.addEventListener(this.transitionEvent, this.mobileHideMainTransitionEndEvent, false);
286
279
  } else {
287
- this.body.classList.add('main-nav-active');
288
- this.mainNavElement.classList.add('activating');
289
- this.mainNavElement.addEventListener(this.transitionEvent, this.mobileShowMainTransitionEndEvent, false);
280
+ document.body.classList.add('main-nav-active');
281
+ this.nav.classList.add('activating');
282
+ this.nav.addEventListener(this.transitionEvent, this.mobileShowMainTransitionEndEvent, false);
290
283
  }
291
284
  }
292
- buttonClickDesktop(e) {
285
+ buttonClickDesktop(event) {
293
286
  const isDesktop = this.breakpoint.matches;
294
- if (!isDesktop || !e.target.closest('.nsw-main-nav__sub-nav')) {
295
- this.saveElements(e);
287
+ if (!isDesktop || !event.target.closest('.nsw-main-nav__sub-nav')) {
288
+ this.saveElements(event);
296
289
  this.toggleSubNavDesktop();
297
- e.preventDefault();
290
+ event.preventDefault();
298
291
  }
299
292
  }
300
- buttonKeydownDesktop(e) {
301
- if (e.key === ' ' || e.key === 'Enter' || e.key === 'Spacebar') {
302
- this.saveElements(e);
293
+ buttonKeydownDesktop(event) {
294
+ if (event.key === ' ' || event.key === 'Enter' || event.key === 'Spacebar') {
295
+ this.saveElements(event);
303
296
  this.toggleSubNavDesktop();
304
- e.preventDefault();
297
+ event.preventDefault();
305
298
  }
306
299
  }
307
300
  escapeClose(e) {
@@ -335,7 +328,7 @@
335
328
  const {
336
329
  submenu
337
330
  } = this.whichSubNavLatest();
338
- if (!propertyName === 'transform') return;
331
+ if (propertyName !== 'transform') return;
339
332
  getFocusableElementBySelector(submenu.id, ['> div button', '> .nsw-main-nav__title a', '> ul > li > a']).all[2].focus();
340
333
  submenu.removeEventListener(this.transitionEvent, this.showSubNavTransitionEndEvent, false);
341
334
  }
@@ -347,9 +340,9 @@
347
340
  if (this.breakpoint.matches) {
348
341
  link.setAttribute('aria-expanded', false);
349
342
  link.classList.remove('active');
350
- this.mainNavElement.removeEventListener('focus', this.checkFocusEvent, true);
343
+ this.nav.removeEventListener('focus', this.checkFocusEvent, true);
351
344
  // fix: workaround for safari because it doesn't support focus event
352
- this.mainNavElement.removeEventListener('click', this.checkFocusEvent, true);
345
+ this.nav.removeEventListener('click', this.checkFocusEvent, true);
353
346
  } else {
354
347
  link.focus();
355
348
  submenu.removeEventListener('keydown', this.mobileSubNavTrapTabKeyEvent, false);
@@ -366,9 +359,9 @@
366
359
  if (this.breakpoint.matches) {
367
360
  link.setAttribute('aria-expanded', true);
368
361
  link.classList.add('active');
369
- this.mainNavElement.addEventListener('focus', this.checkFocusEvent, true);
362
+ this.nav.addEventListener('focus', this.checkFocusEvent, true);
370
363
  // fix: workaround for safari because it doesn't support focus event
371
- this.mainNavElement.addEventListener('click', this.checkFocusEvent, true);
364
+ this.nav.addEventListener('click', this.checkFocusEvent, true);
372
365
  } else {
373
366
  submenu.addEventListener('keydown', this.mobileSubNavTrapTabKeyEvent, false);
374
367
  submenu.addEventListener(this.transitionEvent, this.showSubNavTransitionEndEvent, false);
@@ -383,8 +376,10 @@
383
376
  } = this.whichSubNavLatest();
384
377
  const isExpanded = link.getAttribute('aria-expanded') === 'true';
385
378
  if (isExpanded) {
379
+ this.mainNavIsOpen = false;
386
380
  this.closeSubNav();
387
381
  } else {
382
+ this.mainNavIsOpen = true;
388
383
  this.openSubNav();
389
384
  }
390
385
  }
@@ -592,7 +587,7 @@
592
587
  this.filtersItems = element.querySelectorAll('.nsw-filters__item');
593
588
  /* eslint-disable max-len */
594
589
  this.focusableEls = this.filtersWrapper.querySelectorAll('a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled])');
595
- this.checkIcon = '<span class="material-icons nsw-material-icons" focusable="false" aria-hidden="true">check_circle</span>';
590
+ this.checkIcon = '<span class="material-icons nsw-material-icons nsw-material-icons--valid" focusable="false" aria-hidden="true">check_circle</span>';
596
591
  this.arrowIcon = '<span class="material-icons nsw-material-icons" focusable="false" aria-hidden="true">keyboard_arrow_right</span>';
597
592
  /* eslint-ensable max-len */
598
593
  this.showEvent = e => this.showFilters(e);
@@ -3188,6 +3183,7 @@
3188
3183
  // Header Search
3189
3184
  const openSearchButton = document.querySelectorAll('.js-open-search');
3190
3185
  const closeSearchButton = document.querySelectorAll('.js-close-search');
3186
+ const navigation = document.getElementById('main-nav');
3191
3187
  const accordions = document.querySelectorAll('.js-accordion');
3192
3188
  const dialogs = document.querySelectorAll('.js-dialog');
3193
3189
  const fileUpload = document.querySelectorAll('.js-file-upload');
@@ -3204,9 +3200,9 @@
3204
3200
  closeSearchButton.forEach(element => {
3205
3201
  new SiteSearch(element).init();
3206
3202
  });
3207
-
3208
- // Navigation
3209
- new Navigation().init();
3203
+ if (navigation) {
3204
+ new Navigation(navigation).init();
3205
+ }
3210
3206
  accordions.forEach(element => {
3211
3207
  new Accordion(element).init();
3212
3208
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nsw-design-system",
3
- "version": "3.9.0",
3
+ "version": "3.9.2",
4
4
  "description": "Design system for Digital NSW",
5
5
  "main": "dist/main.js",
6
6
  "style": "dist/main.css",
@@ -368,19 +368,26 @@
368
368
  span:not(.nsw-material-icons) {
369
369
  display: flex;
370
370
  align-items: center;
371
- padding: 0;
371
+ }
372
372
 
373
- .nsw-material-icons:last-child {
374
- font-size: rem(map-get($nsw-icon-sizes, 20));
375
- background-color: var(--nsw-white);
373
+ .nsw-material-icons {
374
+ font-size: rem(map-get($nsw-icon-sizes, 20));
375
+ margin-left: rem(8px);
376
+ border-radius: 50%;
377
+ width: rem(16px);
378
+ height: rem(16px);
379
+ display: flex;
380
+ justify-content: center;
381
+ align-items: center;
382
+
383
+ &--error {
384
+ background-color: var(--nsw-status-error-bg);
385
+ color: var(--nsw-status-error);
386
+ }
387
+
388
+ &--valid {
389
+ background-color: var(--nsw-status-success-bg);
376
390
  color: var(--nsw-status-success);
377
- margin-left: rem(8px);
378
- border-radius: 50%;
379
- width: rem(16px);
380
- height: rem(16px);
381
- display: flex;
382
- justify-content: center;
383
- align-items: center;
384
391
  }
385
392
  }
386
393
 
@@ -19,7 +19,7 @@ class Filters {
19
19
  this.filtersItems = element.querySelectorAll('.nsw-filters__item')
20
20
  /* eslint-disable max-len */
21
21
  this.focusableEls = this.filtersWrapper.querySelectorAll('a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled])')
22
- this.checkIcon = '<span class="material-icons nsw-material-icons" focusable="false" aria-hidden="true">check_circle</span>'
22
+ this.checkIcon = '<span class="material-icons nsw-material-icons nsw-material-icons--valid" focusable="false" aria-hidden="true">check_circle</span>'
23
23
  this.arrowIcon = '<span class="material-icons nsw-material-icons" focusable="false" aria-hidden="true">keyboard_arrow_right</span>'
24
24
  /* eslint-ensable max-len */
25
25
  this.showEvent = (e) => this.showFilters(e)
@@ -81,6 +81,14 @@
81
81
  position: relative;
82
82
  }
83
83
 
84
+ > li {
85
+ @include breakpoint($nsw-desktop-breakpoint) {
86
+ &.active {
87
+ box-shadow: inset 0 -4px 0 var(--nsw-brand-dark);
88
+ }
89
+ }
90
+ }
91
+
84
92
  > li > a {
85
93
  @include breakpoint($nsw-desktop-breakpoint) {
86
94
  .nsw-material-icons {
@@ -90,6 +98,7 @@
90
98
 
91
99
  &.active {
92
100
  background-color: var(--nsw-white);
101
+ box-shadow: inset 0 -4px 0 var(--nsw-brand-dark);
93
102
  }
94
103
 
95
104
  &.active .nsw-material-icons {
@@ -261,7 +270,7 @@
261
270
  }
262
271
 
263
272
  &:nth-last-child(-n+3) {
264
- border-bottom: solid 1px var(--nsw-grey-04);
273
+ box-shadow: inset 0 -1px 0 var(--nsw-grey-04);
265
274
  }
266
275
 
267
276
  a {
@@ -3,16 +3,15 @@ import {
3
3
  } from '../../global/scripts/helpers/utilities'
4
4
 
5
5
  class Navigation {
6
- constructor() {
6
+ constructor(element) {
7
+ this.nav = element
8
+ this.navID = this.nav.id
7
9
  this.openNavButton = document.querySelector('.js-open-nav')
8
- this.closeNavButtons = document.querySelectorAll('.js-close-nav')
9
- this.openSubNavButtons = document.querySelectorAll('.js-open-sub-nav')
10
- this.closeSubNavButtons = document.querySelectorAll('.js-close-sub-nav')
11
- this.mainNavElement = document.getElementById('main-nav')
12
- this.isMegaMenuElement = !!document.querySelector('.js-mega-menu')
10
+ this.closeNavButtons = this.nav.querySelectorAll('.js-close-nav')
11
+ this.closeSubNavButtons = this.nav.querySelectorAll('.js-close-sub-nav')
12
+ this.isMegaMenuElement = this.nav.classList.contains('js-mega-menu')
13
+ this.mainNavIsOpen = false
13
14
  this.transitionEvent = whichTransitionEvent()
14
- this.mobileToggleMainNavEvent = (e) => this.mobileToggleMainNav(e)
15
- this.mobileToggleSubNavEvent = () => this.closeSubNav()
16
15
  this.mobileShowMainTransitionEndEvent = (e) => this.mobileShowMainNav(e)
17
16
  this.mobileHideMainTransitionEndEvent = (e) => this.mobileHideMainNav(e)
18
17
  this.showSubNavTransitionEndEvent = (e) => this.showSubNav(e)
@@ -21,55 +20,64 @@ class Navigation {
21
20
  this.desktopButtonClickEvent = (e) => this.buttonClickDesktop(e)
22
21
  this.desktopButtonKeydownEvent = (e) => this.buttonKeydownDesktop(e)
23
22
  this.checkFocusEvent = (e) => this.checkIfContainsFocus(e)
24
- this.escapeCloseEvent = (e) => this.escapeClose(e)
25
- this.outsideClickEvent = (e) => this.handleOutsideClick(e)
26
23
  this.openSubNavElements = []
27
24
  this.breakpoint = window.matchMedia('(min-width: 62em)')
28
- this.body = document.body
29
25
  }
30
26
 
31
27
  init() {
32
- if (this.mainNavElement) {
33
- this.setUpMobileControls()
34
- this.responsiveCheck(this.breakpoint)
35
- this.breakpoint.addListener((e) => this.responsiveCheck(e))
36
- this.addOutsideClickListener()
28
+ this.initEvents()
29
+ this.responsiveCheck(this.breakpoint)
30
+
31
+ if (this.nav) {
32
+ this.breakpoint.addEventListener('change', (event) => this.responsiveCheck(event))
37
33
  }
38
34
  }
39
35
 
40
- addOutsideClickListener() {
41
- document.addEventListener('click', this.outsideClickEvent, false)
42
- }
36
+ initEvents() {
37
+ if (this.isMegaMenuElement) {
38
+ document.addEventListener('click', this.handleOutsideClick.bind(this), false)
39
+ document.addEventListener('keydown', this.escapeClose.bind(this), false)
40
+ }
43
41
 
44
- removeOutsideClickListener() {
45
- document.removeEventListener('click', this.outsideClickEvent, false)
46
- }
42
+ this.openNavButton.addEventListener('click', this.mobileToggleMainNav.bind(this), false)
47
43
 
48
- handleOutsideClick(event) {
49
- const isOutsideNav = !this.mainNavElement.contains(event.target)
44
+ this.closeNavButtons.forEach((element) => {
45
+ element.addEventListener('click', this.mobileToggleMainNav.bind(this), false)
46
+ })
50
47
 
51
- if (isOutsideNav) {
52
- this.saveElements(event)
53
- this.toggleSubNavDesktop(true)
54
- event.preventDefault()
55
- }
48
+ this.closeSubNavButtons.forEach((element) => {
49
+ element.addEventListener('click', this.closeSubNav.bind(this), false)
50
+ })
56
51
  }
57
52
 
58
- responsiveCheck(e) {
53
+ responsiveCheck(event) {
59
54
  let megaMenuListItems = []
60
- if (e.matches) {
61
- megaMenuListItems = [].slice.call(this.mainNavElement.querySelectorAll('ul > li'))
62
- this.body.classList.remove('main-nav-active')
55
+ if (event.matches) {
56
+ megaMenuListItems = [].slice.call(this.nav.querySelectorAll('ul > li'))
57
+ document.body.classList.remove('main-nav-active')
63
58
  } else {
64
- megaMenuListItems = [].slice.call(this.mainNavElement.querySelectorAll('li'))
59
+ megaMenuListItems = [].slice.call(this.nav.querySelectorAll('li'))
65
60
  }
66
61
  this.tearDownNavControls()
67
62
  this.setUpNavControls(megaMenuListItems)
68
63
  }
69
64
 
65
+ handleOutsideClick(event) {
66
+ // removes handleOutsideClick functionality from docs site
67
+ if (this.nav.closest('.nsw-docs')) return
68
+
69
+ if (!this.mainNavIsOpen) return
70
+
71
+ const isOutsideNav = !this.nav.contains(event.target)
72
+
73
+ if (isOutsideNav) {
74
+ this.toggleSubNavDesktop(true)
75
+ }
76
+ }
77
+
70
78
  tearDownNavControls() {
71
79
  if (this.isMegaMenuElement) {
72
- const listItems = [].slice.call(this.mainNavElement.querySelectorAll('li'))
80
+ const listItems = [].slice.call(this.nav.querySelectorAll('li'))
73
81
  listItems.forEach((item) => {
74
82
  const submenu = item.querySelector('[id^=sub-nav-]')
75
83
  const link = item.querySelector('a')
@@ -84,23 +92,6 @@ class Navigation {
84
92
  }
85
93
  }
86
94
 
87
- setUpMobileControls() {
88
- this.openNavButton.addEventListener('click', this.mobileToggleMainNavEvent, false)
89
-
90
- this.closeNavButtons.forEach((element) => {
91
- element.addEventListener('click', this.mobileToggleMainNavEvent, false)
92
- })
93
-
94
- this.closeSubNavButtons.forEach((element) => {
95
- element.addEventListener('click', this.mobileToggleSubNavEvent, false)
96
- })
97
- }
98
-
99
- mobileMainNavTrapTabs(e) {
100
- const elemObj = getFocusableElementBySelector(this.mainNavElement.id, ['> div button', '> ul > li > a'])
101
- trapTabKey(e, elemObj)
102
- }
103
-
104
95
  setUpNavControls(listItems) {
105
96
  if (this.isMegaMenuElement) {
106
97
  listItems.forEach((item) => {
@@ -112,26 +103,31 @@ class Navigation {
112
103
  link.setAttribute('aria-controls', submenu.id)
113
104
  link.addEventListener('click', this.desktopButtonClickEvent, false)
114
105
  link.addEventListener('keydown', this.desktopButtonKeydownEvent, false)
115
- document.addEventListener('keydown', this.escapeCloseEvent, false)
116
106
  }
117
107
  })
118
108
  }
119
109
  }
120
110
 
111
+ mobileMainNavTrapTabs(e) {
112
+ const elemObj = getFocusableElementBySelector(this.navID, ['> div button', '> ul > li > a'])
113
+ trapTabKey(e, elemObj)
114
+ }
115
+
121
116
  mobileShowMainNav({ propertyName }) {
122
- if (!propertyName === 'transform') return
123
- getFocusableElementBySelector(this.mainNavElement.id, ['> div button', '> ul > li > a']).all[1].focus()
124
- this.mainNavElement.classList.add('active')
125
- this.mainNavElement.classList.remove('activating')
126
- this.mainNavElement.removeEventListener(this.transitionEvent, this.mobileShowMainTransitionEndEvent, false)
127
- this.mainNavElement.addEventListener('keydown', this.mobileTrapTabKeyEvent, false)
117
+ if (propertyName !== 'transform') return
118
+ getFocusableElementBySelector(this.navID, ['> div button', '> ul > li > a']).all[1].focus()
119
+ this.nav.classList.add('active')
120
+ this.nav.classList.remove('activating')
121
+ this.nav.removeEventListener(this.transitionEvent, this.mobileShowMainTransitionEndEvent, false)
122
+ this.nav.addEventListener('keydown', this.mobileTrapTabKeyEvent, false)
128
123
  }
129
124
 
130
125
  mobileHideMainNav({ propertyName }) {
131
- if (!propertyName === 'transform') return
126
+ if (propertyName !== 'transform') return
127
+
128
+ this.nav.classList.remove('active')
129
+ this.nav.classList.remove('closing')
132
130
 
133
- this.mainNavElement.classList.remove('active')
134
- this.mainNavElement.classList.remove('closing')
135
131
  while (this.openSubNavElements.length > 0) {
136
132
  const { submenu } = this.whichSubNavLatest()
137
133
  submenu.removeEventListener('keydown', this.mobileSubNavTrapTabKeyEvent, false)
@@ -139,39 +135,40 @@ class Navigation {
139
135
  submenu.classList.remove('closing')
140
136
  this.openSubNavElements.pop()
141
137
  }
142
- this.mainNavElement.removeEventListener(this.transitionEvent, this.mobileHideMainTransitionEndEvent, false)
143
- this.mainNavElement.removeEventListener('keydown', this.mobileTrapTabKeyEvent, false)
138
+
139
+ this.nav.removeEventListener(this.transitionEvent, this.mobileHideMainTransitionEndEvent, false)
140
+ this.nav.removeEventListener('keydown', this.mobileTrapTabKeyEvent, false)
144
141
  }
145
142
 
146
143
  mobileToggleMainNav(e) {
147
144
  const { currentTarget } = e
148
145
  const isExpanded = currentTarget.getAttribute('aria-expanded') === 'true'
149
146
  if (isExpanded) {
150
- this.body.classList.remove('main-nav-active')
147
+ document.body.classList.remove('main-nav-active')
151
148
  this.openNavButton.focus()
152
- this.mainNavElement.classList.add('closing')
153
- this.mainNavElement.addEventListener(this.transitionEvent, this.mobileHideMainTransitionEndEvent, false)
149
+ this.nav.classList.add('closing')
150
+ this.nav.addEventListener(this.transitionEvent, this.mobileHideMainTransitionEndEvent, false)
154
151
  } else {
155
- this.body.classList.add('main-nav-active')
156
- this.mainNavElement.classList.add('activating')
157
- this.mainNavElement.addEventListener(this.transitionEvent, this.mobileShowMainTransitionEndEvent, false)
152
+ document.body.classList.add('main-nav-active')
153
+ this.nav.classList.add('activating')
154
+ this.nav.addEventListener(this.transitionEvent, this.mobileShowMainTransitionEndEvent, false)
158
155
  }
159
156
  }
160
157
 
161
- buttonClickDesktop(e) {
158
+ buttonClickDesktop(event) {
162
159
  const isDesktop = this.breakpoint.matches
163
- if (!isDesktop || !e.target.closest('.nsw-main-nav__sub-nav')) {
164
- this.saveElements(e)
160
+ if (!isDesktop || !event.target.closest('.nsw-main-nav__sub-nav')) {
161
+ this.saveElements(event)
165
162
  this.toggleSubNavDesktop()
166
- e.preventDefault()
163
+ event.preventDefault()
167
164
  }
168
165
  }
169
166
 
170
- buttonKeydownDesktop(e) {
171
- if (e.key === ' ' || e.key === 'Enter' || e.key === 'Spacebar') {
172
- this.saveElements(e)
167
+ buttonKeydownDesktop(event) {
168
+ if (event.key === ' ' || event.key === 'Enter' || event.key === 'Spacebar') {
169
+ this.saveElements(event)
173
170
  this.toggleSubNavDesktop()
174
- e.preventDefault()
171
+ event.preventDefault()
175
172
  }
176
173
  }
177
174
 
@@ -200,7 +197,7 @@ class Navigation {
200
197
 
201
198
  showSubNav({ propertyName }) {
202
199
  const { submenu } = this.whichSubNavLatest()
203
- if (!propertyName === 'transform') return
200
+ if (propertyName !== 'transform') return
204
201
  getFocusableElementBySelector(submenu.id, ['> div button', '> .nsw-main-nav__title a', '> ul > li > a']).all[2].focus()
205
202
  submenu.removeEventListener(this.transitionEvent, this.showSubNavTransitionEndEvent, false)
206
203
  }
@@ -210,9 +207,9 @@ class Navigation {
210
207
  if (this.breakpoint.matches) {
211
208
  link.setAttribute('aria-expanded', false)
212
209
  link.classList.remove('active')
213
- this.mainNavElement.removeEventListener('focus', this.checkFocusEvent, true)
210
+ this.nav.removeEventListener('focus', this.checkFocusEvent, true)
214
211
  // fix: workaround for safari because it doesn't support focus event
215
- this.mainNavElement.removeEventListener('click', this.checkFocusEvent, true)
212
+ this.nav.removeEventListener('click', this.checkFocusEvent, true)
216
213
  } else {
217
214
  link.focus()
218
215
  submenu.removeEventListener('keydown', this.mobileSubNavTrapTabKeyEvent, false)
@@ -227,9 +224,9 @@ class Navigation {
227
224
  if (this.breakpoint.matches) {
228
225
  link.setAttribute('aria-expanded', true)
229
226
  link.classList.add('active')
230
- this.mainNavElement.addEventListener('focus', this.checkFocusEvent, true)
227
+ this.nav.addEventListener('focus', this.checkFocusEvent, true)
231
228
  // fix: workaround for safari because it doesn't support focus event
232
- this.mainNavElement.addEventListener('click', this.checkFocusEvent, true)
229
+ this.nav.addEventListener('click', this.checkFocusEvent, true)
233
230
  } else {
234
231
  submenu.addEventListener('keydown', this.mobileSubNavTrapTabKeyEvent, false)
235
232
  submenu.addEventListener(this.transitionEvent, this.showSubNavTransitionEndEvent, false)
@@ -243,8 +240,10 @@ class Navigation {
243
240
  const { link } = this.whichSubNavLatest()
244
241
  const isExpanded = link.getAttribute('aria-expanded') === 'true'
245
242
  if (isExpanded) {
243
+ this.mainNavIsOpen = false
246
244
  this.closeSubNav()
247
245
  } else {
246
+ this.mainNavIsOpen = true
248
247
  this.openSubNav()
249
248
  }
250
249
  }