2022-04-06 05:45:20 +08:00

129 lines
3.7 KiB
TypeScript

import { useRouteLocale, useSiteLocaleData } from '@vuepress/client'
import { isLinkHttp, isString } from '@vuepress/shared'
import type { ComputedRef } from 'vue'
import { computed } from 'vue'
import { useRouter } from 'vue-router'
import type {
NavbarGroup,
NavbarItem,
NavLink,
ResolveNavbarItem,
} from '../../shared'
import { resolveRepoType } from '../utils'
import { useNavLink } from './navLink'
import { useThemeLocaleData } from './themeData'
export const useNavbarSelectLanguage = (): ComputedRef<ResolveNavbarItem[]> => {
const router = useRouter()
const routeLocale = useRouteLocale()
const siteLocale = useSiteLocaleData()
const themeLocale = useThemeLocaleData()
return computed<ResolveNavbarItem[]>(() => {
const localePaths = Object.keys(siteLocale.value.locales)
if (localePaths.length < 2) {
return []
}
const currentPath = router.currentRoute.value.path
const currentFullPath = router.currentRoute.value.fullPath
const languageDropdown: ResolveNavbarItem = {
text: themeLocale.value.selectLanguageText ?? 'unknown language',
ariaLabel:
themeLocale.value.selectLanguageAriaLabel ?? 'unknown language',
children: localePaths.map((targetLocalPath) => {
const targetSiteLocale =
siteLocale.value.locales?.[targetLocalPath] ?? {}
const targetThemeLocale =
themeLocale.value.locales?.[targetLocalPath] ?? {}
const targetLang = `${targetSiteLocale.lang}`
const text = targetThemeLocale.selectLanguageName ?? targetLang
let link: string
if (targetLang === siteLocale.value.lang) {
link = currentFullPath
} else {
const targetLocalePage = currentPath.replace(
routeLocale.value,
targetLocalPath
)
if (
router.getRoutes().some((item) => item.path === targetLocalPath)
) {
link = targetLocalePage
} else {
link = (targetThemeLocale.home as NavLink)?.link ?? targetLocalPath
}
}
return { text, link }
}),
}
return [languageDropdown]
})
}
export const useNavbarRepo = (): ComputedRef<ResolveNavbarItem[]> => {
const themeLocale = useThemeLocaleData()
const repo = computed(() => themeLocale.value.repo)
const repoType = computed(() => {
return repo.value ? resolveRepoType(repo.value) : null
})
const repoLink = computed(() => {
if (repo.value && !isLinkHttp(repo.value)) {
return `https://github.com/${repo.value}`
}
return repo.value
})
const repoLabel = computed(() => {
if (!repoLink.value) return null
if (themeLocale.value.repoLabel) return themeLocale.value.repoLabel
if (repoType.value === null) return 'Source'
return repoType.value
})
return computed(() => {
if (!repoLink.value || !repoLabel.value) {
return []
}
return [
{
text: repoLabel.value,
link: repoLink.value,
},
]
})
}
const resolveNavbarItem = (
item: NavbarItem | NavbarGroup | string
): ResolveNavbarItem => {
if (isString(item)) {
return useNavLink(item)
}
if ((item as NavbarGroup).children) {
return {
...item,
children: (item as NavbarGroup).children.map(resolveNavbarItem),
}
}
return item as ResolveNavbarItem
}
export const useNavbarConfig = (): ComputedRef<ResolveNavbarItem[]> => {
const themeLocale = useThemeLocaleData()
const { navbar, home, category, archive, tag } = themeLocale.value
const config: NavbarItem[] = [
home as NavbarItem,
...((navbar || []) as unknown as NavbarItem[]),
category as NavbarItem,
tag as NavbarItem,
archive as NavbarItem,
].filter((nav) => nav)
return computed(() => config.map(resolveNavbarItem))
}