@worksafevictoria/wcl7.5 1.2.2 → 1.3.0

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.
@@ -0,0 +1,1105 @@
1
+ <template>
2
+ <div>
3
+ <header
4
+ v-if="headerMenu"
5
+ :class="'app-header' + (screen === 'mobile' ? ' ' + 'isMobile' : '')"
6
+ >
7
+ <!-- Top menu -->
8
+ <div class="logo">
9
+ <nuxt-link class="dark" to="/">
10
+ <img
11
+ :alt="
12
+ isWorkWell
13
+ ? 'Work Well Victoria - Logo'
14
+ : 'Work Safe Victoria - Logo'
15
+ "
16
+ width="127"
17
+ height="55"
18
+ :src="isWorkWell ? WorkWellLogo : WorkSafeLogo"
19
+ />
20
+ </nuxt-link>
21
+ <span class="logo__nav">
22
+ <table>
23
+ <tbody>
24
+ <tr>
25
+ <td>
26
+ <nuxt-link
27
+ to="/languages"
28
+ @click.native="fireAnalytics('Choose your language', '/languages')"
29
+ title="Language"
30
+ >
31
+ <span v-if="!topLevelIconsOnly">Choose your language </span>
32
+ <img alt="Language Icon" width="20px" height="20px" :src=LanguageIcon />
33
+ </nuxt-link>
34
+ </td>
35
+ <td>
36
+ <a href="javascript:void(0)" @click="show = !show" title="Contrast">
37
+ <span v-if="!topLevelIconsOnly">Adjust control</span> <img alt="Contrast Icon" width="20px" height="20px" :src=ContrastIcon />
38
+ </a>
39
+ <div
40
+ class="flex-container"
41
+ v-if="show"
42
+ >
43
+ <div class="contrast_slide--box-list">
44
+ <div v-for="list in lists" :key="list.value">
45
+ <label>
46
+ <input
47
+ type="radio"
48
+ :name="list.name"
49
+ :value="list.value"
50
+ :checked="list.value === selectedValue"
51
+ @click="handleContrast"
52
+ />
53
+ {{ list.label }}
54
+ </label>
55
+ </div>
56
+ </div>
57
+ </div>
58
+ </td>
59
+ <td>
60
+ <nuxt-link
61
+ class="cta-button cta-button--text-only cta-button--slim"
62
+ to="/search"
63
+ title="Search"
64
+ ><span v-if="!topLevelButtonIconsOnly">Search &nbsp;</span> <img alt="Search Icon" width="20px" height="20px" :src=NavSearchIcon />
65
+ </nuxt-link>
66
+ </td>
67
+ <td>
68
+ <nuxt-link
69
+ class="cta-button cta-button--text-only cta-button--slim cta-button--dark-no-filter"
70
+ to="/login"
71
+ title="Login"
72
+ ><span v-if="!topLevelButtonIconsOnly">Login &nbsp;</span><span><img alt="Login Icon" width="20px" height="20px" :src=LoginLeft /></span>
73
+ </nuxt-link>
74
+ </td>
75
+ </tr>
76
+ </tbody>
77
+ </table>
78
+ </span>
79
+ </div>
80
+ <!-- Bottom menu -->
81
+ <div class="app-header__wrap" @keyup.esc="closeMegaMenu">
82
+ <div class="app-header__close-button mobile-close">
83
+ <button
84
+ v-if="
85
+ (isMobileMenuOpen && screen === 'mobile' && !isSecondLevelOpen)
86
+ "
87
+ ref="closeMenuButton"
88
+ class="dark"
89
+ @click="closeMegaMenu"
90
+ >
91
+ <img :alt="Close" width="12" height="12" :src="Close"/>
92
+ Close menu
93
+ </button>
94
+ </div>
95
+ <div
96
+ v-if="
97
+ (!isSecondLevelOpen && screen === 'desktop') ||
98
+ (!isMobileMenuOpen && screen === 'mobile')
99
+ "
100
+ class="app-header__app-branding"
101
+ >
102
+
103
+ </div>
104
+ <nav
105
+ v-if="isMobileMenuOpen || screen === 'desktop'"
106
+ :class="{
107
+ 'styled-scrollbar': screen === 'mobile' && !isSecondLevelOpen,
108
+ }"
109
+ >
110
+ <ul class="app-header__nav-menu" id="navitems">
111
+ <li
112
+ v-for="(firstLevelLink, parentIndex) in headerMenu"
113
+ :key="firstLevelLink.key"
114
+ :ref="`firstLevelMenuItem-${parentIndex}`"
115
+ class="nav-item"
116
+ >
117
+ <a
118
+ v-if="firstLevelLink.below"
119
+ class="dark"
120
+ href
121
+ role="button"
122
+ aria-expanded="false"
123
+ @click.prevent="
124
+ firstLevelClick(
125
+ firstLevelLink,
126
+ `firstLevelMenuItem-${parentIndex}`,
127
+ )
128
+ "
129
+ @mouseover="mouseHover('firstLevelMenuItem', parentIndex)"
130
+ @mouseleave="mouseLeave('firstLevelMenuItem', parentIndex)"
131
+ @focusin="mouseHover('firstLevelMenuItem', parentIndex)"
132
+ @focusout="mouseLeave('firstLevelMenuItem', parentIndex)"
133
+ >
134
+ <span>{{ firstLevelLink.title }}</span>
135
+
136
+ <caret-down v-if="screen === 'desktop'" class="caret-down" />
137
+ <caret-right
138
+ v-else-if="!isSecondLevelOpen && !isThirdLevelOpen"
139
+ class="caret-right"
140
+ />
141
+ </a>
142
+ <a
143
+ v-else-if="!firstLevelLink.relative"
144
+ :href="firstLevelLink.absolute"
145
+ class="dark"
146
+ >
147
+ <span>{{ firstLevelLink.title }}</span>
148
+ </a>
149
+ <nuxt-link
150
+ v-else
151
+ class="dark"
152
+ :to="firstLevelLink.relative"
153
+ @click.native="fireAnalytics(firstLevelLink.title, firstLevelLink.relative)"
154
+ >
155
+ <span>{{ firstLevelLink.title }}</span>
156
+ </nuxt-link>
157
+ <div v-if="isSecondLevelOpen" class="sub-nav-container">
158
+ <div class="app-header__close-button">
159
+ <button
160
+ v-if="screen === 'mobile'"
161
+ ref="menuBackButton"
162
+ class="dark"
163
+ @click="mobileGoBack"
164
+ @keydown.tab="submenuFocus"
165
+ >
166
+ <caret-left/>
167
+ {{ isThirdLevelOpen ? firstLevelItemName : 'Main menu' }}
168
+ </button>
169
+ <button
170
+ v-if="
171
+ (isSecondLevelOpen && screen === 'desktop') ||
172
+ (isMobileMenuOpen && screen === 'mobile')
173
+ "
174
+ ref="closeMenuButton"
175
+ class="dark"
176
+ @click="closeMegaMenu"
177
+ >
178
+ <img :alt="Close" width="12" height="12" :src="Close"/>
179
+ Close menu
180
+ </button>
181
+ </div>
182
+ <div
183
+ class="sub-nav-container__inner"
184
+ :class="{ 'styled-scrollbar': screen === 'desktop' }"
185
+ >
186
+ <div
187
+ class="sub-nav-container__wrap"
188
+ :class="{
189
+ 'styled-scrollbar':
190
+ screen === 'mobile' && isSecondLevelOpen,
191
+ }"
192
+ >
193
+ <div
194
+ class="selected-title"
195
+ :class="{ 'selected-title--chrome': isChrome }"
196
+ >
197
+ <nuxt-link
198
+ v-if="firstLevelLink.relative"
199
+ :ref="`secondLevelSelectedTitle-${parentIndex}`"
200
+ :to="firstLevelLink.relative"
201
+ class="dark"
202
+ @click.native="fireAnalytics(firstLevelLink.title, firstLevelLink.relative)"
203
+ @keydown.tab.native="backBtnFocus($event)"
204
+ >
205
+ <span>{{ firstLevelLink.title }}</span>
206
+ </nuxt-link>
207
+ <span v-else>{{ firstLevelLink.title }}</span>
208
+ </div>
209
+ <div class="selected-items">
210
+ <ul v-if="firstLevelLink.below" class="sub-nav-group">
211
+ <li
212
+ v-for="(
213
+ secondLevelLink, secondIndex
214
+ ) in firstLevelLink.below"
215
+ :key="secondLevelLink.key"
216
+ :ref="`secondLevelMenuItem-${parentIndex}-${secondIndex}`"
217
+ class="sub-nav-parent-item"
218
+ >
219
+ <a
220
+ v-if="secondLevelLink.below"
221
+ href
222
+ class="dark"
223
+ role="button"
224
+ aria-expanded="false"
225
+ @keydown.tab="
226
+ searchFocus(
227
+ secondIndex,
228
+ firstLevelLink.below.length,
229
+ $event,
230
+ )
231
+ "
232
+ @click.prevent="
233
+ secondLevelClick(
234
+ secondLevelLink,
235
+ `secondLevelMenuItem-${parentIndex}-${secondIndex}`,
236
+ )
237
+ "
238
+ @mouseover="
239
+ mouseHover(
240
+ 'secondLevelMenuItem',
241
+ parentIndex,
242
+ secondIndex,
243
+ )
244
+ "
245
+ @mouseleave="
246
+ mouseLeave(
247
+ 'secondLevelMenuItem',
248
+ parentIndex,
249
+ secondIndex,
250
+ )
251
+ "
252
+ @focusin="
253
+ mouseHover(
254
+ 'secondLevelMenuItem',
255
+ parentIndex,
256
+ secondIndex,
257
+ )
258
+ "
259
+ @focusout="
260
+ mouseLeave(
261
+ 'secondLevelMenuItem',
262
+ parentIndex,
263
+ secondIndex,
264
+ )
265
+ "
266
+ >
267
+ <span>{{ secondLevelLink.title }}</span>
268
+ <caret-right
269
+ v-if="!(screen === 'mobile' && isThirdLevelOpen)"
270
+ class="caret-right"
271
+ />
272
+ </a>
273
+ <a
274
+ v-else-if="!secondLevelLink.relative"
275
+ :href="secondLevelLink.absolute"
276
+ class="dark"
277
+ >
278
+ <span>{{ secondLevelLink.title }}</span>
279
+ </a>
280
+ <nuxt-link
281
+ v-else
282
+ class="dark"
283
+ :to="secondLevelLink.relative"
284
+ @keydown.tab.native="
285
+ searchFocus(
286
+ secondIndex,
287
+ firstLevelLink.below.length,
288
+ $event,
289
+ )
290
+ "
291
+ @mouseover.native="
292
+ mouseHover(
293
+ 'secondLevelMenuItem',
294
+ parentIndex,
295
+ secondIndex,
296
+ )
297
+ "
298
+ @mouseleave.native="
299
+ mouseLeave(
300
+ 'secondLevelMenuItem',
301
+ parentIndex,
302
+ secondIndex,
303
+ )
304
+ "
305
+ @focusin.native="
306
+ mouseHover(
307
+ 'secondLevelMenuItem',
308
+ parentIndex,
309
+ secondIndex,
310
+ )
311
+ "
312
+ @focusout.native="
313
+ mouseLeave(
314
+ 'secondLevelMenuItem',
315
+ parentIndex,
316
+ secondIndex,
317
+ )
318
+ "
319
+ @click.native="fireAnalytics(secondLevelLink.title, secondLevelLink.relative)"
320
+ >
321
+ <span>{{ secondLevelLink.title }}</span>
322
+ </nuxt-link>
323
+ <div v-if="isThirdLevelOpen" class="sub-nav">
324
+ <div class="sub-nav__wrap">
325
+ <div class="selected-title">
326
+ <nuxt-link
327
+ v-if="secondLevelLink.relative"
328
+ :ref="`secondLevelSelectedTitle-${parentIndex}-${secondIndex}`"
329
+ :to="secondLevelLink.relative"
330
+ class="dark"
331
+ @click.native="fireAnalytics(secondLevelLink.title, secondLevelLink.relative)"
332
+ @keydown.tab.native="backBtnFocus($event)"
333
+ >
334
+ <span>{{ secondLevelLink.title }}</span>
335
+ </nuxt-link>
336
+ <span v-else>{{ secondLevelLink.title }}</span>
337
+ </div>
338
+ <div class="selected-sub-nav">
339
+ <ul
340
+ v-if="secondLevelLink.below"
341
+ class="sub-nav-group"
342
+ >
343
+ <li
344
+ v-for="(
345
+ thirdLevelLink, thirdIndex
346
+ ) in secondLevelLink.below"
347
+ :key="thirdLevelLink.key"
348
+ :ref="`thirdLevelMenuItem-${parentIndex}-${secondIndex}-${thirdIndex}`"
349
+ >
350
+ <nuxt-link
351
+ v-if="thirdLevelLink.relative"
352
+ class="dark"
353
+ :to="thirdLevelLink.relative"
354
+ @keydown.tab.native="
355
+ searchFocus(
356
+ thirdIndex,
357
+ secondLevelLink.below.length,
358
+ $event,
359
+ )
360
+ "
361
+ @mouseover.native="
362
+ mouseHover(
363
+ 'thirdLevelMenuItem',
364
+ parentIndex,
365
+ secondIndex,
366
+ thirdIndex,
367
+ )
368
+ "
369
+ @mouseleave.native="
370
+ mouseLeave(
371
+ 'thirdLevelMenuItem',
372
+ parentIndex,
373
+ secondIndex,
374
+ thirdIndex,
375
+ )
376
+ "
377
+ @focusin.native="
378
+ mouseHover(
379
+ 'thirdLevelMenuItem',
380
+ parentIndex,
381
+ secondIndex,
382
+ thirdIndex,
383
+ )
384
+ "
385
+ @focusout.native="
386
+ mouseLeave(
387
+ 'thirdLevelMenuItem',
388
+ parentIndex,
389
+ secondIndex,
390
+ thirdIndex,
391
+ )
392
+ "
393
+ @click.native="
394
+ fireAnalytics(thirdLevelLink.title, thirdLevelLink.relative)
395
+ "
396
+ >
397
+ <span>{{ thirdLevelLink.title }}</span>
398
+ </nuxt-link>
399
+ <a
400
+ v-else
401
+ class="dark"
402
+ :href="thirdLevelLink.absolute"
403
+ >
404
+ <span>{{ thirdLevelLink.title }}</span>
405
+ </a>
406
+ </li>
407
+ </ul>
408
+ </div>
409
+ </div>
410
+ </div>
411
+ </li>
412
+ </ul>
413
+ </div>
414
+ </div>
415
+ </div>
416
+ </div>
417
+ </li>
418
+ <!-- <li id="moreDesktop" v-if="screen === 'desktop' && this.moreList.length > 0">
419
+ <a class="dark" role="button" @click="showMore = !showMore">
420
+ <span>More</span>
421
+ <caret-down class="caret-down" />
422
+ </a>
423
+ <div
424
+ class="flex-container"
425
+ v-if="showMore"
426
+ >
427
+ <div class="contrast_slide--box-list">
428
+ <div v-for="list in this.moreList" :key="list.value">
429
+ <label>
430
+ <input
431
+ type="radio"
432
+ :name="list.name"
433
+ :value="list.value"
434
+ :checked="list.value === selectedValue"
435
+ @click="handleContrast"
436
+ />
437
+ {{ list.label }}
438
+ </label>
439
+ </div>
440
+ </div>
441
+ </div>
442
+ </li> -->
443
+ <li v-if="isWorkWell && screen === 'desktop'" class="nav-item hide">
444
+ <a href="#" class="dark" @focus="resetTab"></a>
445
+ </li>
446
+
447
+ </ul>
448
+ </nav>
449
+ <div v-if="screen === 'mobile'" class="app-header__mobile-menu-container">
450
+ <ul id="mobileitems">
451
+ <!-- <li v-if="!isMobileMenuOpen" id="moreMobile">
452
+ <a class="dark" role="button" @click.prevent="showMobileMenu">
453
+ <span>More</span>
454
+ <caret-down class="caret-down" />
455
+ </a>
456
+ </li> -->
457
+ <li v-if="!isMobileMenuOpen">
458
+ <a class="dark" role="button" @click.prevent="showMobileMenu">
459
+ <span>Menu</span>
460
+ <menu-icon class="menu-icon" />
461
+ </a>
462
+ </li>
463
+ </ul>
464
+ </div>
465
+ </div>
466
+ </header>
467
+ </div>
468
+ </template>
469
+
470
+ <script>
471
+ import ModalSearch from './ModalSearch/index.vue'
472
+ import Close from './../../../assets/icons/close.svg?url'
473
+ import WorkSafeLogo from './../../../assets/icons/WSV-reversed.svg?url'
474
+ import WorkWellLogo from './../../../assets/icons/AppFooter/logo-workwell-reversed.svg?url'
475
+ import CaretRight from './../../../assets/icons/caret-right.svg?component'
476
+ import CaretDown from './../../../assets/icons/caret-down.svg?component'
477
+ import SearchIcon from './../../../assets/icons/AppHeader/search-32px.svg?component'
478
+ import CaretLeft from './../../../assets/icons/caret-left.svg?component'
479
+ import MenuIcon from './../../../assets/icons/AppHeader/menu-32px.svg?component'
480
+ import LoginLeft from './../../../assets/icons/login.svg?url'
481
+ import LanguageIcon from './../../../assets/icons/lang.svg?url'
482
+ import ContrastIcon from './../../../assets/icons/contrast.svg?url'
483
+ import NavSearchIcon from './../../../assets/icons/search.svg?url'
484
+ import CtaButton from '../../SubComponents/CtaButton/index.vue'
485
+ import { ref } from "vue";
486
+
487
+ export default {
488
+ setup() {
489
+ const show = ref(false);
490
+ const showMore = ref(false);
491
+ const moreList = [];
492
+ return {
493
+ show,
494
+ showMore,
495
+ moreList
496
+ };
497
+ },
498
+ components: {
499
+ ModalSearch,
500
+ Close,
501
+ CaretRight,
502
+ CaretDown,
503
+ CaretLeft,
504
+ MenuIcon,
505
+ SearchIcon,
506
+ CtaButton,
507
+ },
508
+ props: {
509
+ headerMenu: {
510
+ type: Array,
511
+ required: true,
512
+ },
513
+ contentParser: {
514
+ type: Function,
515
+ required: true,
516
+ },
517
+ isWorkWell: {
518
+ type: Boolean,
519
+ default: false,
520
+ },
521
+ authenticated: {
522
+ type: Boolean,
523
+ default: false,
524
+ },
525
+ },
526
+ data() {
527
+ return {
528
+ screen: null,
529
+ topLevelIconsOnly: false,
530
+ topLevelButtonIconsOnly: false,
531
+ isMobileMenuOpen: false,
532
+ isSecondLevelOpen: false,
533
+ isThirdLevelOpen: false,
534
+ isSearchOpen: false,
535
+ firstLevelItemName: null,
536
+ firstLevelItemRef: null,
537
+ secondLevelItemRef: null,
538
+ WorkSafeLogo,
539
+ WorkWellLogo,
540
+ CaretRight,
541
+ CaretDown,
542
+ SearchIcon,
543
+ Close,
544
+ CaretLeft,
545
+ MenuIcon,
546
+ windowWidth: 0,
547
+ searchQuery: null,
548
+ LanguageIcon,
549
+ LoginLeft,
550
+ ContrastIcon,
551
+ NavSearchIcon,
552
+ lists: [
553
+ {
554
+ name: 'contrast',
555
+ value: 'default',
556
+ label: 'Light contrast (default)'
557
+ },
558
+ {
559
+ name: 'contrast',
560
+ value: 'high_contrast',
561
+ label: 'Increased contrast'
562
+ },
563
+ { name: 'contrast',
564
+ value: 'grayscale',
565
+ label: 'Greyscale'
566
+ }
567
+ ],
568
+ selectedValue: null
569
+ }
570
+ },
571
+ computed: {
572
+ showSecondLevelCaret() {
573
+ return (
574
+ (this.screen === 'mobile' &&
575
+ this.isSecondLevelOpen &&
576
+ !this.isThirdLevelOpen) ||
577
+ this.screen === 'desktop'
578
+ )
579
+ },
580
+ isChrome() {
581
+ return !!window.chrome
582
+ },
583
+ },
584
+ watch: {
585
+ $route() {
586
+ if (this.screen) {
587
+ this.closeMegaMenu()
588
+ }
589
+ },
590
+ windowWidth(val) {
591
+
592
+ if (val > 980) {
593
+ this.screen = 'desktop'
594
+ } else if (val <= 980) {
595
+ this.screen = 'mobile'
596
+ if (this.isSecondLevelOpen === true) {
597
+ this.isMobileMenuOpen = true
598
+ }
599
+ }
600
+ // added code to check if val < 760, when top menu should revert to icons, not labels.
601
+ if (val < 760) {
602
+ this.topLevelIconsOnly = true
603
+ } else {
604
+ this.topLevelIconsOnly = false
605
+ }
606
+ if (val < 500) {
607
+ this.topLevelButtonIconsOnly = true
608
+ } else {
609
+ this.topLevelButtonIconsOnly = false
610
+ }
611
+ this.updateMoreMenu(val)
612
+ },
613
+ },
614
+ destroyed() {
615
+ window.removeEventListener('resize', this.screenWidth)
616
+ },
617
+ created() {
618
+ if (typeof window !== 'undefined' && window) {
619
+ window.addEventListener('resize', this.screenWidth)
620
+ this.screenWidth()
621
+ }
622
+ if (this.$nuxt) {
623
+ //console.log('🚀 ~ this.$nuxt.$on ~ this.$nuxt:', this.$nuxt)
624
+ // this.$nuxt.$on('site-search', (query) => {
625
+ // this.searchQuery = query
626
+ // if (query) {
627
+ // this.showSearch()
628
+ // }
629
+ // })
630
+ }
631
+ },
632
+ methods: {
633
+ screenWidth() {
634
+ this.windowWidth = window.innerWidth
635
+ },
636
+ updateMoreMenu(screenVal) {
637
+ console.log('in updateMoreMenu - val' + screenVal)
638
+ const nItems = document.getElementById('navitems')
639
+ // let nItem = nItems.getElementsByTagName('li')
640
+ // console.log('nItem number: ' + nItem.length)
641
+ // const mItems = document.getElementById('mobileitems')
642
+ console.log('nItems: ' + nItems)
643
+ // console.log('mItems: ' + mItems)
644
+ // let navI = document.getElementById('navitems')
645
+ // console.log('navI items: ' + navI.children)
646
+ // if (navI?.offsetWidth) {
647
+ // console.log('navI: ' + navI.offsetWidth)
648
+ // } else {
649
+ // console.log('navI offsetWidth not available')
650
+ // }
651
+ // console.log('headerMenu: ' + this.headerMenu[0].title)
652
+ // console.log('headerMenu items: ' + this.headerMenu.length)
653
+ this.moreList = [
654
+ {"value":"One",
655
+ "label":"First Item"},
656
+ {"value":"Two",
657
+ "label":"Second Item"},
658
+ ]
659
+ let moreItem = {
660
+ "value": "Three",
661
+ "label": "Third Item"
662
+ }
663
+ this.moreList.unshift(moreItem)
664
+
665
+ let xItems = this.headerMenu
666
+ var vItems = []
667
+
668
+ console.log('xItems: ' + xItems.length)
669
+
670
+ if (xItems.length > 7) {
671
+ var tempItems = xItems.slice(-(xItems.length - 7))
672
+ console.log('tempItems: ' + tempItems[0].title + ', totalnumber: ' + tempItems.length)
673
+ }
674
+
675
+
676
+ // const mChildren = this.mItems.children;
677
+ // console.log('mChildren: ' + mChildren)
678
+ // let numW = 0;
679
+
680
+ /* [...mChildren].forEach(item => {
681
+ item.outHTML = '';
682
+ this.nItems.appendChild(item);
683
+ }) */
684
+
685
+ // const teleW = this.nItems.offsetWidth,
686
+ // nChildren = this.nItems.children;
687
+
688
+ /* [...mChildren].forEach(item => {
689
+ numW += item.offsetWidth;
690
+
691
+ if (numW > teleW) {
692
+ item.outHTML = '';
693
+ this.nItems.appendChild(item);
694
+ }
695
+ }); */
696
+ },
697
+ firstLevelClick(item, ref) {
698
+ // Reset screen to fix whitespace
699
+ if (window && window.scrollTo && this.screen === 'desktop') {
700
+ window.scrollTo(0, 0)
701
+ }
702
+
703
+ let selectedItem = this.$refs[ref][0]
704
+ let previouslyOpenItem = this.getActiveParent()
705
+
706
+ // Set this for mobile
707
+ this.firstLevelItemName = item.title
708
+ this.firstLevelItemRef = ref
709
+
710
+ // Set the first item to the variable
711
+ if (previouslyOpenItem.length) {
712
+ previouslyOpenItem = previouslyOpenItem[0]
713
+ }
714
+ // If the menu is not open, open it
715
+ if (item.below && this.isSecondLevelOpen === false) {
716
+ selectedItem.classList.add('isActiveParent')
717
+ selectedItem
718
+ .getElementsByTagName('a')[0]
719
+ .setAttribute('aria-expanded', 'true')
720
+ this.isSecondLevelOpen = true
721
+ this.letBodyOverflow(false)
722
+ }
723
+ // If the menu is already open and the same item is clicked,
724
+ // close it
725
+ else if (
726
+ item.below &&
727
+ this.isSecondLevelOpen === true &&
728
+ selectedItem === previouslyOpenItem
729
+ ) {
730
+ selectedItem.classList.remove('isActiveParent')
731
+ selectedItem
732
+ .getElementsByTagName('a')[0]
733
+ .setAttribute('aria-expanded', 'false')
734
+ this.isSecondLevelOpen = false
735
+ this.letBodyOverflow(true)
736
+ }
737
+ // If the link has no children then go to that page
738
+ else if (!item.below) {
739
+ if (item.relative !== '/') {
740
+ this.$router.push(item.relative)
741
+ }
742
+ }
743
+ // Otherwise just remove the existing open menu and add
744
+ // the isActive class on the new selected item
745
+ else {
746
+ previouslyOpenItem.classList.remove('isActiveParent')
747
+ selectedItem.classList.add('isActiveParent')
748
+ previouslyOpenItem
749
+ .getElementsByTagName('a')[0]
750
+ .setAttribute('aria-expanded', 'false')
751
+ selectedItem
752
+ .getElementsByTagName('a')[0]
753
+ .setAttribute('aria-expanded', 'true')
754
+ }
755
+ if (this.screen === 'mobile') {
756
+ this.focusOnNext(selectedItem)
757
+ }
758
+ },
759
+ secondLevelClick(item, ref) {
760
+ let selectedItem = this.$refs[ref][0]
761
+ let previouslyOpenItem = this.getActiveChild()
762
+ this.secondLevelItemRef = ref
763
+
764
+ // Set the first item to the variable
765
+ if (previouslyOpenItem.length) {
766
+ previouslyOpenItem = previouslyOpenItem[0]
767
+ }
768
+
769
+ // If the menu is not open, open it
770
+ if (item.below && this.isThirdLevelOpen === false) {
771
+ selectedItem.classList.add('isActiveChild')
772
+ selectedItem
773
+ .getElementsByTagName('a')[0]
774
+ .setAttribute('aria-expanded', 'true')
775
+ this.isThirdLevelOpen = true
776
+ }
777
+ // If the link has no children then go to that page
778
+ else if (!item.below) {
779
+ if (item.relative !== '/') {
780
+ this.$router.push(item.relative)
781
+ }
782
+ }
783
+ // If the menu is already open and the same item is clicked,
784
+ // close it
785
+ else if (
786
+ item.below &&
787
+ this.isThirdLevelOpen === true &&
788
+ selectedItem === previouslyOpenItem
789
+ ) {
790
+ selectedItem.classList.remove('isActiveChild')
791
+ selectedItem
792
+ .getElementsByTagName('a')[0]
793
+ .setAttribute('aria-expanded', 'false')
794
+ this.isThirdLevelOpen = false
795
+ }
796
+ // Otherwise just remove the existing open menu and add
797
+ // the isActive class on the new selected item
798
+ else {
799
+ previouslyOpenItem.classList.remove('isActiveChild')
800
+ previouslyOpenItem
801
+ .getElementsByTagName('a')[0]
802
+ .setAttribute('aria-expanded', 'false')
803
+ selectedItem.classList.add('isActiveChild')
804
+ selectedItem
805
+ .getElementsByTagName('a')[0]
806
+ .setAttribute('aria-expanded', 'true')
807
+ }
808
+
809
+ this.focusOnNext(selectedItem)
810
+ },
811
+
812
+ showMobileMenu() {
813
+ // Reset screen to top to fix whitespace issues
814
+ if (window) {
815
+ window.scrollTo(0, 0)
816
+ }
817
+
818
+ this.isMobileMenuOpen = true
819
+ this.letBodyOverflow(false)
820
+ this.showMore = false
821
+ /* this.$nextTick(() => {
822
+ this.$refs['firstLevelMenuItem-0'][0].firstElementChild.focus()
823
+ }) */
824
+ },
825
+ mouseHover(refID, parentIndex, secondIndex, thirdIndex) {
826
+ let theLI = this.getLIaboveHovered(
827
+ refID,
828
+ parentIndex,
829
+ secondIndex,
830
+ thirdIndex,
831
+ )
832
+ if (theLI) {
833
+ let A = theLI.getElementsByTagName('A')[0]
834
+ A.style.borderBottom = '1px solid transparent'
835
+ }
836
+ },
837
+ mouseLeave(refID, parentIndex, secondIndex, thirdIndex) {
838
+ let theLI = this.getLIaboveHovered(
839
+ refID,
840
+ parentIndex,
841
+ secondIndex,
842
+ thirdIndex,
843
+ )
844
+ if (theLI) {
845
+ let A = theLI.getElementsByTagName('A')[0]
846
+ A.removeAttribute('style')
847
+ }
848
+ },
849
+ getLIaboveHovered(refID, parentIndex, secondIndex, thirdIndex) {
850
+ // Check if its a first level link
851
+ if (secondIndex === undefined && thirdIndex === undefined) {
852
+ if (screen === 'desktop') {
853
+ return
854
+ }
855
+
856
+ let prevFirstIndex = parentIndex - 1
857
+
858
+ if (prevFirstIndex < 0) {
859
+ return
860
+ } else {
861
+ let aboveHovered = `${refID}-${prevFirstIndex}`
862
+ return this.$refs[aboveHovered][0]
863
+ }
864
+ }
865
+ // Check if its a second level link
866
+ else if (thirdIndex === undefined) {
867
+ let prevSecondIndex = secondIndex - 1
868
+ if (prevSecondIndex < 0) {
869
+ return
870
+ } else {
871
+ let aboveHovered = `${refID}-${parentIndex}-${prevSecondIndex}`
872
+ return this.$refs[aboveHovered][0]
873
+ }
874
+ }
875
+ // If its a third level link
876
+ else {
877
+ let prevThirdIndex = thirdIndex - 1
878
+ if (prevThirdIndex < 0) {
879
+ return
880
+ } else {
881
+ let aboveHovered = `${refID}-${parentIndex}-${secondIndex}-${prevThirdIndex}`
882
+ return this.$refs[aboveHovered][0]
883
+ }
884
+ }
885
+ },
886
+ showSearch() {
887
+ this.isSearchOpen = true
888
+ this.letBodyOverflow(false)
889
+ },
890
+ closeSearch() {
891
+ this.isSearchOpen = false
892
+ this.letBodyOverflow(true)
893
+ this.resetTab()
894
+ this.searchQuery = null
895
+ },
896
+ closeMegaMenu() {
897
+ let activeChild = this.getActiveChild()
898
+ let theActiveParent = this.getActiveParent()
899
+
900
+ if (theActiveParent.length) {
901
+ theActiveParent = theActiveParent[0]
902
+ theActiveParent.classList.remove('isActiveParent')
903
+ theActiveParent
904
+ .getElementsByTagName('a')[0]
905
+ .setAttribute('aria-expanded', 'false')
906
+ }
907
+
908
+ if (this.isThirdLevelOpen) {
909
+ activeChild = activeChild[0]
910
+ activeChild.classList.remove('isActiveChild')
911
+ activeChild
912
+ .getElementsByTagName('a')[0]
913
+ .setAttribute('aria-expanded', 'false')
914
+ this.isThirdLevelOpen = false
915
+ }
916
+ this.isMobileMenuOpen = false
917
+ this.isSecondLevelOpen = false
918
+ this.letBodyOverflow(true)
919
+ },
920
+ letBodyOverflow(state) {
921
+ let body = document.body
922
+ let main = document.getElementsByTagName('main')[0]
923
+ let footer = document.getElementsByTagName('footer')[0]
924
+ switch (state) {
925
+ case true:
926
+ body.removeAttribute('style')
927
+ if (main) {
928
+ main.removeAttribute('style')
929
+ }
930
+ if (footer) {
931
+ footer.removeAttribute('style')
932
+ }
933
+ break
934
+ case false:
935
+ body.style.overflow = 'hidden'
936
+ body.style.background = '#ffffff'
937
+ if (main) {
938
+ main.style.display = 'none'
939
+ }
940
+ if (footer) {
941
+ footer.style.display = 'none'
942
+ }
943
+ break
944
+ }
945
+ },
946
+ resetTab(el) {
947
+ if (this.$refs.closeMenuButton) {
948
+ if (el) {
949
+ el.preventDefault()
950
+ }
951
+ this.$refs.closeMenuButton.focus()
952
+ }
953
+ },
954
+ getActiveParent() {
955
+ return document.getElementsByClassName('isActiveParent')
956
+ },
957
+ getActiveChild() {
958
+ return document.getElementsByClassName('isActiveChild')
959
+ },
960
+ mobileGoBack() {
961
+ if (this.isThirdLevelOpen) {
962
+ let activeChild = this.getActiveChild()
963
+ activeChild = activeChild[0]
964
+ activeChild.classList.remove('isActiveChild')
965
+ activeChild
966
+ .getElementsByTagName('a')[0]
967
+ .setAttribute('aria-expanded', 'false')
968
+ this.isThirdLevelOpen = false
969
+ } else if (this.isSecondLevelOpen) {
970
+ let activeParent = this.getActiveParent()
971
+ activeParent = activeParent[0]
972
+ activeParent.classList.remove('isActiveParent')
973
+ activeParent
974
+ .getElementsByTagName('a')[0]
975
+ .setAttribute('aria-expanded', 'false')
976
+ this.isSecondLevelOpen = false
977
+ }
978
+ },
979
+ searchFocus(index, length, event) {
980
+ if (index === length - 1 && this.isMobileMenuOpen && !event.shiftKey) {
981
+ event.preventDefault()
982
+ this.$refs.searchButton.focus()
983
+ } else if (index === 0 && this.isMobileMenuOpen && event.shiftKey) {
984
+ event.preventDefault()
985
+ let firstIndex = this.firstLevelItemRef.split('-')[1]
986
+ let key = null
987
+ if (!this.isThirdLevelOpen) {
988
+ key = `secondLevelSelectedTitle-${firstIndex}`
989
+ } else if (this.isThirdLevelOpen) {
990
+ let secondIndex = this.secondLevelItemRef.split('-')[2]
991
+ key = `secondLevelSelectedTitle-${firstIndex}-${secondIndex}`
992
+ }
993
+ if (this.$refs[key][0].$el.nodeName === 'A') {
994
+ this.$refs[key][0].$el.focus()
995
+ }
996
+ }
997
+ },
998
+ submenuFocus(event) {
999
+ if (this.isMobileMenuOpen && !event.shiftKey && this.isSecondLevelOpen) {
1000
+ event.preventDefault()
1001
+ let firstIndex = this.firstLevelItemRef.split('-')[1]
1002
+ let key = null
1003
+ if (!this.isThirdLevelOpen) {
1004
+ key = `secondLevelSelectedTitle-${firstIndex}`
1005
+ } else if (this.isThirdLevelOpen) {
1006
+ let secondIndex = this.secondLevelItemRef.split('-')[2]
1007
+ key = `secondLevelSelectedTitle-${firstIndex}-${secondIndex}`
1008
+ }
1009
+ if (this.$refs[key][0].$el.nodeName === 'A') {
1010
+ this.$refs[key][0].$el.focus()
1011
+ }
1012
+ }
1013
+ },
1014
+ backBtnFocus(event) {
1015
+ if (this.isMobileMenuOpen && event.shiftKey && this.isSecondLevelOpen) {
1016
+ event.preventDefault()
1017
+ this.$refs.menuBackButton.focus()
1018
+ }
1019
+ },
1020
+ focusOnNext(selectedItem) {
1021
+ this.$nextTick(() => {
1022
+ selectedItem
1023
+ .getElementsByClassName('selected-title')[0]
1024
+ .firstChild.focus()
1025
+ })
1026
+ },
1027
+ fireAnalytics(contentTitle, contentRelative) {
1028
+ let payload = {
1029
+ event: 'custom.interaction.megamenu.click',
1030
+ group: 'Mega Menu',
1031
+ label: contentTitle,
1032
+ url: contentRelative,
1033
+ }
1034
+ // this.$store.dispatch('tracking/event', payload)
1035
+ },
1036
+ skipToContent() {
1037
+ if (this.$nuxt) {
1038
+ this.$nuxt.$emit('scrollToTop')
1039
+ }
1040
+ },
1041
+ goToLocation(path) {
1042
+ this.$router.push(path)
1043
+ },
1044
+ handleContrast(event) {
1045
+ const selMode = event.target.value
1046
+ // the css we are going to inject
1047
+ let cssVar = ''
1048
+ if (selMode === 'high_contrast') {
1049
+ cssVar =
1050
+ 'html {filter: invert(100%);' +
1051
+ '-webkit-filter: invert(100%);' +
1052
+ '-moz-filter: invert(100%);' +
1053
+ '-o-filter: invert(100%);' +
1054
+ '-ms-filter: invert(100%); }' +
1055
+ 'img {filter: invert(100%);' +
1056
+ 'background-color: #BABABA; }' +
1057
+ 'section[style*="background-image"],' +
1058
+ 'div[style*="background-image"] {filter: invert(100%);}'
1059
+ } else if (selMode === 'grayscale') {
1060
+ cssVar =
1061
+ 'html {filter: grayscale(100%);' +
1062
+ '-webkit-filter: grayscale(100%);' +
1063
+ '-moz-filter: grayscale(100%);' +
1064
+ '-o-filter: grayscale(100%);' +
1065
+ '-ms-filter: grayscale(100%);}' +
1066
+ 'img {filter: invert(0);}'
1067
+ } else {
1068
+ cssVar = ''
1069
+ }
1070
+ this.setContrast(cssVar, selMode)
1071
+ },
1072
+ setContrast(cssVar, selMode) {
1073
+ const head = document.getElementsByTagName('head')[0]
1074
+
1075
+ // Check if the style with the specified ID already exists
1076
+ let style = document.getElementById('contrastStyle')
1077
+
1078
+ if (!style) {
1079
+ // If style doesn't exist, create a new style element
1080
+ style = document.createElement('style')
1081
+ style.id = 'contrastStyle' // Assign an ID to the style element
1082
+
1083
+ if (style.styleSheet) {
1084
+ style.styleSheet.cssText = cssVar
1085
+ } else {
1086
+ style.appendChild(document.createTextNode(cssVar))
1087
+ }
1088
+ // Inject the CSS to the head
1089
+ head.appendChild(style)
1090
+ } else {
1091
+ // If style already exists, update its CSS
1092
+ style.textContent = cssVar
1093
+ }
1094
+ style.setAttribute('data-sel', selMode) // Set a data attribute on the style element
1095
+ // panel collapsing after making selection
1096
+ this.show = !this.show
1097
+ }
1098
+ },
1099
+ }
1100
+ </script>
1101
+
1102
+ <style lang="scss" scoped>
1103
+ @import './styles';
1104
+ @import './mobile';
1105
+ </style>