@apptegy/nuxt-navigation 0.1.7 → 0.1.8

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/module.d.mts CHANGED
@@ -2,6 +2,6 @@ import * as _nuxt_schema from '@nuxt/schema';
2
2
 
3
3
  interface ModuleOptions {
4
4
  }
5
- declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
5
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
6
6
 
7
7
  export { type ModuleOptions, _default as default };
package/dist/module.d.ts CHANGED
@@ -2,6 +2,6 @@ import * as _nuxt_schema from '@nuxt/schema';
2
2
 
3
3
  interface ModuleOptions {
4
4
  }
5
- declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
5
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
6
6
 
7
7
  export { type ModuleOptions, _default as default };
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@apptegy/nuxt-navigation",
3
3
  "configKey": "@apptegy/nuxt-navigation",
4
- "version": "0.1.7",
4
+ "version": "0.1.8",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.3",
7
7
  "unbuild": "unknown"
@@ -22,7 +22,7 @@
22
22
  >
23
23
  <img v-if="isDropdown" src="../../assets/img/help-toggle.svg" alt="" class="help-center-btn-icon">
24
24
  <img v-else src="../../assets/img/help.svg" alt="" class="help-center-btn-icon">
25
- <span>
25
+ <span v-if="expandedSidebar">
26
26
  {{ isDropdown ? $t('navigation.helpCenter') : $t('navigation.helpArticles') }}
27
27
  </span>
28
28
  <img
@@ -47,6 +47,8 @@ const props = withDefaults(defineProps<IHelpArticlesProps>(), {
47
47
  helpArticleOptions: () => [],
48
48
  })
49
49
 
50
+ const { state: expandedSidebar } = useSidebar();
51
+
50
52
  const expanded = ref(false);
51
53
  const helpBtnActions = ref();
52
54
  const dropdownScrollHeight = ref(0);
@@ -1,6 +1,14 @@
1
1
  <template>
2
2
  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden>
3
- <rect x="4.3335" y="5.5" width="15.3333" height="13" rx="0.666667" stroke="currentColor"/>
4
- <path d="M10 6L10 18" stroke="currentColor" stroke-linecap="round"/>
3
+ <rect x="4.3335" y="5.5" width="15.3333" height="13" rx="0.666667" stroke="currentColor"/>
4
+ <rect x="4.3335" y="5.5" :width="expanded ? 6: 2" height="13" rx="0.666667" fill="currentColor" stroke="currentColor" stroke-linecap="round"/>
5
5
  </svg>
6
6
  </template>
7
+
8
+ <script setup lang="ts">
9
+ const { state: expanded } = useSidebar();
10
+ </script>
11
+
12
+ <style scoped>
13
+ rect{transition:width .2s}
14
+ </style>
@@ -170,7 +170,7 @@ function handleSelectedOrg($event: KeyboardEvent | MouseEvent, orgId: number) {
170
170
  white-space: nowrap;
171
171
  cursor: pointer;
172
172
  }
