Skip to content

Commit 94f6719

Browse files
committed
feat: implement breadcrumbs
1 parent 87fe93a commit 94f6719

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { useCurrentModule } from "./useCurrentModule"
2+
import { useRoute, withBase } from 'vitepress'
3+
import { computed } from 'vue'
4+
5+
export interface Breadcrumb {
6+
text: string
7+
link?: string
8+
icon?: string
9+
}
10+
11+
export function useBreadcrumbs() {
12+
const { currentDocModule } = useCurrentModule()
13+
const route = useRoute()
14+
15+
const breadcrumbs = computed<Breadcrumb[]>(() => {
16+
const items: Breadcrumb[] = []
17+
18+
// 1. Add module info with link
19+
items.push({
20+
text: currentDocModule.value.text,
21+
link: currentDocModule.value.subpath,
22+
})
23+
24+
// Find current page in sidebar
25+
const currentSidebar = currentDocModule.value.sidebar.find(section => {
26+
return section.items.some(item =>
27+
item.link && withBase(item.link) + '/' === route.path ||
28+
(item.items?.some(subitem => withBase(subitem.link) + '/' === route.path))
29+
)
30+
})
31+
32+
// 2. Add section label if exists
33+
if (currentSidebar?.label)
34+
items.push({ text: currentSidebar.label })
35+
36+
// 3. Add parent item if exists (for nested items)
37+
const parentItem = currentSidebar?.items.find(item =>
38+
item.items?.some(subitem => withBase(subitem.link) + '/' === route.path)
39+
)
40+
if (parentItem)
41+
items.push({ text: parentItem.text })
42+
43+
// 4. Add current item
44+
const currentItem = currentSidebar?.items.find(item => item.link === route.path) ||
45+
currentSidebar?.items
46+
.find(item => item.items?.some(subitem => subitem.link === route.path))
47+
?.items?.find(subitem => subitem.link === route.path)
48+
49+
if (currentItem)
50+
items.push({ text: currentItem.text })
51+
52+
return items
53+
})
54+
55+
return {
56+
breadcrumbs
57+
}
58+
}

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { useData, useRoute } from 'vitepress'
77
import { computed, onMounted, ref, watch } from 'vue'
88
import SecondarySidebar from './SecondarySidebar.vue'
99
import { data } from '../lib/git.data'
10+
import { useBreadcrumbs } from '../composables/useBreadcrumbs'
1011
import '../assets/code-blocks.css'
1112
import '../assets/typography.css'
1213
import '../assets/github-callouts.css'
@@ -41,11 +42,21 @@ onMounted(() => {
4142
4243
const showEditContent = computed(() => theme.value.showEditContent !== false)
4344
const showLastUpdated = computed(() => theme.value.showLastUpdated !== false)
45+
46+
const { breadcrumbs } = useBreadcrumbs()
4447
</script>
4548

4649
<template>
47-
<div f-pl-xl f-pr-xs f-pt-xl f="$px $px-min-48 $px-max-72" f-pb-md flex="~ gap-16" relative h-full>
50+
<div f-pl-xl f-pr-xs f-pt-sm f="$px $px-min-48 $px-max-72" f-pb-md flex="~ gap-16" relative h-full>
4851
<div flex="~ col" h-full flex-1 w="[calc(100vw-2*var(--nq-sidebar-width)-2*var(--f-px))]">
52+
<ul px-32 f-pb-lg flex="~ items-center gap-12">
53+
<li v-for="({text, icon},i) in breadcrumbs" :key="text" contents w-max>
54+
<div v-if="icon" :class="icon" />
55+
<span nq-label f-text-2xs w-max>{{ text }}</span>
56+
<div i-nimiq:chevron-right text="neutral-700 9" v-if="i < breadcrumbs.length - 1" />
57+
</li>
58+
</ul>
59+
4960
<article flex-1 class="nq-prose" var:nq-prose-max-width:none>
5061
<Content max-w-none />
5162
</article>

0 commit comments

Comments
 (0)