Skip to content

Commit dcc5735

Browse files
authored
feat: find nearest exclusive parent for currentNav (#395)
* feat: find nearest exclusive parent for currentNav * fix: issue with filtering * chore: remove default links * docs: add back link usage
1 parent 0f71b4a commit dcc5735

File tree

11 files changed

+77
-49
lines changed

11 files changed

+77
-49
lines changed

nuxtjs.org/components/HeaderNavigation.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export default defineComponent({
6969
const route = useRoute()
7070
const hover = ref(false)
7171
const itemIndex = ref(null)
72-
const currentNav = computed(() => $docus.currentNav.value)
72+
const currentNav = computed(() => $docus.get({ depth: 1 }).links)
7373
7474
// computed
7575
const headerLinks = computed(() =>

nuxtjs.org/content/0.discover/0.framework/index.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
---
22
title: Framework
3-
slug: framework
43
description: Framework page.
54
---
65

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
---
22
title: Features
3-
slug: features
3+
navigation:
4+
exclusive: true
45
---

nuxtjs.org/content/1.learn/2.internals/0.concepts/index.md

Whitespace-only changes.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
navigation:
3+
exclusive: true
4+
---

nuxtjs.org/content/1.learn/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
---
22
title: Learn
3+
navigation:
4+
exclusive: true
35
---

src/core/runtime/composables/navigation.ts

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,38 +47,62 @@ export const useDocusNavigation = ({ context, state, api }: DocusAddonContext) =
4747
const nav = state.navigation[locale || currentLocale] || []
4848

4949
let items = nav
50+
let match
51+
52+
// The deepest exclusive navigation that can be found based on `from`
53+
let exclusiveContent
54+
// Parent of exclusive Content
55+
let parent
5056

5157
// `from` parameter handling
5258
if (from) {
59+
let lastMatch
60+
5361
const paths = from.split('/')
5462

5563
items = paths.reduce((links: NavItem[], path: string, index: number) => {
5664
// Empty path, skip iteration
5765
if (!path) return links
5866

59-
// If we iterated on the latest path, return links
60-
if (index + 1 === paths.length) return links
61-
62-
// If this path links are only 1 long, set the current path children as root
63-
if (links.length === 1) {
64-
links = links[0].children
65-
66-
return links
67+
// Remember last matched content
68+
// This content will use as navigation parent if it has an exclusive decendant
69+
if (match && !match.shadow) {
70+
lastMatch = match
6771
}
6872

69-
// Otherwise, find matching path and get its childrens
70-
links = links.find(item => {
71-
const itemPaths = item.to.split('/')
73+
// Find matched content
74+
match = links.find(item => item.to.split('/')[index] === path)
75+
if (match) {
76+
// Update parent and exclusiveContent if the matched content marked as exclusive navigation
77+
if (match && match.navigation && match.navigation.exclusive) {
78+
parent = lastMatch || parent
79+
exclusiveContent = match
80+
}
7281

73-
return itemPaths[index] === path
74-
}).children
82+
return match.children
83+
}
7584

7685
return links
7786
}, items)
87+
88+
if (exclusiveContent) {
89+
// Use exclusive links
90+
items = exclusiveContent.children
91+
} else {
92+
items = nav
93+
}
7894
}
7995

80-
// Start filtering loop
81-
return all ? items : filterLinks(items, depth, 1)
96+
return {
97+
// matched page info
98+
title: exclusiveContent && exclusiveContent.title,
99+
to: exclusiveContent && exclusiveContent.to,
100+
navigation: exclusiveContent ? exclusiveContent.navigation : {},
101+
// matched parent
102+
parent,
103+
// filter children
104+
links: all ? items : filterLinks(items, depth, 1)
105+
}
82106
}
83107

84108
/**
@@ -120,20 +144,10 @@ export const useDocusNavigation = ({ context, state, api }: DocusAddonContext) =
120144
// eslint-disable-next-line no-unused-expressions
121145
fetchCounter.value
122146

123-
// Get links from path
124-
const links = get({
125-
from: path.value,
126-
all: true
147+
// Calcualte navigatin based on current path
148+
return get({
149+
from: path.value
127150
})
128-
129-
// Get current link
130-
const currentLink = links.find(link => link.to === path.value)
131-
132-
// Return filtered items for exclusive page
133-
if (currentLink && currentLink.navigation && currentLink.navigation.exclusive) return links
134-
135-
// Return whole navigation
136-
return get()
137151
})
138152

139153
// Update content on update.

src/core/runtime/composables/templates.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
import { pascalCase } from 'scule'
22
import Vue from 'vue'
33
import { ComputedRef } from '@nuxtjs/composition-api'
4-
import { DocusAddonContext, DocusDocument, NavItem } from '../../../types'
4+
import { DocusAddonContext, DocusCurrentNav, DocusDocument } from '../../../types'
55

6-
export const useDocusTemplates = ({ api, state }: Partial<DocusAddonContext>, currentNav: ComputedRef<NavItem[]>) => {
6+
export const useDocusTemplates = (
7+
{ api, state }: Partial<DocusAddonContext>,
8+
currentNav: ComputedRef<DocusCurrentNav>
9+
) => {
710
function getPageTemplate(page: DocusDocument) {
811
let template = typeof page.template === 'string' ? page.template : page.template?.self
912

1013
if (!template) {
1114
// Fetch from nav (root to link) and fallback to settings.template
1215
const slugs: string[] = page.to.split('/').filter(Boolean).slice(0, -1) // no need to get latest slug since it is current page
1316

14-
let links = currentNav?.value || []
17+
let { links } = currentNav?.value || {}
1518

1619
slugs.forEach((_slug: string, index: number) => {
1720
// generate full path of parent

src/core/utils/navigation.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,6 @@ const findLink = (links: NavItem[], to: string) => links.find(link => link.to ==
1414
*/
1515
const slugToTitle = title => title && title.replace(/-/g, ' ').split(' ').map(pascalCase).join(' ')
1616

17-
/**
18-
* Get a page directory index.md page if exists
19-
*/
20-
const getPageIndex = (pages, page): NavItem | undefined =>
21-
pages.find(_page => _page.dir === page.dir && _page.slug === '')
22-
2317
/**
2418
* Get navigation link for a page
2519
*/
@@ -45,6 +39,7 @@ const getPageLink = (page: any): NavItem => {
4539
return {
4640
slug,
4741
to,
42+
shadow: !!page.shadow,
4843
title: page.title,
4944
draft: page.draft,
5045
template,
@@ -117,8 +112,6 @@ function createNav(pages: any[]) {
117112
return
118113
}
119114

120-
const $index = getPageIndex(pages, _page)
121-
122115
const $page = getPageLink(_page)
123116

124117
// To: '/docs/guide/hello.md' -> dirs: ['docs', 'guide']
@@ -127,11 +120,6 @@ function createNav(pages: any[]) {
127120
// Remove the file part (except if index.md)
128121
if (_page.slug !== '') dirs = dirs.slice(0, -1)
129122

130-
// Merge index exclusive parameter
131-
if ($index && $index.navigation && $index.navigation.exclusive && $page.navigation) {
132-
$page.navigation.exclusive = $index.navigation.exclusive
133-
}
134-
135123
if (!dirs.length) {
136124
if ($page.navigation) {
137125
$page.navigation.slot = $page.navigation.slot || 'header'
@@ -154,7 +142,8 @@ function createNav(pages: any[]) {
154142
if (!link) {
155143
link = getPageLink({
156144
slug: dir,
157-
to
145+
to,
146+
shadow: true
158147
})
159148

160149
currentLinks.push(link)

src/defaultTheme/components/molecules/AsideNavigation.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@
5454
>
5555
<div class="py-4 pl-4 pr-24 sm:pl-6 lg:pr-0 lg:pt-10">
5656
<AsideTop />
57+
<NuxtLink v-if="parent" class="mb-3 block" :to="$contentLocalePath(parent.to)">
58+
<IconArrowLeft width="16" height="16" class="inline-block mr-2" /> {{ parent.title }}
59+
</NuxtLink>
5760
<ul>
5861
<template v-for="link in links">
5962
<AsideNavigationItem
@@ -78,7 +81,11 @@ import { defineComponent } from '@nuxtjs/composition-api'
7881
export default defineComponent({
7982
computed: {
8083
links() {
81-
return this.$docus.currentNav.value
84+
const nav = this.$docus.currentNav.value
85+
return nav.links
86+
},
87+
parent() {
88+
return this.$docus.currentNav.value.parent
8289
},
8390
lastRelease() {
8491
return this.$docus.lastRelease?.value

0 commit comments

Comments
 (0)