Skip to content

Commit 0d24f08

Browse files
committed
feat: enhance DocNavigation and navigation logic
1 parent b7c4868 commit 0d24f08

File tree

2 files changed

+74
-25
lines changed

2 files changed

+74
-25
lines changed

packages/nimiq-vitepress-theme/src/composables/useDocNavigation.ts

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { useCurrentModule } from './useCurrentModule'
66
export interface DocNavigationItem {
77
text: string
88
link: string
9-
description?: string
109
}
1110

1211
export function useDocNavigation() {
@@ -29,13 +28,26 @@ export function useDocNavigation() {
2928
for (const section of currentDocModule.value.sidebar) {
3029
const visibleItems = section.items.filter(item => !item.hidden)
3130
for (const item of visibleItems) {
32-
if (item.link && (withBase(item.link) === route.path || `${withBase(item.link)}/` === route.path))
31+
if (!item.link)
32+
continue
33+
34+
// Normalize paths for comparison
35+
const itemPath = withBase(item.link)
36+
const currentPath = route.path
37+
const itemPathWithoutHtml = itemPath.replace(/\.html$/, '')
38+
const currentPathWithoutHtml = currentPath.replace(/\.html$/, '')
39+
40+
if (itemPathWithoutHtml === currentPathWithoutHtml || itemPath === currentPath)
3341
return { item, section, visibleItems }
3442
if (item.items) {
3543
const visibleSubItems = item.items.filter(subitem => !subitem.hidden)
36-
const nestedItem = visibleSubItems.find(subitem =>
37-
withBase(subitem.link) === route.path || `${withBase(subitem.link)}/` === route.path,
38-
)
44+
const nestedItem = visibleSubItems.find((subitem) => {
45+
if (!subitem.link)
46+
return false
47+
const subItemPath = withBase(subitem.link)
48+
const subItemPathWithoutHtml = subItemPath.replace(/\.html$/, '')
49+
return subItemPathWithoutHtml === currentPathWithoutHtml || subItemPath === currentPath
50+
})
3951
if (nestedItem)
4052
return { item: nestedItem, section, parent: item, visibleItems, visibleSubItems }
4153
}
@@ -47,37 +59,49 @@ export function useDocNavigation() {
4759
const navigation = computed(() => {
4860
if (!showNavigation.value || !currentDocModule.value?.sidebar)
4961
return { prev: null, next: null }
62+
5063
const current = findCurrentPageInSidebar()
64+
5165
if (!current)
5266
return { prev: null, next: null }
67+
5368
const { section, parent, item: currentItem, visibleItems, visibleSubItems } = current
5469
const sectionIndex = currentDocModule.value.sidebar.indexOf(section)
5570
const items = visibleItems || section.items.filter(item => !item.hidden)
5671
let prev: DocNavigationItem | null = null
5772
let next: DocNavigationItem | null = null
73+
5874
if (parent && visibleSubItems) {
5975
const parentIndex = items.indexOf(parent)
6076
const siblingIndex = visibleSubItems.indexOf(currentItem)
61-
if (siblingIndex > 0)
77+
78+
if (siblingIndex > 0) {
6279
prev = { text: visibleSubItems[siblingIndex - 1].text, link: withBase(visibleSubItems[siblingIndex - 1].link) }
63-
else if (parentIndex > 0 && items[parentIndex - 1].link)
80+
}
81+
else if (parentIndex > 0 && items[parentIndex - 1].link) {
6482
prev = { text: items[parentIndex - 1].text, link: withBase(items[parentIndex - 1].link!) }
65-
if (siblingIndex < visibleSubItems.length - 1)
83+
}
84+
85+
if (siblingIndex < visibleSubItems.length - 1) {
6686
next = { text: visibleSubItems[siblingIndex + 1].text, link: withBase(visibleSubItems[siblingIndex + 1].link) }
67-
else if (parentIndex < items.length - 1 && items[parentIndex + 1].link)
87+
}
88+
else if (parentIndex < items.length - 1 && items[parentIndex + 1].link) {
6889
next = { text: items[parentIndex + 1].text, link: withBase(items[parentIndex + 1].link!) }
90+
}
6991
}
7092
else {
7193
const itemIndex = items.indexOf(currentItem)
94+
7295
if (itemIndex > 0) {
7396
const prevItem = items[itemIndex - 1]
7497
if (prevItem.link) {
7598
prev = { text: prevItem.text, link: withBase(prevItem.link) }
7699
}
77100
else if (prevItem.items?.length) {
78101
const visiblePrevItems = prevItem.items.filter(item => !item.hidden)
79-
if (visiblePrevItems.length > 0)
102+
if (visiblePrevItems.length > 0) {
80103
prev = { text: visiblePrevItems[visiblePrevItems.length - 1].text, link: withBase(visiblePrevItems[visiblePrevItems.length - 1].link) }
104+
}
81105
}
82106
}
83107
else if (sectionIndex > 0) {
@@ -89,19 +113,22 @@ export function useDocNavigation() {
89113
}
90114
else if (lastItem?.items?.length) {
91115
const visibleLastItems = lastItem.items.filter(item => !item.hidden)
92-
if (visibleLastItems.length > 0)
116+
if (visibleLastItems.length > 0) {
93117
prev = { text: visibleLastItems[visibleLastItems.length - 1].text, link: withBase(visibleLastItems[visibleLastItems.length - 1].link) }
118+
}
94119
}
95120
}
121+
96122
if (itemIndex < items.length - 1) {
97123
const nextItem = items[itemIndex + 1]
98124
if (nextItem.link) {
99125
next = { text: nextItem.text, link: withBase(nextItem.link) }
100126
}
101127
else if (nextItem.items?.length) {
102128
const visibleNextItems = nextItem.items.filter(item => !item.hidden)
103-
if (visibleNextItems.length > 0)
129+
if (visibleNextItems.length > 0) {
104130
next = { text: visibleNextItems[0].text, link: withBase(visibleNextItems[0].link) }
131+
}
105132
}
106133
}
107134
else if (sectionIndex < currentDocModule.value.sidebar.length - 1) {
@@ -113,16 +140,18 @@ export function useDocNavigation() {
113140
}
114141
else if (firstItem?.items?.length) {
115142
const visibleFirstItems = firstItem.items.filter(item => !item.hidden)
116-
if (visibleFirstItems.length > 0)
143+
if (visibleFirstItems.length > 0) {
117144
next = { text: visibleFirstItems[0].text, link: withBase(visibleFirstItems[0].link) }
145+
}
118146
}
119147
}
120148
}
121-
// Respect frontmatter booleans
149+
122150
if (frontmatter.value.prev === false)
123151
prev = null
124152
if (frontmatter.value.next === false)
125153
next = null
154+
126155
return { prev, next }
127156
})
128157

packages/nimiq-vitepress-theme/src/layout/DocNavigation.vue

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,43 @@ const { navigation, showNavigation } = useDocNavigation()
55
</script>
66

77
<template>
8-
<nav v-if="showNavigation && (navigation.prev || navigation.next)" flex="~ gap-8" justify-between f-mt-lg>
9-
<a v-if="navigation.prev" :href="navigation.prev.link" nq-hoverable grid="~ cols-[1fr_auto] rows-2 gap-8" items-center un-text-neutral-800>
10-
<div relative>
11-
<div nq-label>Previous</div>
12-
<div i-nimiq:arrow-left text-16 />
13-
<div f-text-sm>{{ navigation.prev.text }}</div>
8+
<nav v-if="showNavigation && (navigation.prev || navigation.next)" class="grid grid-cols-1 sm:grid-cols-2 gap-8" f-mt-lg>
9+
<!-- Previous Card -->
10+
<a
11+
v-if="navigation.prev"
12+
:href="navigation.prev.link"
13+
class="navigation-card navigation-card-prev group block px-6 py-8 rounded-12 border border-neutral-200 hover:bg-neutral-50 focus-visible:outline-blue-500 transition-colors bg-white"
14+
>
15+
<div class="inline-flex items-center mb-4 pl-16">
16+
<div class="i-nimiq:arrow-left size-16 pt-24 shrink-0 text-neutral-600 group-hover:text-blue-600 transition-[color,translate] group-active:-translate-x-0.5" />
1417
</div>
18+
<p class="font-medium f-text-xl text-neutral-900 mb-1 truncate pl-16">{{ navigation.prev.text }}</p>
1519
</a>
1620
<div v-else />
1721

18-
<a v-if="navigation.next" :href="navigation.next.link" nq-hoverable grid="~ cols-[1fr_auto] rows-2 gap-8" items-center un-text-neutral-800>
19-
<div relative>
20-
<div nq-label>Next</div>
21-
<div i-nimiq:arrow-right text-16 />
22-
<div f-text-sm>{{ navigation.next.text }}</div>
22+
<!-- Next Card -->
23+
<a
24+
v-if="navigation.next"
25+
:href="navigation.next.link"
26+
class="navigation-card navigation-card-next group block px-6 py-8 rounded-12 border border-neutral-200 hover:bg-neutral-50 focus-visible:outline-blue-500 transition-colors text-right bg-white"
27+
>
28+
<div class="inline-flex items-center mb-4 justify-end pr-16">
29+
<div class="i-nimiq:arrow-right size-16 pt-24 shrink-0 text-neutral-600 group-hover:text-blue-600 transition-[color,translate] group-active:translate-x-0.5" />
2330
</div>
31+
<p class="font-medium f-text-xl text-neutral-900 mb-1 truncate pr-16">{{ navigation.next.text }}</p>
2432
</a>
2533
<div v-else />
2634
</nav>
2735
</template>
36+
37+
<style scoped>
38+
.navigation-card {
39+
min-height: 120px;
40+
}
41+
42+
@media (max-width: 640px) {
43+
nav {
44+
grid-template-columns: 1fr;
45+
}
46+
}
47+
</style>

0 commit comments

Comments
 (0)