From de1dfe2b065a64d95cbc39fc8aaafe41c1c0155d Mon Sep 17 00:00:00 2001 From: Kia Ishii Date: Sun, 5 Jul 2020 19:49:53 +0900 Subject: [PATCH] feat: add multi sidebar support --- .../theme-default/components/SideBar.ts | 20 +++++++++++++++++-- src/client/theme-default/utils.ts | 19 ++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/client/theme-default/components/SideBar.ts b/src/client/theme-default/components/SideBar.ts index 4edb86f7..ea89018b 100644 --- a/src/client/theme-default/components/SideBar.ts +++ b/src/client/theme-default/components/SideBar.ts @@ -1,7 +1,7 @@ import { useSiteData, usePageData, useRoute } from 'vitepress' import { computed, h, FunctionalComponent, VNode } from 'vue' import { Header } from '../../../../types/shared' -import { isActive } from '../utils' +import { isActive, resolvePath } from '../utils' import { DefaultTheme } from '../config' import { useActiveSidebarLinks } from '../composables/activeSidebarLink' @@ -62,7 +62,12 @@ export default { } else if (themeSidebar === false) { return [] } else if (typeof themeSidebar === 'object') { - return resolveMultiSidebar(themeSidebar, route.path, sidebarDepth) + return resolveMultiSidebar( + themeSidebar, + route.path, + headers, + sidebarDepth + ) } } }) @@ -117,8 +122,19 @@ function resolveArraySidebar( function resolveMultiSidebar( config: DefaultTheme.MultiSideBarConfig, path: string, + headers: Header[], depth: number ): ResolvedSidebar { + const item = config[resolvePath(path)] + + if (Array.isArray(item)) { + return resolveArraySidebar(item, depth) + } + + if (item === 'auto') { + return resolveAutoSidebar(headers, depth) + } + return [] } diff --git a/src/client/theme-default/utils.ts b/src/client/theme-default/utils.ts index 4c6aee47..2fbcce35 100644 --- a/src/client/theme-default/utils.ts +++ b/src/client/theme-default/utils.ts @@ -21,3 +21,22 @@ export function isActive(route: Route, path?: string): boolean { export function normalize(path: string): string { return decodeURI(path).replace(hashRE, '').replace(extRE, '') } + +/** + * get the path without filename (the last segment). for example, if the given + * path is `/guide/getting-started.html`, this method will return `/guide/`. + * Always with a trailing slash. + */ +export function resolvePath(path: string): string { + const segments = path.split('/') + + if (segments[segments.length - 1]) { + segments.pop() + } + + return ensureEndingSlash(segments.join('/')) +} + +export function ensureEndingSlash(path: string): string { + return /(\.html|\/)$/.test(path) ? path : `${path}/` +}