sidebar.ts 2.2 KB

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