mirror of https://github.com/vuejs/vitepress
refactor: migrate default theme to use script-setup (#137)
Co-authored-by: Kia King Ishii <kia.king.08@gmail.com>pull/156/head
parent
136a56e74d
commit
b127aeeaf1
@ -1,77 +0,0 @@
|
|||||||
import { defineComponent, computed, PropType } from 'vue'
|
|
||||||
import { useRoute } from 'vitepress'
|
|
||||||
import { withBase, isExternal } from '../utils'
|
|
||||||
import { DefaultTheme } from '../config'
|
|
||||||
import OutboundLink from './icons/OutboundLink.vue'
|
|
||||||
|
|
||||||
const normalizePath = (path: string): string => {
|
|
||||||
path = path
|
|
||||||
.replace(/#.*$/, '')
|
|
||||||
.replace(/\?.*$/, '')
|
|
||||||
.replace(/\.html$/, '')
|
|
||||||
if (path.endsWith('/')) {
|
|
||||||
path += 'index'
|
|
||||||
}
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
components: {
|
|
||||||
OutboundLink
|
|
||||||
},
|
|
||||||
|
|
||||||
props: {
|
|
||||||
item: {
|
|
||||||
type: Object as PropType<DefaultTheme.NavItemWithLink>,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setup(props) {
|
|
||||||
const item = props.item
|
|
||||||
|
|
||||||
const route = useRoute()
|
|
||||||
|
|
||||||
const classes = computed(() => ({
|
|
||||||
active: isActiveLink.value,
|
|
||||||
external: isExternalLink.value
|
|
||||||
}))
|
|
||||||
|
|
||||||
const isActiveLink = computed(() => {
|
|
||||||
return normalizePath(withBase(item.link)) === normalizePath(route.path)
|
|
||||||
})
|
|
||||||
|
|
||||||
const isExternalLink = computed(() => {
|
|
||||||
return isExternal(item.link)
|
|
||||||
})
|
|
||||||
|
|
||||||
const href = computed(() => {
|
|
||||||
return isExternalLink.value ? item.link : withBase(item.link)
|
|
||||||
})
|
|
||||||
|
|
||||||
const target = computed(() => {
|
|
||||||
if (item.target) {
|
|
||||||
return item.target
|
|
||||||
}
|
|
||||||
|
|
||||||
return isExternalLink.value ? '_blank' : ''
|
|
||||||
})
|
|
||||||
|
|
||||||
const rel = computed(() => {
|
|
||||||
if (item.rel) {
|
|
||||||
return item.rel
|
|
||||||
}
|
|
||||||
|
|
||||||
return isExternalLink.value ? 'noopener noreferrer' : ''
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
classes,
|
|
||||||
isActiveLink,
|
|
||||||
isExternalLink,
|
|
||||||
href,
|
|
||||||
target,
|
|
||||||
rel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
@ -1,101 +0,0 @@
|
|||||||
import { computed } from 'vue'
|
|
||||||
import { useSiteData, useSiteDataByRoute, useRoute } from 'vitepress'
|
|
||||||
import { inBrowser } from '/@app/utils'
|
|
||||||
import NavBarLink from './NavBarLink.vue'
|
|
||||||
import NavDropdownLink from './NavDropdownLink.vue'
|
|
||||||
import { DefaultTheme } from '../config'
|
|
||||||
|
|
||||||
const platforms = ['GitHub', 'GitLab', 'Bitbucket'].map(
|
|
||||||
(platform) => [platform, new RegExp(platform, 'i')] as const
|
|
||||||
)
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
NavBarLink,
|
|
||||||
NavDropdownLink
|
|
||||||
},
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
const siteDataByRoute = useSiteDataByRoute()
|
|
||||||
const siteData = useSiteData()
|
|
||||||
const route = useRoute()
|
|
||||||
const repoInfo = computed(() => {
|
|
||||||
const theme = siteData.value.themeConfig as DefaultTheme.Config
|
|
||||||
const repo = theme.docsRepo || theme.repo
|
|
||||||
let text: string | undefined = theme.repoLabel
|
|
||||||
|
|
||||||
if (repo) {
|
|
||||||
const link = /^https?:/.test(repo) ? repo : `https://github.com/${repo}`
|
|
||||||
if (!text) {
|
|
||||||
// if no label is provided, deduce it from the repo url
|
|
||||||
const repoHosts = link.match(/^https?:\/\/[^/]+/)
|
|
||||||
if (repoHosts) {
|
|
||||||
const repoHost = repoHosts[0]
|
|
||||||
const foundPlatform = platforms.find(([_platform, re]) =>
|
|
||||||
re.test(repoHost)
|
|
||||||
)
|
|
||||||
text = foundPlatform && foundPlatform[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { link, text: text || 'Source' }
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
})
|
|
||||||
|
|
||||||
const localeCandidates = computed(() => {
|
|
||||||
const locales = siteData.value.themeConfig.locales
|
|
||||||
if (!locales) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
const localeKeys = Object.keys(locales)
|
|
||||||
if (localeKeys.length <= 1) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle site base
|
|
||||||
const siteBase = inBrowser ? siteData.value.base : '/'
|
|
||||||
const siteBaseWithoutSuffix = siteBase.endsWith('/')
|
|
||||||
? siteBase.slice(0, -1)
|
|
||||||
: siteBase
|
|
||||||
// remove site base in browser env
|
|
||||||
const routerPath = route.path.slice(siteBaseWithoutSuffix.length)
|
|
||||||
|
|
||||||
const currentLangBase = localeKeys.find((v) => {
|
|
||||||
if (v === '/') {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return routerPath.startsWith(v)
|
|
||||||
})
|
|
||||||
const currentContentPath = currentLangBase
|
|
||||||
? routerPath.substring(currentLangBase.length - 1)
|
|
||||||
: routerPath
|
|
||||||
const candidates = localeKeys.map((v) => {
|
|
||||||
const localePath = v.endsWith('/') ? v.slice(0, -1) : v
|
|
||||||
return {
|
|
||||||
text: locales[v].label || locales[v].lang,
|
|
||||||
link: `${localePath}${currentContentPath}`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const currentLangKey = currentLangBase ? currentLangBase : '/'
|
|
||||||
const selectText = locales[currentLangKey].selectText
|
|
||||||
? locales[currentLangKey].selectText
|
|
||||||
: 'Languages'
|
|
||||||
return {
|
|
||||||
text: selectText,
|
|
||||||
items: candidates
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const navData = computed(() => {
|
|
||||||
return siteDataByRoute.value.themeConfig.nav
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
navData,
|
|
||||||
repoInfo,
|
|
||||||
localeCandidates
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
import NavBarLink from './NavBarLink.vue'
|
|
||||||
import { defineComponent, ref, watch, PropType } from 'vue'
|
|
||||||
import { useRoute } from 'vitepress'
|
|
||||||
import { DefaultTheme } from '../config'
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'DropdownLink',
|
|
||||||
components: {
|
|
||||||
NavBarLink
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
item: {
|
|
||||||
type: Object as PropType<DefaultTheme.NavItemWithChildren>,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setup(props) {
|
|
||||||
const open = ref(false)
|
|
||||||
const route = useRoute()
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => route.path,
|
|
||||||
() => {
|
|
||||||
open.value = false
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const setOpen = (value: boolean) => {
|
|
||||||
open.value = value
|
|
||||||
}
|
|
||||||
|
|
||||||
const isLastItemOfArray = <T>(item: T, array: T[]) => {
|
|
||||||
return array.length && array.indexOf(item) === array.length - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
open,
|
|
||||||
setOpen,
|
|
||||||
isLastItemOfArray
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
@ -1,29 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<ul v-if="items.length > 0" class="sidebar-links">
|
<ul v-if="items.length > 0" class="sidebar-links">
|
||||||
<SideBarLink
|
<SideBarLink v-for="item of items" :key="item.text" :item="item" />
|
||||||
v-for="item of items"
|
|
||||||
:key="item.text"
|
|
||||||
:item="item"
|
|
||||||
/>
|
|
||||||
</ul>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent } from 'vue'
|
|
||||||
import { useSideBar } from '../composables/sideBar'
|
import { useSideBar } from '../composables/sideBar'
|
||||||
import { SideBarLink } from './SideBarLink'
|
import { SideBarLink } from './SideBarLink'
|
||||||
|
|
||||||
export default defineComponent({
|
const items = useSideBar()
|
||||||
components: {
|
|
||||||
SideBarLink
|
|
||||||
},
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
const items = useSideBar()
|
|
||||||
|
|
||||||
return {
|
|
||||||
items
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in new issue