nsw-design-system 3.9.1 → 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/css/main.css +1 -1
- package/dist/js/main.js +75 -81
- package/package.json +1 -1
- package/src/components/filters/_filters.scss +18 -11
- package/src/components/filters/filters.js +1 -1
- package/src/components/main-nav/_main-nav.scss +10 -1
- package/src/components/main-nav/main-nav.js +78 -82
- package/src/main.js +4 -2
package/dist/js/main.js
CHANGED
|
@@ -141,17 +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 =
|
|
147
|
-
this.
|
|
148
|
-
this.
|
|
149
|
-
this.mainNavElement = document.getElementById('main-nav');
|
|
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');
|
|
150
151
|
this.mainNavIsOpen = false;
|
|
151
|
-
this.isMegaMenuElement = !!document.querySelector('.js-mega-menu');
|
|
152
152
|
this.transitionEvent = whichTransitionEvent();
|
|
153
|
-
this.mobileToggleMainNavEvent = e => this.mobileToggleMainNav(e);
|
|
154
|
-
this.mobileToggleSubNavEvent = () => this.closeSubNav();
|
|
155
153
|
this.mobileShowMainTransitionEndEvent = e => this.mobileShowMainNav(e);
|
|
156
154
|
this.mobileHideMainTransitionEndEvent = e => this.mobileHideMainNav(e);
|
|
157
155
|
this.showSubNavTransitionEndEvent = e => this.showSubNav(e);
|
|
@@ -160,47 +158,52 @@
|
|
|
160
158
|
this.desktopButtonClickEvent = e => this.buttonClickDesktop(e);
|
|
161
159
|
this.desktopButtonKeydownEvent = e => this.buttonKeydownDesktop(e);
|
|
162
160
|
this.checkFocusEvent = e => this.checkIfContainsFocus(e);
|
|
163
|
-
this.escapeCloseEvent = e => this.escapeClose(e);
|
|
164
|
-
this.outsideClickEvent = e => this.handleOutsideClick(e);
|
|
165
161
|
this.openSubNavElements = [];
|
|
166
162
|
this.breakpoint = window.matchMedia('(min-width: 62em)');
|
|
167
|
-
this.body = document.body;
|
|
168
163
|
}
|
|
169
164
|
init() {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this.breakpoint.
|
|
174
|
-
this.addOutsideClickListener();
|
|
165
|
+
this.initEvents();
|
|
166
|
+
this.responsiveCheck(this.breakpoint);
|
|
167
|
+
if (this.nav) {
|
|
168
|
+
this.breakpoint.addEventListener('change', event => this.responsiveCheck(event));
|
|
175
169
|
}
|
|
176
170
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
document.removeEventListener('click', this.outsideClickEvent, false);
|
|
182
|
-
}
|
|
183
|
-
handleOutsideClick(event) {
|
|
184
|
-
if (!this.mainNavIsOpen) return;
|
|
185
|
-
const isOutsideNav = !this.mainNavElement.contains(event.target);
|
|
186
|
-
if (isOutsideNav) {
|
|
187
|
-
this.toggleSubNavDesktop(true);
|
|
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(
|
|
184
|
+
responsiveCheck(event) {
|
|
191
185
|
let megaMenuListItems = [];
|
|
192
|
-
if (
|
|
193
|
-
megaMenuListItems = [].slice.call(this.
|
|
194
|
-
|
|
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.
|
|
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.
|
|
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 (
|
|
251
|
-
getFocusableElementBySelector(this.
|
|
252
|
-
this.
|
|
253
|
-
this.
|
|
254
|
-
this.
|
|
255
|
-
this.
|
|
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 (
|
|
262
|
-
this.
|
|
263
|
-
this.
|
|
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.
|
|
274
|
-
this.
|
|
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
|
-
|
|
275
|
+
document.body.classList.remove('main-nav-active');
|
|
283
276
|
this.openNavButton.focus();
|
|
284
|
-
this.
|
|
285
|
-
this.
|
|
277
|
+
this.nav.classList.add('closing');
|
|
278
|
+
this.nav.addEventListener(this.transitionEvent, this.mobileHideMainTransitionEndEvent, false);
|
|
286
279
|
} else {
|
|
287
|
-
|
|
288
|
-
this.
|
|
289
|
-
this.
|
|
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(
|
|
285
|
+
buttonClickDesktop(event) {
|
|
293
286
|
const isDesktop = this.breakpoint.matches;
|
|
294
|
-
if (!isDesktop || !
|
|
295
|
-
this.saveElements(
|
|
287
|
+
if (!isDesktop || !event.target.closest('.nsw-main-nav__sub-nav')) {
|
|
288
|
+
this.saveElements(event);
|
|
296
289
|
this.toggleSubNavDesktop();
|
|
297
|
-
|
|
290
|
+
event.preventDefault();
|
|
298
291
|
}
|
|
299
292
|
}
|
|
300
|
-
buttonKeydownDesktop(
|
|
301
|
-
if (
|
|
302
|
-
this.saveElements(
|
|
293
|
+
buttonKeydownDesktop(event) {
|
|
294
|
+
if (event.key === ' ' || event.key === 'Enter' || event.key === 'Spacebar') {
|
|
295
|
+
this.saveElements(event);
|
|
303
296
|
this.toggleSubNavDesktop();
|
|
304
|
-
|
|
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 (
|
|
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.
|
|
343
|
+
this.nav.removeEventListener('focus', this.checkFocusEvent, true);
|
|
351
344
|
// fix: workaround for safari because it doesn't support focus event
|
|
352
|
-
this.
|
|
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.
|
|
362
|
+
this.nav.addEventListener('focus', this.checkFocusEvent, true);
|
|
370
363
|
// fix: workaround for safari because it doesn't support focus event
|
|
371
|
-
this.
|
|
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);
|
|
@@ -594,7 +587,7 @@
|
|
|
594
587
|
this.filtersItems = element.querySelectorAll('.nsw-filters__item');
|
|
595
588
|
/* eslint-disable max-len */
|
|
596
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])');
|
|
597
|
-
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>';
|
|
598
591
|
this.arrowIcon = '<span class="material-icons nsw-material-icons" focusable="false" aria-hidden="true">keyboard_arrow_right</span>';
|
|
599
592
|
/* eslint-ensable max-len */
|
|
600
593
|
this.showEvent = e => this.showFilters(e);
|
|
@@ -3190,6 +3183,7 @@
|
|
|
3190
3183
|
// Header Search
|
|
3191
3184
|
const openSearchButton = document.querySelectorAll('.js-open-search');
|
|
3192
3185
|
const closeSearchButton = document.querySelectorAll('.js-close-search');
|
|
3186
|
+
const navigation = document.getElementById('main-nav');
|
|
3193
3187
|
const accordions = document.querySelectorAll('.js-accordion');
|
|
3194
3188
|
const dialogs = document.querySelectorAll('.js-dialog');
|
|
3195
3189
|
const fileUpload = document.querySelectorAll('.js-file-upload');
|
|
@@ -3206,9 +3200,9 @@
|
|
|
3206
3200
|
closeSearchButton.forEach(element => {
|
|
3207
3201
|
new SiteSearch(element).init();
|
|
3208
3202
|
});
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3203
|
+
if (navigation) {
|
|
3204
|
+
new Navigation(navigation).init();
|
|
3205
|
+
}
|
|
3212
3206
|
accordions.forEach(element => {
|
|
3213
3207
|
new Accordion(element).init();
|
|
3214
3208
|
});
|
package/package.json
CHANGED
|
@@ -368,19 +368,26 @@
|
|
|
368
368
|
span:not(.nsw-material-icons) {
|
|
369
369
|
display: flex;
|
|
370
370
|
align-items: center;
|
|
371
|
-
|
|
371
|
+
}
|
|
372
372
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
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
|
-
|
|
273
|
+
box-shadow: inset 0 -1px 0 var(--nsw-grey-04);
|
|
265
274
|
}
|
|
266
275
|
|
|
267
276
|
a {
|
|
@@ -3,17 +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 =
|
|
9
|
-
this.
|
|
10
|
-
this.
|
|
11
|
-
this.mainNavElement = document.getElementById('main-nav')
|
|
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')
|
|
12
13
|
this.mainNavIsOpen = false
|
|
13
|
-
this.isMegaMenuElement = !!document.querySelector('.js-mega-menu')
|
|
14
14
|
this.transitionEvent = whichTransitionEvent()
|
|
15
|
-
this.mobileToggleMainNavEvent = (e) => this.mobileToggleMainNav(e)
|
|
16
|
-
this.mobileToggleSubNavEvent = () => this.closeSubNav()
|
|
17
15
|
this.mobileShowMainTransitionEndEvent = (e) => this.mobileShowMainNav(e)
|
|
18
16
|
this.mobileHideMainTransitionEndEvent = (e) => this.mobileHideMainNav(e)
|
|
19
17
|
this.showSubNavTransitionEndEvent = (e) => this.showSubNav(e)
|
|
@@ -22,55 +20,64 @@ class Navigation {
|
|
|
22
20
|
this.desktopButtonClickEvent = (e) => this.buttonClickDesktop(e)
|
|
23
21
|
this.desktopButtonKeydownEvent = (e) => this.buttonKeydownDesktop(e)
|
|
24
22
|
this.checkFocusEvent = (e) => this.checkIfContainsFocus(e)
|
|
25
|
-
this.escapeCloseEvent = (e) => this.escapeClose(e)
|
|
26
|
-
this.outsideClickEvent = (e) => this.handleOutsideClick(e)
|
|
27
23
|
this.openSubNavElements = []
|
|
28
24
|
this.breakpoint = window.matchMedia('(min-width: 62em)')
|
|
29
|
-
this.body = document.body
|
|
30
25
|
}
|
|
31
26
|
|
|
32
27
|
init() {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
this.
|
|
28
|
+
this.initEvents()
|
|
29
|
+
this.responsiveCheck(this.breakpoint)
|
|
30
|
+
|
|
31
|
+
if (this.nav) {
|
|
32
|
+
this.breakpoint.addEventListener('change', (event) => this.responsiveCheck(event))
|
|
38
33
|
}
|
|
39
34
|
}
|
|
40
35
|
|
|
41
|
-
|
|
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
|
+
}
|
|
41
|
+
|
|
42
|
+
this.openNavButton.addEventListener('click', this.mobileToggleMainNav.bind(this), false)
|
|
43
|
+
|
|
44
|
+
this.closeNavButtons.forEach((element) => {
|
|
45
|
+
element.addEventListener('click', this.mobileToggleMainNav.bind(this), false)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
this.closeSubNavButtons.forEach((element) => {
|
|
49
|
+
element.addEventListener('click', this.closeSubNav.bind(this), false)
|
|
50
|
+
})
|
|
43
51
|
}
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
responsiveCheck(event) {
|
|
54
|
+
let megaMenuListItems = []
|
|
55
|
+
if (event.matches) {
|
|
56
|
+
megaMenuListItems = [].slice.call(this.nav.querySelectorAll('ul > li'))
|
|
57
|
+
document.body.classList.remove('main-nav-active')
|
|
58
|
+
} else {
|
|
59
|
+
megaMenuListItems = [].slice.call(this.nav.querySelectorAll('li'))
|
|
60
|
+
}
|
|
61
|
+
this.tearDownNavControls()
|
|
62
|
+
this.setUpNavControls(megaMenuListItems)
|
|
47
63
|
}
|
|
48
64
|
|
|
49
65
|
handleOutsideClick(event) {
|
|
66
|
+
// removes handleOutsideClick functionality from docs site
|
|
67
|
+
if (this.nav.closest('.nsw-docs')) return
|
|
68
|
+
|
|
50
69
|
if (!this.mainNavIsOpen) return
|
|
51
70
|
|
|
52
|
-
const isOutsideNav = !this.
|
|
71
|
+
const isOutsideNav = !this.nav.contains(event.target)
|
|
53
72
|
|
|
54
73
|
if (isOutsideNav) {
|
|
55
74
|
this.toggleSubNavDesktop(true)
|
|
56
75
|
}
|
|
57
76
|
}
|
|
58
77
|
|
|
59
|
-
responsiveCheck(e) {
|
|
60
|
-
let megaMenuListItems = []
|
|
61
|
-
if (e.matches) {
|
|
62
|
-
megaMenuListItems = [].slice.call(this.mainNavElement.querySelectorAll('ul > li'))
|
|
63
|
-
this.body.classList.remove('main-nav-active')
|
|
64
|
-
} else {
|
|
65
|
-
megaMenuListItems = [].slice.call(this.mainNavElement.querySelectorAll('li'))
|
|
66
|
-
}
|
|
67
|
-
this.tearDownNavControls()
|
|
68
|
-
this.setUpNavControls(megaMenuListItems)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
78
|
tearDownNavControls() {
|
|
72
79
|
if (this.isMegaMenuElement) {
|
|
73
|
-
const listItems = [].slice.call(this.
|
|
80
|
+
const listItems = [].slice.call(this.nav.querySelectorAll('li'))
|
|
74
81
|
listItems.forEach((item) => {
|
|
75
82
|
const submenu = item.querySelector('[id^=sub-nav-]')
|
|
76
83
|
const link = item.querySelector('a')
|
|
@@ -85,23 +92,6 @@ class Navigation {
|
|
|
85
92
|
}
|
|
86
93
|
}
|
|
87
94
|
|
|
88
|
-
setUpMobileControls() {
|
|
89
|
-
this.openNavButton.addEventListener('click', this.mobileToggleMainNavEvent, false)
|
|
90
|
-
|
|
91
|
-
this.closeNavButtons.forEach((element) => {
|
|
92
|
-
element.addEventListener('click', this.mobileToggleMainNavEvent, false)
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
this.closeSubNavButtons.forEach((element) => {
|
|
96
|
-
element.addEventListener('click', this.mobileToggleSubNavEvent, false)
|
|
97
|
-
})
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
mobileMainNavTrapTabs(e) {
|
|
101
|
-
const elemObj = getFocusableElementBySelector(this.mainNavElement.id, ['> div button', '> ul > li > a'])
|
|
102
|
-
trapTabKey(e, elemObj)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
95
|
setUpNavControls(listItems) {
|
|
106
96
|
if (this.isMegaMenuElement) {
|
|
107
97
|
listItems.forEach((item) => {
|
|
@@ -113,26 +103,31 @@ class Navigation {
|
|
|
113
103
|
link.setAttribute('aria-controls', submenu.id)
|
|
114
104
|
link.addEventListener('click', this.desktopButtonClickEvent, false)
|
|
115
105
|
link.addEventListener('keydown', this.desktopButtonKeydownEvent, false)
|
|
116
|
-
document.addEventListener('keydown', this.escapeCloseEvent, false)
|
|
117
106
|
}
|
|
118
107
|
})
|
|
119
108
|
}
|
|
120
109
|
}
|
|
121
110
|
|
|
111
|
+
mobileMainNavTrapTabs(e) {
|
|
112
|
+
const elemObj = getFocusableElementBySelector(this.navID, ['> div button', '> ul > li > a'])
|
|
113
|
+
trapTabKey(e, elemObj)
|
|
114
|
+
}
|
|
115
|
+
|
|
122
116
|
mobileShowMainNav({ propertyName }) {
|
|
123
|
-
if (
|
|
124
|
-
getFocusableElementBySelector(this.
|
|
125
|
-
this.
|
|
126
|
-
this.
|
|
127
|
-
this.
|
|
128
|
-
this.
|
|
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)
|
|
129
123
|
}
|
|
130
124
|
|
|
131
125
|
mobileHideMainNav({ propertyName }) {
|
|
132
|
-
if (
|
|
126
|
+
if (propertyName !== 'transform') return
|
|
127
|
+
|
|
128
|
+
this.nav.classList.remove('active')
|
|
129
|
+
this.nav.classList.remove('closing')
|
|
133
130
|
|
|
134
|
-
this.mainNavElement.classList.remove('active')
|
|
135
|
-
this.mainNavElement.classList.remove('closing')
|
|
136
131
|
while (this.openSubNavElements.length > 0) {
|
|
137
132
|
const { submenu } = this.whichSubNavLatest()
|
|
138
133
|
submenu.removeEventListener('keydown', this.mobileSubNavTrapTabKeyEvent, false)
|
|
@@ -140,39 +135,40 @@ class Navigation {
|
|
|
140
135
|
submenu.classList.remove('closing')
|
|
141
136
|
this.openSubNavElements.pop()
|
|
142
137
|
}
|
|
143
|
-
|
|
144
|
-
this.
|
|
138
|
+
|
|
139
|
+
this.nav.removeEventListener(this.transitionEvent, this.mobileHideMainTransitionEndEvent, false)
|
|
140
|
+
this.nav.removeEventListener('keydown', this.mobileTrapTabKeyEvent, false)
|
|
145
141
|
}
|
|
146
142
|
|
|
147
143
|
mobileToggleMainNav(e) {
|
|
148
144
|
const { currentTarget } = e
|
|
149
145
|
const isExpanded = currentTarget.getAttribute('aria-expanded') === 'true'
|
|
150
146
|
if (isExpanded) {
|
|
151
|
-
|
|
147
|
+
document.body.classList.remove('main-nav-active')
|
|
152
148
|
this.openNavButton.focus()
|
|
153
|
-
this.
|
|
154
|
-
this.
|
|
149
|
+
this.nav.classList.add('closing')
|
|
150
|
+
this.nav.addEventListener(this.transitionEvent, this.mobileHideMainTransitionEndEvent, false)
|
|
155
151
|
} else {
|
|
156
|
-
|
|
157
|
-
this.
|
|
158
|
-
this.
|
|
152
|
+
document.body.classList.add('main-nav-active')
|
|
153
|
+
this.nav.classList.add('activating')
|
|
154
|
+
this.nav.addEventListener(this.transitionEvent, this.mobileShowMainTransitionEndEvent, false)
|
|
159
155
|
}
|
|
160
156
|
}
|
|
161
157
|
|
|
162
|
-
buttonClickDesktop(
|
|
158
|
+
buttonClickDesktop(event) {
|
|
163
159
|
const isDesktop = this.breakpoint.matches
|
|
164
|
-
if (!isDesktop || !
|
|
165
|
-
this.saveElements(
|
|
160
|
+
if (!isDesktop || !event.target.closest('.nsw-main-nav__sub-nav')) {
|
|
161
|
+
this.saveElements(event)
|
|
166
162
|
this.toggleSubNavDesktop()
|
|
167
|
-
|
|
163
|
+
event.preventDefault()
|
|
168
164
|
}
|
|
169
165
|
}
|
|
170
166
|
|
|
171
|
-
buttonKeydownDesktop(
|
|
172
|
-
if (
|
|
173
|
-
this.saveElements(
|
|
167
|
+
buttonKeydownDesktop(event) {
|
|
168
|
+
if (event.key === ' ' || event.key === 'Enter' || event.key === 'Spacebar') {
|
|
169
|
+
this.saveElements(event)
|
|
174
170
|
this.toggleSubNavDesktop()
|
|
175
|
-
|
|
171
|
+
event.preventDefault()
|
|
176
172
|
}
|
|
177
173
|
}
|
|
178
174
|
|
|
@@ -201,7 +197,7 @@ class Navigation {
|
|
|
201
197
|
|
|
202
198
|
showSubNav({ propertyName }) {
|
|
203
199
|
const { submenu } = this.whichSubNavLatest()
|
|
204
|
-
if (
|
|
200
|
+
if (propertyName !== 'transform') return
|
|
205
201
|
getFocusableElementBySelector(submenu.id, ['> div button', '> .nsw-main-nav__title a', '> ul > li > a']).all[2].focus()
|
|
206
202
|
submenu.removeEventListener(this.transitionEvent, this.showSubNavTransitionEndEvent, false)
|
|
207
203
|
}
|
|
@@ -211,9 +207,9 @@ class Navigation {
|
|
|
211
207
|
if (this.breakpoint.matches) {
|
|
212
208
|
link.setAttribute('aria-expanded', false)
|
|
213
209
|
link.classList.remove('active')
|
|
214
|
-
this.
|
|
210
|
+
this.nav.removeEventListener('focus', this.checkFocusEvent, true)
|
|
215
211
|
// fix: workaround for safari because it doesn't support focus event
|
|
216
|
-
this.
|
|
212
|
+
this.nav.removeEventListener('click', this.checkFocusEvent, true)
|
|
217
213
|
} else {
|
|
218
214
|
link.focus()
|
|
219
215
|
submenu.removeEventListener('keydown', this.mobileSubNavTrapTabKeyEvent, false)
|
|
@@ -228,9 +224,9 @@ class Navigation {
|
|
|
228
224
|
if (this.breakpoint.matches) {
|
|
229
225
|
link.setAttribute('aria-expanded', true)
|
|
230
226
|
link.classList.add('active')
|
|
231
|
-
this.
|
|
227
|
+
this.nav.addEventListener('focus', this.checkFocusEvent, true)
|
|
232
228
|
// fix: workaround for safari because it doesn't support focus event
|
|
233
|
-
this.
|
|
229
|
+
this.nav.addEventListener('click', this.checkFocusEvent, true)
|
|
234
230
|
} else {
|
|
235
231
|
submenu.addEventListener('keydown', this.mobileSubNavTrapTabKeyEvent, false)
|
|
236
232
|
submenu.addEventListener(this.transitionEvent, this.showSubNavTransitionEndEvent, false)
|
package/src/main.js
CHANGED
|
@@ -35,6 +35,7 @@ function initSite() {
|
|
|
35
35
|
// Header Search
|
|
36
36
|
const openSearchButton = document.querySelectorAll('.js-open-search')
|
|
37
37
|
const closeSearchButton = document.querySelectorAll('.js-close-search')
|
|
38
|
+
const navigation = document.getElementById('main-nav')
|
|
38
39
|
const accordions = document.querySelectorAll('.js-accordion')
|
|
39
40
|
const dialogs = document.querySelectorAll('.js-dialog')
|
|
40
41
|
const fileUpload = document.querySelectorAll('.js-file-upload')
|
|
@@ -54,8 +55,9 @@ function initSite() {
|
|
|
54
55
|
new SiteSearch(element).init()
|
|
55
56
|
})
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
if (navigation) {
|
|
59
|
+
new Navigation(navigation).init()
|
|
60
|
+
}
|
|
59
61
|
|
|
60
62
|
accordions.forEach((element) => {
|
|
61
63
|
new Accordion(element).init()
|