Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dropdown Items in Navbar #13

Merged
merged 23 commits into from
Apr 16, 2018
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ https://vuepress.vuejs.org/

VuePress is still a work in progress. There are a few things that it currently does not support but are planned:

- Dropdown Items in Navbar
- Multi-Language Support
- Algolia DocSearch Integration
- Blogging support
Expand Down
94 changes: 94 additions & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,100 @@ module.exports = {
{
text: 'Default Theme Config',
link: '/default-theme-config/'
},
{
text: 'Links',
items: [
{
text: 'Vue',
link: 'https://vuejs.org/',
},
{
text: 'Vue-Router',
link: 'https://router.vuejs.org/en/',
},
{
text: 'Vue-CLI',
link: 'https://github.com/vuejs/vue-cli/blob/dev/docs/README.md',
},
{
text: 'Vue-Press',
link: '/',
},
]
},
{
text: 'Ecosystem',
items: [
{
text: 'Help',
items: [
{
text: 'Forum',
link: 'https://forum.vuejs.org/'
},
{
text: 'Chat',
link: 'https://chat.vuejs.org/'
}
]
},
{
text: 'Tooling',
items: [
{
text: 'Devtools',
link: 'https://github.com/vuejs/vue-devtools'
},
{
text: 'Webpack Template',
link: 'https://vuejs-templates.github.io/webpack'
},
{
text: 'Vue Loader',
link: 'https://vue-loader.vuejs.org'
}
]
},
{
text: 'News',
items: [
{
text: 'Weekly News',
link: 'https://news.vuejs.org'
},
{
text: 'Roadmap',
link: 'https://github.com/vuejs/roadmap'
},
{
text: 'Twitter',
link: 'https://twitter.com/vuejs'
},
{
text: 'Blog',
link: 'https://medium.com/the-vue-point'
},
{
text: 'Jobs',
link: 'https://vuejobs.com/?ref=vuejs'
}
]
},
{
text: 'Resource Lists',
items: [
{
text: 'Vue Curated',
link: 'ttps://curated.vuejs.org/'
},
{
text: 'Awesome Vue',
link: 'https://github.com/vuejs/awesome-vue'
}
]
}
]
}
],
sidebar: {
Expand Down
18 changes: 18 additions & 0 deletions docs/default-theme-config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,24 @@ module.exports = {
}
```

Those links can also be dropdown menus, add nested items via `items`:

```js
module.exports = {
themeConfig: {
nav: [
{
text: 'Languages',
items: [
{ text: 'Chinese', link: '/language/chinese' },
{ text: 'Japanese', link: '/language/japanese' }
]
}
]
}
}
```

## Sidebar

To enable the sidebar, use `themeConfig.sidebar`. The basic configuration expects an Array of links:
Expand Down
1 change: 0 additions & 1 deletion docs/guide/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ Each markdown file is compiled into HTML with [markdown-it](https://github.com/m

VuePress is still a work in progress. There are a few things that it currently does not support but are planned:

- Dropdown Items in Navbar
- Multi-Language Support
- Algolia DocSearch Integration
- Blogging support
Expand Down
33 changes: 33 additions & 0 deletions lib/default-theme/NavLink.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<template>
<router-link
class="router-link"
:to="link"
v-if="!isExternal(link)"
exact
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See 67c758e, should only be exact for the homepage.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed at 96a6cc6.

>{{ item.text }}</router-link>
<a
v-else
:href="link"
target="_blank"
class="router-link"
>{{ item.text }}</a>
</template>

<script>
import { isExternal, ensureExt } from './util'
export default {
props: {
item: {
required: true
}
},
computed: {
link() {
return ensureExt(this.item.link)
}
},
methods: {
isExternal
}
}
</script>
137 changes: 118 additions & 19 deletions lib/default-theme/NavLinks.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
<template>
<nav class="nav-links" v-if="userLinks.length || githubLink">
<!-- user links -->
<router-link v-for="item in userLinks"
:to="item.link"
<div
class="nav-item"
v-for="item in userLinks"
:key="item.link">
{{ item.text }}
</router-link>
<div
v-if="item.type === 'links'"
class="dropdown-wrapper">
<span class="dropdown-title">{{ item.text }}</span>
<span class="arrow"></span>
<ul class="nav-dropdown">
<li
v-for="subItem in item.items"
:key="subItem.link">
<h4 v-if="subItem.type === 'links'">{{ subItem.text }}</h4>
<ul v-if="subItem.type === 'links'">
<li
v-for="childSubItem in subItem.items"
:key="childSubItem.link">
<nav-link :item="childSubItem"></nav-link>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some conflicts due to fixes which are also addressed in this PR. Should be easy to resolve.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All conflict has been resolved.

</li>
</ul>
<nav-link v-else :item="subItem"></nav-link>
</li>
</ul>
</div>
<nav-link v-else :item="item"></nav-link>
</div>
<!-- github link -->
<a v-if="githubLink"
:href="githubLink"
Expand All @@ -20,15 +42,17 @@

<script>
import OutboundLink from './OutboundLink.vue'
import { isActive, ensureExt } from './util'
import NavLink from './NavLink.vue'
import { isActive, resolveNavLinkItem } from './util'

export default {
components: { OutboundLink },
components: { OutboundLink, NavLink },
computed: {
userLinks () {
return (this.$site.themeConfig.nav || []).map(item => ({
text: item.text,
link: ensureExt(item.link)
return (this.$site.themeConfig.nav || []).map((link => {
return Object.assign(resolveNavLinkItem(link), {
items: (link.items || []).map(resolveNavLinkItem)
})
}))
},
githubLink () {
Expand All @@ -52,21 +76,96 @@ export default {
.nav-links
display inline-block
a
color inherit
font-weight 500
line-height 1.25rem
margin-left 1.5rem
color inherit
&:hover, &.router-link-active
color $accentColor
.nav-item
position relative
display inline-block
margin-left 1.5rem
font-weight 500
line-height 2rem
.dropdown-wrapper
&:hover .nav-dropdown
display block
.arrow
display inline-block
vertical-align middle
margin-top -1px
margin-left 6px
width 0
height 0
border-left 4px solid transparent
border-right 4px solid transparent
border-top 5px solid #ccc
.nav-dropdown
li
color inherit
line-height 1.7rem
a
display block
height 1.7rem
line-height 1.7rem
position relative
border-bottom none
font-weight 400
margin-bottom 0
padding 0 1.5rem 0 1.25rem
&:hover
color $accentColor
&.router-link-active
color $accentColor
&::after
content ""
width 0
height 0
border-left 5px solid $accentColor
border-top 4px solid transparent
border-bottom 4px solid transparent
position absolute
top calc(50% - 3px)
left 10px
&:first-child h4
margin-top 0
padding-top 0
border-top 0
& > h4
margin 0.45rem 0 0
border-top 1px solid #eee
padding 0.45rem 1.5rem 0 1.25rem
& > ul
padding 0
list-style none
.github-link
margin-left 1.5rem

@media (max-width: $MQMobile)
.nav-links a
margin-left 0
.nav-links
.nav-item, .github-link
margin-left 0

@media (min-width: $MQMobile)
.nav-links a
&:hover, &.router-link-active
color $textColor
margin-bottom -2px
border-bottom 2px solid lighten($accentColor, 5%)
.nav-links
a
&:hover, &.router-link-active
color $textColor
margin-bottom -2px
border-bottom 2px solid lighten($accentColor, 5%)
.nav-dropdown
display none
box-sizing border-box;
max-height calc(100vh - 2.7rem)
overflow-y auto
position absolute
top 100%
right 0
background-color #fff
padding 10px 0
border 1px solid #ddd
border-bottom-color #ccc
text-align left
border-radius 0.25rem
white-space nowrap
margin 0
</style>
17 changes: 16 additions & 1 deletion lib/default-theme/Sidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,26 @@ function resolveOpenGroupIndex (route, items) {
display none
border-bottom 1px solid $borderColor
padding 0.5rem 0 0.75rem 0
a
.nav-item, .github-link
display block
line-height 1.25rem
font-weight 600
font-size 1.1em
padding 0.5rem 0 0.5rem 1.5rem
.nav-item .dropdown-wrapper
.dropdown-title
display inline-block
margin-bottom 5px
.nav-dropdown
li, h4
font-size 15px
line-height 1.7rem
h4
border-top 0
margin-top 0
padding-top 0
ul > li
padding-left 1rem
.sidebar-links
margin-top 1.5rem

Expand Down
12 changes: 11 additions & 1 deletion lib/default-theme/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ export function getHash (path) {
}
}

export function isExternal (path) {
return outboundRE.test(path)
}

export function ensureExt (path) {
if (outboundRE.test(path)) {
if (isExternal(path)) {
return path
}
const hashMatch = path.match(hashRE)
Expand Down Expand Up @@ -147,6 +151,12 @@ export function groupHeaders (headers) {
return headers.filter(h => h.level === 2)
}

export function resolveNavLinkItem (linkItem) {
return Object.assign(linkItem, {
type: linkItem.items && linkItem.items.length ? 'links' : 'link'
})
}

function resolveMatchingSidebarConfig (route, sidebarConfig) {
if (Array.isArray(sidebarConfig)) {
return {
Expand Down