From dcc5735816bc30d900fa7700114bd6d0b69d2896 Mon Sep 17 00:00:00 2001 From: Ahad Birang Date: Wed, 9 Jun 2021 23:54:11 +0430 Subject: [PATCH] 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 --- nuxtjs.org/components/HeaderNavigation.vue | 2 +- .../content/0.discover/0.framework/index.md | 1 - .../content/0.discover/1.features/index.md | 3 +- .../1.learn/2.internals/0.concepts/index.md | 0 .../content/1.learn/2.internals/index.md | 4 ++ nuxtjs.org/content/1.learn/index.md | 2 + src/core/runtime/composables/navigation.ts | 70 +++++++++++-------- src/core/runtime/composables/templates.ts | 9 ++- src/core/utils/navigation.ts | 17 +---- .../components/molecules/AsideNavigation.vue | 9 ++- src/types/core.ts | 9 +++ 11 files changed, 77 insertions(+), 49 deletions(-) create mode 100644 nuxtjs.org/content/1.learn/2.internals/0.concepts/index.md create mode 100644 nuxtjs.org/content/1.learn/2.internals/index.md diff --git a/nuxtjs.org/components/HeaderNavigation.vue b/nuxtjs.org/components/HeaderNavigation.vue index dc91ebf0f..0ab3e5e74 100644 --- a/nuxtjs.org/components/HeaderNavigation.vue +++ b/nuxtjs.org/components/HeaderNavigation.vue @@ -69,7 +69,7 @@ export default defineComponent({ const route = useRoute() const hover = ref(false) const itemIndex = ref(null) - const currentNav = computed(() => $docus.currentNav.value) + const currentNav = computed(() => $docus.get({ depth: 1 }).links) // computed const headerLinks = computed(() => diff --git a/nuxtjs.org/content/0.discover/0.framework/index.md b/nuxtjs.org/content/0.discover/0.framework/index.md index a6add87ff..6b073596f 100644 --- a/nuxtjs.org/content/0.discover/0.framework/index.md +++ b/nuxtjs.org/content/0.discover/0.framework/index.md @@ -1,6 +1,5 @@ --- title: Framework -slug: framework description: Framework page. --- diff --git a/nuxtjs.org/content/0.discover/1.features/index.md b/nuxtjs.org/content/0.discover/1.features/index.md index 9f615462d..292166477 100644 --- a/nuxtjs.org/content/0.discover/1.features/index.md +++ b/nuxtjs.org/content/0.discover/1.features/index.md @@ -1,4 +1,5 @@ --- title: Features -slug: features +navigation: + exclusive: true --- diff --git a/nuxtjs.org/content/1.learn/2.internals/0.concepts/index.md b/nuxtjs.org/content/1.learn/2.internals/0.concepts/index.md new file mode 100644 index 000000000..e69de29bb diff --git a/nuxtjs.org/content/1.learn/2.internals/index.md b/nuxtjs.org/content/1.learn/2.internals/index.md new file mode 100644 index 000000000..a10e9b982 --- /dev/null +++ b/nuxtjs.org/content/1.learn/2.internals/index.md @@ -0,0 +1,4 @@ +--- +navigation: + exclusive: true +--- \ No newline at end of file diff --git a/nuxtjs.org/content/1.learn/index.md b/nuxtjs.org/content/1.learn/index.md index 0a8061f64..7f963c96b 100644 --- a/nuxtjs.org/content/1.learn/index.md +++ b/nuxtjs.org/content/1.learn/index.md @@ -1,3 +1,5 @@ --- title: Learn +navigation: + exclusive: true --- diff --git a/src/core/runtime/composables/navigation.ts b/src/core/runtime/composables/navigation.ts index b0fc8e69e..f6d97316a 100644 --- a/src/core/runtime/composables/navigation.ts +++ b/src/core/runtime/composables/navigation.ts @@ -47,38 +47,62 @@ export const useDocusNavigation = ({ context, state, api }: DocusAddonContext) = const nav = state.navigation[locale || currentLocale] || [] let items = nav + let match + + // The deepest exclusive navigation that can be found based on `from` + let exclusiveContent + // Parent of exclusive Content + let parent // `from` parameter handling if (from) { + let lastMatch + const paths = from.split('/') items = paths.reduce((links: NavItem[], path: string, index: number) => { // Empty path, skip iteration if (!path) return links - // If we iterated on the latest path, return links - if (index + 1 === paths.length) return links - - // If this path links are only 1 long, set the current path children as root - if (links.length === 1) { - links = links[0].children - - return links + // Remember last matched content + // This content will use as navigation parent if it has an exclusive decendant + if (match && !match.shadow) { + lastMatch = match } - // Otherwise, find matching path and get its childrens - links = links.find(item => { - const itemPaths = item.to.split('/') + // Find matched content + match = links.find(item => item.to.split('/')[index] === path) + if (match) { + // Update parent and exclusiveContent if the matched content marked as exclusive navigation + if (match && match.navigation && match.navigation.exclusive) { + parent = lastMatch || parent + exclusiveContent = match + } - return itemPaths[index] === path - }).children + return match.children + } return links }, items) + + if (exclusiveContent) { + // Use exclusive links + items = exclusiveContent.children + } else { + items = nav + } } - // Start filtering loop - return all ? items : filterLinks(items, depth, 1) + return { + // matched page info + title: exclusiveContent && exclusiveContent.title, + to: exclusiveContent && exclusiveContent.to, + navigation: exclusiveContent ? exclusiveContent.navigation : {}, + // matched parent + parent, + // filter children + links: all ? items : filterLinks(items, depth, 1) + } } /** @@ -120,20 +144,10 @@ export const useDocusNavigation = ({ context, state, api }: DocusAddonContext) = // eslint-disable-next-line no-unused-expressions fetchCounter.value - // Get links from path - const links = get({ - from: path.value, - all: true + // Calcualte navigatin based on current path + return get({ + from: path.value }) - - // Get current link - const currentLink = links.find(link => link.to === path.value) - - // Return filtered items for exclusive page - if (currentLink && currentLink.navigation && currentLink.navigation.exclusive) return links - - // Return whole navigation - return get() }) // Update content on update. diff --git a/src/core/runtime/composables/templates.ts b/src/core/runtime/composables/templates.ts index 9d2160243..a7a7c1f9c 100644 --- a/src/core/runtime/composables/templates.ts +++ b/src/core/runtime/composables/templates.ts @@ -1,9 +1,12 @@ import { pascalCase } from 'scule' import Vue from 'vue' import { ComputedRef } from '@nuxtjs/composition-api' -import { DocusAddonContext, DocusDocument, NavItem } from '../../../types' +import { DocusAddonContext, DocusCurrentNav, DocusDocument } from '../../../types' -export const useDocusTemplates = ({ api, state }: Partial, currentNav: ComputedRef) => { +export const useDocusTemplates = ( + { api, state }: Partial, + currentNav: ComputedRef +) => { function getPageTemplate(page: DocusDocument) { let template = typeof page.template === 'string' ? page.template : page.template?.self @@ -11,7 +14,7 @@ export const useDocusTemplates = ({ api, state }: Partial, cu // Fetch from nav (root to link) and fallback to settings.template const slugs: string[] = page.to.split('/').filter(Boolean).slice(0, -1) // no need to get latest slug since it is current page - let links = currentNav?.value || [] + let { links } = currentNav?.value || {} slugs.forEach((_slug: string, index: number) => { // generate full path of parent diff --git a/src/core/utils/navigation.ts b/src/core/utils/navigation.ts index 847e2ba7f..882246867 100644 --- a/src/core/utils/navigation.ts +++ b/src/core/utils/navigation.ts @@ -14,12 +14,6 @@ const findLink = (links: NavItem[], to: string) => links.find(link => link.to == */ const slugToTitle = title => title && title.replace(/-/g, ' ').split(' ').map(pascalCase).join(' ') -/** - * Get a page directory index.md page if exists - */ -const getPageIndex = (pages, page): NavItem | undefined => - pages.find(_page => _page.dir === page.dir && _page.slug === '') - /** * Get navigation link for a page */ @@ -45,6 +39,7 @@ const getPageLink = (page: any): NavItem => { return { slug, to, + shadow: !!page.shadow, title: page.title, draft: page.draft, template, @@ -117,8 +112,6 @@ function createNav(pages: any[]) { return } - const $index = getPageIndex(pages, _page) - const $page = getPageLink(_page) // To: '/docs/guide/hello.md' -> dirs: ['docs', 'guide'] @@ -127,11 +120,6 @@ function createNav(pages: any[]) { // Remove the file part (except if index.md) if (_page.slug !== '') dirs = dirs.slice(0, -1) - // Merge index exclusive parameter - if ($index && $index.navigation && $index.navigation.exclusive && $page.navigation) { - $page.navigation.exclusive = $index.navigation.exclusive - } - if (!dirs.length) { if ($page.navigation) { $page.navigation.slot = $page.navigation.slot || 'header' @@ -154,7 +142,8 @@ function createNav(pages: any[]) { if (!link) { link = getPageLink({ slug: dir, - to + to, + shadow: true }) currentLinks.push(link) diff --git a/src/defaultTheme/components/molecules/AsideNavigation.vue b/src/defaultTheme/components/molecules/AsideNavigation.vue index 129c3b913..6c0b0ea9c 100644 --- a/src/defaultTheme/components/molecules/AsideNavigation.vue +++ b/src/defaultTheme/components/molecules/AsideNavigation.vue @@ -54,6 +54,9 @@ >
+ + {{ parent.title }} +