Skip to content

Commit

Permalink
feat: find nearest exclusive parent for currentNav (#395)
Browse files Browse the repository at this point in the history
* feat: find nearest exclusive parent for currentNav

* fix: issue with filtering

* chore: remove default links

* docs: add back link usage
  • Loading branch information
farnabaz authored Jun 9, 2021
1 parent 0f71b4a commit dcc5735
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 49 deletions.
2 changes: 1 addition & 1 deletion nuxtjs.org/components/HeaderNavigation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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(() =>
Expand Down
1 change: 0 additions & 1 deletion nuxtjs.org/content/0.discover/0.framework/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
title: Framework
slug: framework
description: Framework page.
---

Expand Down
3 changes: 2 additions & 1 deletion nuxtjs.org/content/0.discover/1.features/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
title: Features
slug: features
navigation:
exclusive: true
---
Empty file.
4 changes: 4 additions & 0 deletions nuxtjs.org/content/1.learn/2.internals/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
navigation:
exclusive: true
---
2 changes: 2 additions & 0 deletions nuxtjs.org/content/1.learn/index.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
---
title: Learn
navigation:
exclusive: true
---
70 changes: 42 additions & 28 deletions src/core/runtime/composables/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

/**
Expand Down Expand Up @@ -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.
Expand Down
9 changes: 6 additions & 3 deletions src/core/runtime/composables/templates.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
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<DocusAddonContext>, currentNav: ComputedRef<NavItem[]>) => {
export const useDocusTemplates = (
{ api, state }: Partial<DocusAddonContext>,
currentNav: ComputedRef<DocusCurrentNav>
) => {
function getPageTemplate(page: DocusDocument) {
let template = typeof page.template === 'string' ? page.template : page.template?.self

if (!template) {
// 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
Expand Down
17 changes: 3 additions & 14 deletions src/core/utils/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -45,6 +39,7 @@ const getPageLink = (page: any): NavItem => {
return {
slug,
to,
shadow: !!page.shadow,
title: page.title,
draft: page.draft,
template,
Expand Down Expand Up @@ -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']
Expand All @@ -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'
Expand All @@ -154,7 +142,8 @@ function createNav(pages: any[]) {
if (!link) {
link = getPageLink({
slug: dir,
to
to,
shadow: true
})

currentLinks.push(link)
Expand Down
9 changes: 8 additions & 1 deletion src/defaultTheme/components/molecules/AsideNavigation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
>
<div class="py-4 pl-4 pr-24 sm:pl-6 lg:pr-0 lg:pt-10">
<AsideTop />
<NuxtLink v-if="parent" class="mb-3 block" :to="$contentLocalePath(parent.to)">
<IconArrowLeft width="16" height="16" class="inline-block mr-2" /> {{ parent.title }}
</NuxtLink>
<ul>
<template v-for="link in links">
<AsideNavigationItem
Expand All @@ -78,7 +81,11 @@ import { defineComponent } from '@nuxtjs/composition-api'
export default defineComponent({
computed: {
links() {
return this.$docus.currentNav.value
const nav = this.$docus.currentNav.value
return nav.links
},
parent() {
return this.$docus.currentNav.value.parent
},
lastRelease() {
return this.$docus.lastRelease?.value
Expand Down
9 changes: 9 additions & 0 deletions src/types/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface NavItem {
slug: string
to: string
title: string
shadow: boolean
draft?: boolean
template?: {
self: string
Expand All @@ -49,6 +50,14 @@ export type DocusNavigation = {
[language: string]: NavItem[]
}

export type DocusCurrentNav = {
title?: string
to?: string
navigation?: NavItemNavigationConfig | false
parent?: NavItem
links: NavItem[]
}

export interface DocusDocument {
// FrontMatter
title: string
Expand Down

0 comments on commit dcc5735

Please sign in to comment.