173
- .org-selection .dropdown-trigger .org-title:focus {
173
+ .org-selection .dropdown-trigger .org-title:focus-visible {
174
174
  outline: none;
175
175
  }
176
176
  .org-selection .dropdown {
@@ -4,6 +4,8 @@
4
4
  role="navigation"
5
5
  aria-label="Main"
6
6
  :class="{ expanded }"
7
+ @mouseenter="onHover"
8
+ @mouseleave="onHoverLeave"
7
9
  >
8
10
  <a
9
11
  ref="skip-to-content"
@@ -13,8 +15,10 @@
13
15
  >
14
16
  {{ $t('navigation.skipToContent') }}
15
17
  </a>
18
+ <div class="navbar--header">
19
+ <slot name="switcher" />
20
+ </div>
16
21
  <div class="navbar--content">
17
- <slot name="switcher" />
18
22
  <ul class="navbar-applications">
19
23
  <li v-for="application of applications" :key="application.id">
20
24
  <NavSidebarSection
@@ -31,22 +35,21 @@
31
35
  />
32
36
  </li>
33
37
  </ul>
34
-
35
38
  </div>
36
39
  <div class="navbar--footer">
37
40
  <NavImpersonateInfoPanel
38
41
  v-if="impersonatedUser.show"
39
42
  :impersonated-user="impersonatedUser"
40
43
  />
41
- </div>
42
44
 
43
45
  <slot name="logo">
44
46
  <NuxtLink :to="homepageUrl">
45
47
  <div class="navbar--logo">
46
- <img :src="logo.src" :alt="logo.alt">
48
+ <img :src="expanded ? logo.src : logo.iconSrc" :alt="logo.alt">
47
49
  </div>
48
50
  </NuxtLink>
49
51
  </slot>
52
+ </div>
50
53
  </nav>
51
54
  </template>
52
55
 
@@ -102,10 +105,24 @@ withDefaults(defineProps<ISidebarProps>(), {
102
105
  logo: () => ({
103
106
  alt: 'Thrillshare',
104
107
  src: 'logo.svg',
105
- iconSrc: 'logo.svg',
108
+ iconSrc: 'icon.svg',
106
109
  })
107
110
  })
108
111
 
112
+ // Debounced Expand on Hover
113
+ let expandedTimer;
114
+ function onHover() {
115
+ if(!expanded.value) {
116
+ expandedTimer = setTimeout(() => {
117
+ expanded.value = true;
118
+ }, 280);
119
+ }
120
+ }
121
+ function onHoverLeave() {
122
+ if(!expanded.value) {
123
+ clearTimeout(expandedTimer);
124
+ }
125
+ }
109
126
 
110
127
  </script>
111
128
 
@@ -113,15 +130,14 @@ withDefaults(defineProps<ISidebarProps>(), {
113
130
  .navbar {
114
131
  grid-area: navsidebar;
115
132
  display: grid;
116
- grid-template-rows: 1fr auto auto;
133
+ grid-template-rows: 0fr auto 0fr;
117
134
  font: var(--font-regular);
118
135
  background-color: var(--dscl-nav-background-color, var(--purple-70));
119
136
  color: var(--dscl-nav-font-color, var(--dscl-light-font, var(--primary-white)));
120
137
  transition: width 0.3s ease-in-out, translate 0.2s ease-in-out;
121
138
  height: 100vh;
122
139
  overflow-y: auto;
123
- /* min-width: 0px; */
124
- translate: -256px;
140
+ width: 64px;
125
141
  }
126
142
  .navbar a:focus-visible {
127
143
  outline: var(--orange) auto 2px;
@@ -130,9 +146,12 @@ withDefaults(defineProps<ISidebarProps>(), {
130
146
  }
131
147
  .navbar.expanded {
132
148
  transition: width 0.3s ease-in-out, translate 0.2s ease-in-out;
133
- min-width: 256px;
149
+ width: 256px;
134
150
  translate: 0px;
135
151
  }
152
+ .navbar.expanded .navbar--content ul {
153
+ width: 256px;
154
+ }
136
155
  .navbar--logo {
137
156
  padding: 16px;
138
157
  background-color: var(--dscl-nav-background-color, var(--purple-70));
@@ -141,7 +160,6 @@ withDefaults(defineProps<ISidebarProps>(), {
141
160
  .navbar--content {
142
161
  display: flex;
143
162
  flex-direction: column;
144
- flex-basis: auto;
145
163
  margin-top: 24px;
146
164
  background-color: var(--dscl-nav-background-color, var(--purple-70));
147
165
  }
@@ -149,15 +167,16 @@ withDefaults(defineProps<ISidebarProps>(), {
149
167
  list-style: none;
150
168
  padding: 0;
151
169
  margin: 0;
152
- max-width: 256px;
170
+ width: 64px;
153
171
  }
154
172
  .navbar--footer {
155
173
  display: flex;
156
174
  flex-direction: column;
175
+ height: fit-content;
157
176
  }
158
177
  .navbar .skip-to-content {
159
178
  overflow: hidden;
160
- padding: 15px 23px 14px;
179
+ padding: 16px 24px 14px;
161
180
  position: absolute;
162
181
  left: 5px;
163
182
  top: 5px;
@@ -1,15 +1,24 @@
1
+ <script setup lang="ts">
2
+ defineProps<{
3
+ icon: string;
4
+ }>();
5
+ const { state: expanded } = useSidebar();
6
+ </script>
7
+
1
8
  <template>
2
- <NuxtLink class="a-navbar-item">
3
- <slot />
9
+ <NuxtLink class="a-navbar-item" :class="{expanded}">
10
+ <a-icon :icon="icon" font-size="32px"/>
11
+ <slot v-if="expanded" />
4
12
  </NuxtLink>
5
13
  </template>
6
14
 
7
15
  <style scoped>
8
16
  .a-navbar-item {
9
17
  color: var(--dscl-nav-font-color, var(--dscl-light-font, var(--primary-white)));
10
- margin: 4px 16px;
18
+ margin: 4px 12px;
11
19
  display: flex;
12
20
  align-items: center;
21
+ gap: 4px;
13
22
  text-decoration: none;
14
23
  text-transform: capitalize;
15
24
  padding: 4px;
@@ -1,9 +1,9 @@
1
1
  <template>
2
2
  <div class="a-nav-section" :class="{ active }">
3
- <NuxtLink class="a-nav-section--link" :to="application.url">
4
- <img v-if="application.img_src" :src="iconUrl" alt="icon">
5
- <span>{{ application.text.replace("_", " ") }}</span>
6
- <a-icon v-if="active" class="caret-icon" icon="16:carret-up" />
3
+ <NuxtLink class="a-nav-section--link" :to="active ? '' : application.url">
4
+ <img v-if="application.img_src" :src="active ? getActiveIcon(application.img_src) : application.img_src" alt="icon">
5
+ <span v-if="expanded">{{ application.text.replace("_", " ") }}</span>
6
+ <a-icon v-if="expanded && active" class="caret-icon" icon="16:carret-up" />
7
7
  </NuxtLink>
8
8
  <div class="a-nav-section--content">
9
9
  <slot />
@@ -12,18 +12,16 @@
12
12
  </template>
13
13
 
14
14
  <script setup lang="ts">
15
- import { computed } from 'vue';
16
-
17
- const props = defineProps<{
15
+ defineProps<{
18
16
  application: IApplication;
19
17
  active: boolean;
20
18
  }>();
21
19
 
22
- const iconUrl = computed(() =>
23
- props.active
24
- ? props.application.img_src?.replace(".svg", "_active.svg")
25
- : props.application.img_src,
26
- );
20
+ const { state: expanded } = useSidebar();
21
+
22
+ function getActiveIcon(src){
23
+ return src.replace(".svg", "_active.svg");
24
+ };
27
25
  </script>
28
26
 
29
27
  <style scoped>
@@ -31,9 +29,6 @@ const iconUrl = computed(() =>
31
29
  box-shadow: inset 0px -1px 0px 0px var(--dscl-nav-section-border-bottom-color, var(--purple-65));
32
30
  cursor: pointer;
33
31
  min-height: 48px;
34
- /* &--content {
35
- margin-bottom: 8px;
36
- } */
37
32
  }
38
33
  .a-nav-section.active {
39
34
  box-shadow: inset 0px -1px 0px 0px var(--dscl-nav-section-border-bottom-color, var(--purple-65));
@@ -19,11 +19,11 @@ const { toggleSidebar } = useSidebar();
19
19
  background: var(--purple-20);
20
20
  border: none;
21
21
  border-radius: 4px;
22
- padding: 8px 16px;
22
+ padding: 4px 8px;
23
23
  color: var(--purple);
24
24
  cursor: pointer;
25
25
  }
26
- .sidebar-toggle:focus {
26
+ .sidebar-toggle:focus-visible {
27
27
  outline: none;
28
28
  box-shadow: 0 0 0 2px var(--primary-white), 0 0 0 3px var(--purple);
29
29
  }
@@ -48,13 +48,13 @@ defineProps({
48
48
  border-top: 2px solid transparent;
49
49
  border-radius: 4px;
50
50
  }
51
- .menu-item:hover, .menu-item:focus, .menu-item.nuxt-link-exact-active, .menu-item.router-link-exact-active {
51
+ .menu-item:hover, .menu-item:focus-visible, .menu-item.nuxt-link-exact-active, .menu-item.router-link-exact-active {
52
52
  background-color: var(--purple-10);
53
53
  border-radius: 4px 4px 0px 0px;
54
54
  color: var(--purple);
55
55
  outline: none;
56
56
  }
57
- .menu-item:hover:after, .menu-item:focus:after, .menu-item.nuxt-link-exact-active:after, .menu-item.router-link-exact-active:after {
57
+ .menu-item:hover:after, .menu-item:focus-visible:after, .menu-item.nuxt-link-exact-active:after, .menu-item.router-link-exact-active:after {
58
58
  border-top: 2px solid var(--purple);
59
59
  }
60
60
  .menu-item.nuxt-link-exact-active, .menu-item.router-link-exact-active {
@@ -7,8 +7,9 @@ interface IUserDropdown {
7
7
  user: {
8
8
  name: string;
9
9
  avatar?: string;
10
+ email: string;
10
11
  };
11
- userDropdownOptions: Array<{ label: string; url: string; icon: string }>;
12
+ userDropdownOptions: Array<{ label: string; url: string; }>;
12
13
  }
13
14
 
14
15
  const appConfig = useAppConfig();
@@ -72,6 +73,17 @@ function handleKeydownAction($event: KeyboardEvent, index: number) {
72
73
  class="options-dropdown"
73
74
  role="listbox"
74
75
  >
76
+ <div class="user-info">
77
+ <span class="user-info-title">{{ $t("navigation.userDropdown") }}</span>
78
+ <div class="user-info-details">
79
+ <NavAvatar :name="user.name" :src="user.avatar" style="--size: 40px"/>
80
+ <div class="user-info-details-container">
81
+ <span class="user-info-name"> {{ user.name }} </span>
82
+ <span class="user-info-email"> {{ user.email }} </span>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ <hr>
75
87
  <div
76
88
  v-for="(option, idx) in userDropdownOptions"
77
89
  :key="option.label"
@@ -86,7 +98,6 @@ function handleKeydownAction($event: KeyboardEvent, index: number) {
86
98
  <!-- because of the the above handler, this component is never treated as a link and can't redirect natively? -->
87
99
  <NuxtLink class="option" :to="option.url">
88
100
  {{ option.label }}
89
- <a-icon :icon="option.icon" font-size="24px" />
90
101
  </NuxtLink>
91
102
  </div>
92
103
  </div>
@@ -111,13 +122,44 @@ function handleKeydownAction($event: KeyboardEvent, index: number) {
111
122
  align-items: center;
112
123
  cursor: pointer;
113
124
  }
114
- .header__dropdown:focus {
125
+ .header__dropdown:focus-visible {
115
126
  box-shadow: 0 0 0 2px var(--primary-white), 0 0 0 3px var(--purple);
116
127
  }
117
- .header__dropdown .avatar-container:focus {
128
+ .header__dropdown .avatar-container:focus-visible {
118
129
  outline: none;
119
130
  }
120
131
 
132
+ hr {
133
+ border: 0;
134
+ border-top: 1px solid var(--grey-20);
135
+ margin: 8px 0;
136
+ }
137
+
138
+ .user-info {
139
+ display: flex;
140
+ flex-direction: column;
141
+ gap: 12px;
142
+ padding: 8px;
143
+ }
144
+ .user-info .user-info-title {
145
+ font-weight: bold;
146
+ font-size: 12px;
147
+ color: var(--grey-60);
148
+ text-transform: uppercase;
149
+ }
150
+ .user-info .user-info-details {
151
+ display: flex;
152
+ gap: 4px;
153
+ }
154
+ .user-info .user-info-details .user-info-details-container {
155
+ display: flex;
156
+ flex-direction: column;
157
+ }
158
+ .user-info .user-info-details .user-info-details-container .user-info-email {
159
+ font-size: 12px;
160
+ color: var(--grey-50);
161
+ }
162
+
121
163
  .options-dropdown {
122
164
  min-height: 100px;
123
165
  position: absolute;
@@ -3,8 +3,8 @@ export declare function useDropdown(options: Array<unknown>, dropdownOptionsRef:
3
3
  searchable: boolean;
4
4
  trackBy?: string;
5
5
  }): {
6
- active: Ref<boolean>;
7
- searchQuery: Ref<string>;
6
+ active: Ref<boolean, boolean>;
7
+ searchQuery: Ref<string, string>;
8
8
  toggleDropdown: ($event: KeyboardEvent | MouseEvent) => Promise<void>;
9
9
  openDropdown: () => void;
10
10
  closeDropdown: () => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apptegy/nuxt-navigation",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -26,24 +26,24 @@
26
26
  "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
27
27
  },
28
28
  "dependencies": {
29
- "@nuxt/kit": "^3.12.4",
30
- "@vueuse/components": "11.0.1",
29
+ "@nuxt/kit": "^3.13.1",
30
+ "@vueuse/components": "11.0.3",
31
31
  "lodash": "^4.17.21"
32
32
  },
33
33
  "devDependencies": {
34
- "@nuxt/devtools": "^1.3.14",
35
- "@nuxt/eslint-config": "^0.5.1",
34
+ "@nuxt/devtools": "^1.4.1",
35
+ "@nuxt/eslint-config": "^0.5.6",
36
36
  "@nuxt/module-builder": "^0.8.3",
37
- "@nuxt/schema": "^3.12.4",
37
+ "@nuxt/schema": "^3.13.1",
38
38
  "@nuxt/test-utils": "^3.14.1",
39
- "@types/node": "^20.16.1",
39
+ "@types/node": "^20.16.5",
40
40
  "changelogen": "^0.5.5",
41
- "eslint": "^9.9.0",
42
- "nuxt": "^3.12.4",
43
- "sass": "^1.77.8",
41
+ "eslint": "^9.9.1",
42
+ "nuxt": "^3.13.1",
43
+ "sass": "^1.78.0",
44
44
  "typescript": "^5.5.4",
45
45
  "vitest": "^1.6.0",
46
- "vue": "^3.4.38",
47
- "vue-tsc": "^2.0.29"
46
+ "vue": "^3.5.2",
47
+ "vue-tsc": "^2.1.6"
48
48
  }
49
49
  }