blob: 6e893a33a49886d0f5e19c4008c5b543bd24edc9 [file] [log] [blame]
Derick Montaguea2988f42020-01-17 13:46:30 -06001<template>
Yoshie Muranaka74f86872020-02-10 12:28:37 -08002 <div>
3 <div class="nav-container" :class="{ open: isNavigationOpen }">
Derick Montague68592032020-04-04 14:02:34 -05004 <nav ref="nav" :aria-label="$t('appNavigation.primaryNavigation')">
Yoshie Muranaka7d044352020-07-24 10:45:14 -07005 <b-nav vertical class="mb-4">
Yoshie Muranakad329ec82020-08-11 18:24:59 -07006 <template v-for="(navItem, index) in navigationItems">
7 <!-- Navigation items with no children -->
8 <b-nav-item
9 v-if="!navItem.children"
10 :key="index"
11 :to="navItem.route"
12 :data-test-id="`nav-item-${navItem.id}`"
Derick Montague2d589a72020-07-23 17:43:12 -050013 >
Yoshie Muranakad329ec82020-08-11 18:24:59 -070014 <component :is="navItem.icon" />
15 {{ navItem.label }}
16 </b-nav-item>
Derick Montague42c19892020-01-17 16:10:34 -060017
Yoshie Muranakad329ec82020-08-11 18:24:59 -070018 <!-- Navigation items with children -->
19 <li v-else :key="index" class="nav-item">
20 <b-button
21 v-b-toggle="`${navItem.id}`"
22 variant="link"
23 :data-test-id="`nav-button-${navItem.id}`"
Derick Montague2d589a72020-07-23 17:43:12 -050024 >
Yoshie Muranakad329ec82020-08-11 18:24:59 -070025 <component :is="navItem.icon" />
26 {{ navItem.label }}
27 <icon-expand class="icon-expand" />
28 </b-button>
29 <b-collapse :id="navItem.id" tag="ul" class="nav-item__nav">
30 <b-nav-item
31 v-for="(subNavItem, i) of navItem.children"
32 :key="i"
33 :to="subNavItem.route"
34 :data-test-id="`nav-item-${subNavItem.id}`"
35 >
36 {{ subNavItem.label }}
37 </b-nav-item>
38 </b-collapse>
39 </li>
40 </template>
Yoshie Muranaka74f86872020-02-10 12:28:37 -080041 </b-nav>
42 </nav>
43 </div>
44 <transition name="fade">
45 <div
46 v-if="isNavigationOpen"
Derick Montaguead2ceb62020-04-24 18:11:04 -050047 id="nav-overlay"
Yoshie Muranaka74f86872020-02-10 12:28:37 -080048 class="nav-overlay"
49 @click="toggleIsOpen"
50 ></div>
51 </transition>
52 </div>
Derick Montaguea2988f42020-01-17 13:46:30 -060053</template>
54
55<script>
Yoshie Muranaka8263d852020-10-16 07:58:06 -070056//Do not change Mixin import.
57//Exact match alias set to support
58//dotenv customizations.
Yoshie Muranakad329ec82020-08-11 18:24:59 -070059import AppNavigationMixin from './AppNavigationMixin';
Derick Montaguea2988f42020-01-17 13:46:30 -060060
61export default {
Derick Montaguee2fd1562019-12-20 13:26:53 -060062 name: 'AppNavigation',
Yoshie Muranakad329ec82020-08-11 18:24:59 -070063 mixins: [AppNavigationMixin],
Yoshie Muranaka74f86872020-02-10 12:28:37 -080064 data() {
65 return {
Derick Montague602e98a2020-10-21 16:20:00 -050066 isNavigationOpen: false,
Yoshie Muranaka74f86872020-02-10 12:28:37 -080067 };
68 },
69 watch: {
Derick Montague602e98a2020-10-21 16:20:00 -050070 $route: function () {
Yoshie Muranaka74f86872020-02-10 12:28:37 -080071 this.isNavigationOpen = false;
72 },
Derick Montague602e98a2020-10-21 16:20:00 -050073 isNavigationOpen: function (isNavigationOpen) {
Sukanya Pandeyedb8a772020-10-29 11:33:42 +053074 this.$root.$emit('change-is-navigation-open', isNavigationOpen);
Derick Montague602e98a2020-10-21 16:20:00 -050075 },
Yoshie Muranaka74f86872020-02-10 12:28:37 -080076 },
77 mounted() {
Sukanya Pandeyedb8a772020-10-29 11:33:42 +053078 this.$root.$on('toggle-navigation', () => this.toggleIsOpen());
Yoshie Muranaka74f86872020-02-10 12:28:37 -080079 },
80 methods: {
81 toggleIsOpen() {
82 this.isNavigationOpen = !this.isNavigationOpen;
Derick Montague602e98a2020-10-21 16:20:00 -050083 },
84 },
Derick Montaguea2988f42020-01-17 13:46:30 -060085};
86</script>
Derick Montague42c19892020-01-17 16:10:34 -060087
Yoshie Muranaka71ac2302019-12-26 11:43:36 -080088<style scoped lang="scss">
89svg {
Derick Montague66f903f2020-02-28 11:22:31 -060090 fill: currentColor;
91 height: 1.2rem;
92 width: 1.2rem;
Yoshie Muranaka71ac2302019-12-26 11:43:36 -080093 margin-left: 0 !important; //!important overriding button specificity
94 vertical-align: text-bottom;
95 &:not(.icon-expand) {
96 margin-right: $spacer;
97 }
98}
99
100.nav {
SurenNeware057232b2020-06-08 20:53:26 +0530101 padding-top: $spacer / 4;
102 @include media-breakpoint-up($responsive-layout-bp) {
103 padding-top: $spacer;
104 }
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800105}
106
107.nav-item__nav {
Derick Montague42c19892020-01-17 16:10:34 -0600108 list-style: none;
109 padding-left: 0;
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800110 margin-left: 0;
111
Yoshie Muranaka85358ed2020-05-18 10:05:36 -0700112 .nav-item {
113 outline: none;
114 }
115
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800116 .nav-link {
117 padding-left: $spacer * 4;
Yoshie Muranaka85358ed2020-05-18 10:05:36 -0700118 outline: none;
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800119
120 &:not(.nav-link--current) {
121 font-weight: normal;
122 }
123 }
124}
125
126.btn-link {
Dixsie Wolmers30f11f82020-11-10 16:07:56 -0600127 display: inline-block;
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800128 width: 100%;
129 text-align: left;
130 text-decoration: none !important;
131 border-radius: 0;
132
133 &.collapsed {
134 .icon-expand {
135 transform: rotate(180deg);
136 }
137 }
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800138}
139
140.icon-expand {
141 float: right;
142 margin-top: $spacer / 4;
143}
144
145.btn-link,
146.nav-link {
147 position: relative;
148 font-weight: $headings-font-weight;
149 padding-left: $spacer; // defining consistent padding for links and buttons
150 padding-right: $spacer;
Yoshie Muranaka01da8182020-07-08 15:46:43 -0700151 color: theme-color('secondary');
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800152
153 &:hover {
SurenNeware1f8117f2020-09-22 19:28:56 +0530154 background-color: theme-color-level(dark, -10.5);
Yoshie Muranaka01da8182020-07-08 15:46:43 -0700155 color: theme-color('dark');
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800156 }
Yoshie Muranaka9f5cea82020-02-04 09:30:00 -0800157
158 &:focus {
SurenNeware1f8117f2020-09-22 19:28:56 +0530159 background-color: theme-color-level(light, 0);
160 box-shadow: inset 0 0 0 2px theme-color('primary');
Yoshie Muranaka01da8182020-07-08 15:46:43 -0700161 color: theme-color('dark');
Derick Montague59569d82020-10-26 15:17:31 -0500162 outline: 0;
Yoshie Muranaka9f5cea82020-02-04 09:30:00 -0800163 }
SurenNeware1f8117f2020-09-22 19:28:56 +0530164
165 &:active {
Derick Montague59569d82020-10-26 15:17:31 -0500166 background-color: theme-color('secondary');
SurenNeware1f8117f2020-09-22 19:28:56 +0530167 color: $white;
168 }
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800169}
170
SurenNeware1f8117f2020-09-22 19:28:56 +0530171.nav-link--current {
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800172 font-weight: $headings-font-weight;
Yoshie Muranaka01da8182020-07-08 15:46:43 -0700173 background-color: theme-color('secondary');
174 color: theme-color('light');
Derick Montague66f903f2020-02-28 11:22:31 -0600175 cursor: default;
SurenNeware1f8117f2020-09-22 19:28:56 +0530176 box-shadow: none;
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800177
178 &::before {
179 content: '';
180 position: absolute;
181 top: 0;
182 bottom: 0;
183 left: 0;
184 width: 4px;
Yoshie Muranaka01da8182020-07-08 15:46:43 -0700185 background-color: theme-color('primary');
Yoshie Muranaka71ac2302019-12-26 11:43:36 -0800186 }
Derick Montague59569d82020-10-26 15:17:31 -0500187
188 &:hover,
SurenNeware1f8117f2020-09-22 19:28:56 +0530189 &:focus {
Derick Montague59569d82020-10-26 15:17:31 -0500190 background-color: theme-color('secondary');
191 color: theme-color('light');
SurenNeware1f8117f2020-09-22 19:28:56 +0530192 }
193}
Yoshie Muranaka74f86872020-02-10 12:28:37 -0800194
195.nav-container {
196 position: fixed;
197 width: $navigation-width;
198 top: $header-height;
199 bottom: 0;
200 left: 0;
201 z-index: $zindex-fixed;
202 overflow-y: auto;
Derick Montague59569d82020-10-26 15:17:31 -0500203 background-color: theme-color('light');
Yoshie Muranaka74f86872020-02-10 12:28:37 -0800204 transform: translateX(-$navigation-width);
205 transition: transform $exit-easing--productive $duration--moderate-02;
Derick Montague59569d82020-10-26 15:17:31 -0500206 border-right: 1px solid theme-color-level('light', 2.85);
207
SurenNeware057232b2020-06-08 20:53:26 +0530208 @include media-breakpoint-down(md) {
209 z-index: $zindex-fixed + 2;
210 }
Yoshie Muranaka74f86872020-02-10 12:28:37 -0800211
Derick Montague74466b82020-06-28 10:17:32 -0500212 &.open,
213 &:focus-within {
Yoshie Muranaka74f86872020-02-10 12:28:37 -0800214 transform: translateX(0);
215 transition-timing-function: $entrance-easing--productive;
216 }
217
218 @include media-breakpoint-up($responsive-layout-bp) {
219 transition-duration: $duration--fast-01;
220 transform: translateX(0);
221 }
222}
223
224.nav-overlay {
225 position: fixed;
226 top: $header-height;
227 bottom: 0;
228 left: 0;
229 right: 0;
SurenNeware057232b2020-06-08 20:53:26 +0530230 z-index: $zindex-fixed + 1;
Yoshie Muranaka74f86872020-02-10 12:28:37 -0800231 background-color: $black;
232 opacity: 0.5;
233
234 &.fade-enter-active {
235 transition: opacity $duration--moderate-02 $entrance-easing--productive;
236 }
237
238 &.fade-leave-active {
239 transition: opacity $duration--fast-02 $exit-easing--productive;
240 }
241
SurenNeware151dd242020-11-10 20:15:05 +0530242 &.fade-enter, // Remove this vue2 based only class when switching to vue3
243 &.fade-enter-from, // This is vue3 based only class modified from 'fade-enter'
Yoshie Muranaka74f86872020-02-10 12:28:37 -0800244 &.fade-leave-to {
245 opacity: 0;
246 }
247
248 @include media-breakpoint-up($responsive-layout-bp) {
249 display: none;
250 }
251}
Derick Montague42c19892020-01-17 16:10:34 -0600252</style>