Small addition to the language interface
This commit is contained in:
parent
a22cd05c61
commit
c1796919c7
128
docs/.vuepress/components/LanguageDropdown.vue
Normal file
128
docs/.vuepress/components/LanguageDropdown.vue
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<!-- user links -->
|
||||||
|
<div class="nav-links">
|
||||||
|
<div
|
||||||
|
v-for="item in userLinks"
|
||||||
|
:key="item.link"
|
||||||
|
>
|
||||||
|
<DropdownLink
|
||||||
|
v-if="item.type === 'links'"
|
||||||
|
:item="item"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import DropdownLink from '@theme/components/DropdownLink.vue'
|
||||||
|
import { resolveNavLinkItem } from '@parent-theme/util'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'LanguageDropdown',
|
||||||
|
|
||||||
|
components: {
|
||||||
|
DropdownLink
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
nav () {
|
||||||
|
console.log("Trying to load lang")
|
||||||
|
const { locales } = this.$site
|
||||||
|
if (locales && Object.keys(locales).length > 1) {
|
||||||
|
const currentLink = this.$page.path
|
||||||
|
const routes = this.$router.options.routes
|
||||||
|
const themeLocales = this.$site.themeConfig.locales || {}
|
||||||
|
|
||||||
|
const langauges = Object.keys(locales).map(path => {
|
||||||
|
const locale = locales[path]
|
||||||
|
const text = themeLocales[path] && themeLocales[path].label || locale.lang
|
||||||
|
let link
|
||||||
|
// Stay on the current page
|
||||||
|
if (locale.lang === this.$lang) {
|
||||||
|
link = currentLink
|
||||||
|
} else {
|
||||||
|
// Try to stay on the same page
|
||||||
|
link = currentLink.replace(this.$localeConfig.path, path)
|
||||||
|
// fallback to homepage
|
||||||
|
if (!routes.some(route => route.path === link)) {
|
||||||
|
link = path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const group = locale.group
|
||||||
|
|
||||||
|
return { text, link, group }
|
||||||
|
})
|
||||||
|
let groupedLangauges = {}
|
||||||
|
let ungroupedLangauges = []
|
||||||
|
|
||||||
|
langauges.forEach(langauge => {
|
||||||
|
if (langauge.group) {
|
||||||
|
if (groupedLangauges[langauge.group] == null) {
|
||||||
|
groupedLangauges[langauge.group] = {
|
||||||
|
text: langauge.group,
|
||||||
|
items: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
groupedLangauges[langauge.group].items.push(langauge)
|
||||||
|
} else {
|
||||||
|
ungroupedLangauges.push(langauge)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const languageDropdown = {
|
||||||
|
text: this.$themeLocaleConfig.selectText || 'Languages',
|
||||||
|
ariaLabel: this.$themeLocaleConfig.ariaLabel || 'Select language',
|
||||||
|
items: Object.values(groupedLangauges).concat(ungroupedLangauges)
|
||||||
|
}
|
||||||
|
return [languageDropdown]
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
},
|
||||||
|
|
||||||
|
userLinks () {
|
||||||
|
return (this.nav || []).map(link => {
|
||||||
|
return Object.assign(resolveNavLinkItem(link), {
|
||||||
|
items: (link.items || []).map(resolveNavLinkItem)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus">
|
||||||
|
.nav-dropdown
|
||||||
|
top: auto
|
||||||
|
right auto
|
||||||
|
.nav-links
|
||||||
|
display inline-block
|
||||||
|
a
|
||||||
|
line-height 1.4rem
|
||||||
|
color inherit
|
||||||
|
&:hover, &.router-link-active
|
||||||
|
color $accentColor
|
||||||
|
.nav-item
|
||||||
|
position relative
|
||||||
|
display inline-block
|
||||||
|
margin-left 1.5rem
|
||||||
|
line-height 2rem
|
||||||
|
&:first-child
|
||||||
|
margin-left 0
|
||||||
|
.repo-link
|
||||||
|
margin-left 1.5rem
|
||||||
|
|
||||||
|
@media (max-width: $MQMobile)
|
||||||
|
.nav-links
|
||||||
|
.nav-item, .repo-link
|
||||||
|
margin-left 0
|
||||||
|
|
||||||
|
@media (min-width: $MQMobile)
|
||||||
|
.nav-links a
|
||||||
|
&:hover, &.router-link-active
|
||||||
|
color $textColor
|
||||||
|
.nav-item > a:not(.external)
|
||||||
|
&:hover, &.router-link-active
|
||||||
|
margin-bottom -2px
|
||||||
|
border-bottom 2px solid lighten($accentColor, 8%)
|
||||||
|
</style>
|
230
docs/.vuepress/theme/components/DropdownLink.vue
Normal file
230
docs/.vuepress/theme/components/DropdownLink.vue
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="dropdown-wrapper"
|
||||||
|
:class="{ open }"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="dropdown-title"
|
||||||
|
type="button"
|
||||||
|
:aria-label="dropdownAriaLabel"
|
||||||
|
@click="setOpen(!open)"
|
||||||
|
>
|
||||||
|
<span class="title">{{ item.text }}</span>
|
||||||
|
<span
|
||||||
|
class="arrow"
|
||||||
|
:class="open ? 'down' : 'right'"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<DropdownTransition>
|
||||||
|
<ul
|
||||||
|
v-show="open"
|
||||||
|
class="nav-dropdown"
|
||||||
|
>
|
||||||
|
<li
|
||||||
|
v-for="(subItem, index) in item.items"
|
||||||
|
:key="subItem.link || index"
|
||||||
|
class="dropdown-item"
|
||||||
|
>
|
||||||
|
<h4 v-if="subItem.type === 'links'">
|
||||||
|
{{ subItem.text }}
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<ul
|
||||||
|
v-if="subItem.type === 'links'"
|
||||||
|
class="dropdown-subitem-wrapper"
|
||||||
|
>
|
||||||
|
<li
|
||||||
|
v-for="childSubItem in subItem.items"
|
||||||
|
:key="childSubItem.link"
|
||||||
|
class="dropdown-subitem"
|
||||||
|
>
|
||||||
|
<NavLink
|
||||||
|
:item="childSubItem"
|
||||||
|
@focusout="
|
||||||
|
isLastItemOfArray(childSubItem, subItem.items) &&
|
||||||
|
isLastItemOfArray(subItem, item.items) &&
|
||||||
|
setOpen(false)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<NavLink
|
||||||
|
v-else
|
||||||
|
:item="subItem"
|
||||||
|
@focusout="isLastItemOfArray(subItem, item.items) && setOpen(false)"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</DropdownTransition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import NavLink from '@theme/components/NavLink.vue'
|
||||||
|
import DropdownTransition from '@theme/components/DropdownTransition.vue'
|
||||||
|
import last from 'lodash/last'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'DropdownLink',
|
||||||
|
|
||||||
|
components: {
|
||||||
|
NavLink,
|
||||||
|
DropdownTransition
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
item: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
open: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
dropdownAriaLabel () {
|
||||||
|
return this.item.ariaLabel || this.item.text
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
$route () {
|
||||||
|
this.open = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
setOpen (value) {
|
||||||
|
this.open = value
|
||||||
|
},
|
||||||
|
|
||||||
|
isLastItemOfArray (item, array) {
|
||||||
|
return last(array) === item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus">
|
||||||
|
.dropdown-wrapper
|
||||||
|
cursor pointer
|
||||||
|
.dropdown-title
|
||||||
|
display block
|
||||||
|
font-size 0.9rem
|
||||||
|
font-family inherit
|
||||||
|
cursor inherit
|
||||||
|
padding inherit
|
||||||
|
line-height 1.4rem
|
||||||
|
background transparent
|
||||||
|
border none
|
||||||
|
font-weight 500
|
||||||
|
color $textColor
|
||||||
|
&:hover
|
||||||
|
border-color transparent
|
||||||
|
.arrow
|
||||||
|
vertical-align middle
|
||||||
|
margin-top -1px
|
||||||
|
margin-left 0.4rem
|
||||||
|
.nav-dropdown
|
||||||
|
.dropdown-item
|
||||||
|
color inherit
|
||||||
|
line-height 1.7rem
|
||||||
|
h4
|
||||||
|
margin 0.45rem 0 0
|
||||||
|
border-top 1px solid #eee
|
||||||
|
padding 0.45rem 1.5rem 0 1.25rem
|
||||||
|
.dropdown-subitem-wrapper
|
||||||
|
padding 0
|
||||||
|
list-style none
|
||||||
|
.dropdown-subitem
|
||||||
|
font-size 0.9em
|
||||||
|
a
|
||||||
|
display block
|
||||||
|
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 3px solid transparent
|
||||||
|
border-bottom 3px solid transparent
|
||||||
|
position absolute
|
||||||
|
top calc(50% - 2px)
|
||||||
|
left 9px
|
||||||
|
&:first-child h4
|
||||||
|
margin-top 0
|
||||||
|
padding-top 0
|
||||||
|
border-top 0
|
||||||
|
|
||||||
|
@media (max-width: $MQMobile)
|
||||||
|
.dropdown-wrapper
|
||||||
|
&.open .dropdown-title
|
||||||
|
margin-bottom 0.5rem
|
||||||
|
.dropdown-title
|
||||||
|
font-weight 600
|
||||||
|
font-size inherit
|
||||||
|
&:hover
|
||||||
|
color $accentColor
|
||||||
|
.nav-dropdown
|
||||||
|
transition height .1s ease-out
|
||||||
|
overflow hidden
|
||||||
|
.dropdown-item
|
||||||
|
h4
|
||||||
|
border-top 0
|
||||||
|
margin-top 0
|
||||||
|
padding-top 0
|
||||||
|
h4, & > a
|
||||||
|
font-size 15px
|
||||||
|
line-height 2rem
|
||||||
|
.dropdown-subitem
|
||||||
|
font-size 14px
|
||||||
|
padding-left 1rem
|
||||||
|
|
||||||
|
@media (min-width: $MQMobile)
|
||||||
|
.dropdown-wrapper
|
||||||
|
height 1.8rem
|
||||||
|
&:hover .nav-dropdown,
|
||||||
|
&.open .nav-dropdown
|
||||||
|
// override the inline style.
|
||||||
|
display block !important
|
||||||
|
&.open:blur
|
||||||
|
display none
|
||||||
|
.dropdown-title .arrow
|
||||||
|
// make the arrow always down at desktop
|
||||||
|
border-left 4px solid transparent
|
||||||
|
border-right 4px solid transparent
|
||||||
|
border-top 6px solid $arrowBgColor
|
||||||
|
border-bottom 0
|
||||||
|
.nav-dropdown
|
||||||
|
display none
|
||||||
|
// Avoid height shaked by clicking
|
||||||
|
height auto !important
|
||||||
|
box-sizing border-box;
|
||||||
|
max-height calc(100vh - 2.7rem)
|
||||||
|
overflow-y auto
|
||||||
|
position absolute
|
||||||
|
top auto
|
||||||
|
right auto
|
||||||
|
background-color #fff
|
||||||
|
padding 0.6rem 0
|
||||||
|
border 1px solid #ddd
|
||||||
|
border-bottom-color #ccc
|
||||||
|
text-align left
|
||||||
|
border-radius 0.25rem
|
||||||
|
white-space nowrap
|
||||||
|
margin 0
|
||||||
|
</style>
|
Loading…
x
Reference in New Issue
Block a user