sidebar.ts 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import { computed } from 'vue'
  2. import { useData, useRoute } from 'vitepress'
  3. import { ensureStartingSlash, isArray, removeExtention } from '../utils'
  4. import { useLang } from './lang'
  5. export const useSidebar = () => {
  6. const route = useRoute()
  7. const { site, page } = useData()
  8. const lang = useLang()
  9. if (!page.value) {
  10. return {
  11. sidebars: computed(() => []),
  12. hasSidebar: computed(() => false),
  13. }
  14. }
  15. const sidebars = computed(() => {
  16. if (page.value.frontmatter.sidebar === false) return []
  17. const sidebars = getSidebarConfig(site.value.themeConfig.sidebars, route.data.relativePath, lang.value)
  18. return sidebars
  19. })
  20. return {
  21. sidebars,
  22. hasSidebar: computed(() => sidebars.value.length > 0),
  23. }
  24. }
  25. export function isSideBarConfig(sidebar) {
  26. return sidebar === false || sidebar === 'auto' || isArray(sidebar)
  27. }
  28. export function isSideBarGroup(item) {
  29. return item.children !== undefined
  30. }
  31. export function isSideBarEmpty(sidebar) {
  32. return isArray(sidebar) ? sidebar.length === 0 : !sidebar
  33. }
  34. type SidebarItem = {
  35. text: string
  36. link: string
  37. }
  38. type SidebarConfig = SidebarItem[]
  39. type Sidebar =
  40. | {
  41. [key: string]: SidebarConfig
  42. }
  43. | false
  44. | 'auto'
  45. export function getSidebarConfig(sidebar: Sidebar, path: string, lang: string) {
  46. if (sidebar === false || Array.isArray(sidebar) || sidebar === 'auto') {
  47. return []
  48. }
  49. path = ensureStartingSlash(path)
  50. for (const dir in sidebar) {
  51. // make sure the multi sidebar key starts with slash too
  52. if (path.startsWith(ensureStartingSlash(`${lang}${dir}`))) {
  53. return sidebar[dir][lang]
  54. }
  55. }
  56. return []
  57. }
  58. /**
  59. * Get flat sidebar links from the sidebar items. This method is useful for
  60. * creating the "next and prev link" feature. It will ignore any items that
  61. * don't have `link` property and removes `.md` or `.html` extension if a
  62. * link contains it.
  63. */
  64. export function getFlatSideBarLinks(sidebar) {
  65. return sidebar.reduce((links, item) => {
  66. if (item.link) {
  67. links.push({ text: item.text, link: removeExtention(item.link) })
  68. }
  69. if (isSideBarGroup(item)) {
  70. links = [...links, ...getFlatSideBarLinks(item.children)]
  71. }
  72. return links
  73. }, [])
  74. }