|
1 | 1 | <script setup lang="ts"> |
2 | 2 | import { useFocusTrap } from '@vueuse/integrations/useFocusTrap' |
3 | 3 | import { useAtproto } from '~/composables/atproto/useAtproto' |
| 4 | +import type { NavigationConfigWithGroups } from '~/types' |
4 | 5 |
|
5 | 6 | const isOpen = defineModel<boolean>('open', { default: false }) |
| 7 | +const { links } = defineProps<{ |
| 8 | + links: NavigationConfigWithGroups |
| 9 | +}>() |
6 | 10 |
|
7 | 11 | const { isConnected, npmUser, avatar: npmAvatar } = useConnector() |
8 | 12 | const { user: atprotoUser } = useAtproto() |
@@ -175,137 +179,45 @@ onUnmounted(deactivate) |
175 | 179 |
|
176 | 180 | <!-- Navigation links --> |
177 | 181 | <div class="flex-1 overflow-y-auto overscroll-contain py-2"> |
178 | | - <!-- App navigation --> |
179 | | - <div class="px-2 py-2"> |
180 | | - <NuxtLink |
181 | | - :to="{ name: 'compare' }" |
182 | | - class="flex items-center gap-3 px-3 py-3 rounded-md font-mono text-sm text-fg hover:bg-bg-subtle transition-colors duration-200" |
183 | | - @click="closeMenu" |
184 | | - > |
185 | | - <span class="i-carbon:compare w-5 h-5 text-fg-muted" aria-hidden="true" /> |
186 | | - {{ $t('nav.compare') }} |
187 | | - </NuxtLink> |
188 | | - |
189 | | - <NuxtLink |
190 | | - :to="{ name: 'settings' }" |
191 | | - class="flex items-center gap-3 px-3 py-3 rounded-md font-mono text-sm text-fg hover:bg-bg-subtle transition-colors duration-200" |
192 | | - @click="closeMenu" |
193 | | - > |
194 | | - <span class="i-carbon:settings w-5 h-5 text-fg-muted" aria-hidden="true" /> |
195 | | - {{ $t('nav.settings') }} |
196 | | - </NuxtLink> |
197 | | - |
198 | | - <!-- Connected user links --> |
199 | | - <template v-if="isConnected && npmUser"> |
200 | | - <NuxtLink |
201 | | - :to="{ name: '~username', params: { username: npmUser } }" |
202 | | - class="flex items-center gap-3 px-3 py-3 rounded-md font-mono text-sm text-fg hover:bg-bg-subtle transition-colors duration-200" |
203 | | - @click="closeMenu" |
204 | | - > |
205 | | - <span class="i-carbon:package w-5 h-5 text-fg-muted" aria-hidden="true" /> |
206 | | - {{ $t('header.packages') }} |
207 | | - </NuxtLink> |
208 | | - |
209 | | - <NuxtLink |
210 | | - :to="{ name: '~username-orgs', params: { username: npmUser } }" |
211 | | - class="flex items-center gap-3 px-3 py-3 rounded-md font-mono text-sm text-fg hover:bg-bg-subtle transition-colors duration-200" |
212 | | - @click="closeMenu" |
213 | | - > |
214 | | - <span class="i-carbon:enterprise w-5 h-5 text-fg-muted" aria-hidden="true" /> |
215 | | - {{ $t('header.orgs') }} |
216 | | - </NuxtLink> |
217 | | - </template> |
218 | | - </div> |
219 | | - |
220 | | - <!-- Divider --> |
221 | | - <div class="mx-4 my-2 border-t border-border" /> |
222 | | - |
223 | | - <!-- Informational links --> |
224 | | - <div class="px-2 py-2"> |
225 | | - <NuxtLink |
226 | | - :to="{ name: 'about' }" |
227 | | - class="flex items-center gap-3 px-3 py-3 rounded-md font-mono text-sm text-fg hover:bg-bg-subtle transition-colors duration-200" |
228 | | - @click="closeMenu" |
229 | | - > |
230 | | - <span class="i-carbon:information w-5 h-5 text-fg-muted" aria-hidden="true" /> |
231 | | - {{ $t('footer.about') }} |
232 | | - </NuxtLink> |
233 | | - |
234 | | - <NuxtLink |
235 | | - :to="{ name: 'privacy' }" |
236 | | - class="flex items-center gap-3 px-3 py-3 rounded-md font-mono text-sm text-fg hover:bg-bg-subtle transition-colors duration-200" |
237 | | - @click="closeMenu" |
238 | | - > |
239 | | - <span class="i-carbon:security w-5 h-5 text-fg-muted" aria-hidden="true" /> |
240 | | - {{ $t('privacy_policy.title') }} |
241 | | - </NuxtLink> |
242 | | - </div> |
243 | | - |
244 | | - <!-- Divider --> |
245 | | - <div class="mx-4 my-2 border-t border-border" /> |
246 | | - |
247 | | - <!-- External links --> |
248 | | - <div class="px-2 py-2"> |
249 | | - <span class="px-3 py-2 font-mono text-xs text-fg-subtle uppercase tracking-wider"> |
250 | | - {{ $t('nav.links') }} |
251 | | - </span> |
252 | | - |
253 | | - <a |
254 | | - href="https://docs.npmx.dev" |
255 | | - target="_blank" |
256 | | - rel="noopener noreferrer" |
257 | | - class="flex items-center gap-3 px-3 py-3 rounded-md font-mono text-sm text-fg hover:bg-bg-subtle transition-colors duration-200" |
258 | | - > |
259 | | - <span class="i-carbon:document w-5 h-5 text-fg-muted" aria-hidden="true" /> |
260 | | - {{ $t('footer.docs') }} |
261 | | - <span |
262 | | - class="i-carbon:launch rtl-flip w-3 h-3 ms-auto text-fg-subtle" |
263 | | - aria-hidden="true" |
264 | | - /> |
265 | | - </a> |
266 | | - |
267 | | - <a |
268 | | - href="https://repo.npmx.dev" |
269 | | - target="_blank" |
270 | | - rel="noopener noreferrer" |
271 | | - class="flex items-center gap-3 px-3 py-3 rounded-md font-mono text-sm text-fg hover:bg-bg-subtle transition-colors duration-200" |
272 | | - > |
273 | | - <span class="i-carbon:logo-github w-5 h-5 text-fg-muted" aria-hidden="true" /> |
274 | | - {{ $t('footer.source') }} |
275 | | - <span |
276 | | - class="i-carbon:launch rtl-flip w-3 h-3 ms-auto text-fg-subtle" |
277 | | - aria-hidden="true" |
278 | | - /> |
279 | | - </a> |
280 | | - |
281 | | - <a |
282 | | - href="https://social.npmx.dev" |
283 | | - target="_blank" |
284 | | - rel="noopener noreferrer" |
285 | | - class="flex items-center gap-3 px-3 py-3 rounded-md font-mono text-sm text-fg hover:bg-bg-subtle transition-colors duration-200" |
286 | | - > |
287 | | - <span class="i-simple-icons:bluesky w-5 h-5 text-fg-muted" aria-hidden="true" /> |
288 | | - {{ $t('footer.social') }} |
289 | | - <span |
290 | | - class="i-carbon:launch rtl-flip w-3 h-3 ms-auto text-fg-subtle" |
291 | | - aria-hidden="true" |
292 | | - /> |
293 | | - </a> |
| 182 | + <template v-for="(group, index) in links"> |
| 183 | + <div |
| 184 | + v-if="group.type === 'separator'" |
| 185 | + :key="`seperator-${index}`" |
| 186 | + class="mx-4 my-2 border-t border-border" |
| 187 | + /> |
294 | 188 |
|
295 | | - <a |
296 | | - href="https://chat.npmx.dev" |
297 | | - target="_blank" |
298 | | - rel="noopener noreferrer" |
299 | | - class="flex items-center gap-3 px-3 py-3 rounded-md font-mono text-sm text-fg hover:bg-bg-subtle transition-colors duration-200" |
300 | | - > |
301 | | - <span class="i-carbon:chat w-5 h-5 text-fg-muted" aria-hidden="true" /> |
302 | | - {{ $t('footer.chat') }} |
| 189 | + <div v-if="group.type === 'group'" :key="group.name" class="p-2"> |
303 | 190 | <span |
304 | | - class="i-carbon:launch rtl-flip w-3 h-3 ms-auto text-fg-subtle" |
305 | | - aria-hidden="true" |
306 | | - /> |
307 | | - </a> |
308 | | - </div> |
| 191 | + v-if="group.label" |
| 192 | + class="px-3 py-2 font-mono text-xs text-fg-subtle uppercase tracking-wider" |
| 193 | + > |
| 194 | + {{ group.label }} |
| 195 | + </span> |
| 196 | + <div> |
| 197 | + <NuxtLink |
| 198 | + v-for="link in group.items" |
| 199 | + :key="link.name" |
| 200 | + :to="link.to" |
| 201 | + :href="link.href" |
| 202 | + :target="link.target" |
| 203 | + class="flex items-center gap-3 px-3 py-3 rounded-md font-mono text-sm text-fg hover:bg-bg-subtle transition-colors duration-200" |
| 204 | + @click="closeMenu" |
| 205 | + > |
| 206 | + <span |
| 207 | + :class="link.iconClass" |
| 208 | + class="w-5 h-5 text-fg-muted" |
| 209 | + aria-hidden="true" |
| 210 | + /> |
| 211 | + {{ link.label }} |
| 212 | + <span |
| 213 | + v-if="link.external" |
| 214 | + class="i-carbon:launch rtl-flip w-3 h-3 ms-auto text-fg-subtle" |
| 215 | + aria-hidden="true" |
| 216 | + /> |
| 217 | + </NuxtLink> |
| 218 | + </div> |
| 219 | + </div> |
| 220 | + </template> |
309 | 221 | </div> |
310 | 222 | </nav> |
311 | 223 | </Transition> |
|
0 commit comments