From db1c343dfb7011825b18253b4b8a47b5d8f6f817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez?= Date: Sat, 29 Oct 2022 10:06:41 +0200 Subject: [PATCH] feat(theme): sort multiple sidebars (#1552) Co-authored-by: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> --- .../theme-default/support/sidebar.spec.ts | 97 +++++++++++++++++++ examples/configured/.vitepress/config.js | 24 +++++ .../configured/__test__/multisidebar.spec.ts | 40 ++++++++ examples/configured/index.md | 2 +- examples/configured/multi-sidebar/index.md | 5 + src/client/theme-default/support/sidebar.ts | 20 ++-- 6 files changed, 180 insertions(+), 8 deletions(-) create mode 100644 __tests__/client/theme-default/support/sidebar.spec.ts create mode 100644 examples/configured/__test__/multisidebar.spec.ts create mode 100644 examples/configured/multi-sidebar/index.md diff --git a/__tests__/client/theme-default/support/sidebar.spec.ts b/__tests__/client/theme-default/support/sidebar.spec.ts new file mode 100644 index 00000000000..9f41d417c07 --- /dev/null +++ b/__tests__/client/theme-default/support/sidebar.spec.ts @@ -0,0 +1,97 @@ +import { describe, test, expect } from 'vitest' +import { getSidebar } from 'client/theme-default/support/sidebar' + +describe('client/theme-default/support/sidebar', () => { + const root = [ + { + text: 'A', + collapsible: true, + items: [ + { + text: 'A', + link: '' + } + ] + }, + { + text: 'B', + items: [ + { + text: 'B', + link: '' + } + ] + } + ] + const another = [ + { + text: 'C', + items: [ + { + text: 'C', + link: '' + } + ] + } + ] + describe('normal sidebar sort', () => { + const normalSidebar = { + '/': root, + '/multi-sidebar/': another + } + test('gets / sidebar', () => { + expect(getSidebar(normalSidebar, '/')).toBe(root) + }) + test('gets /multi-sidebar/ sidebar', () => { + expect(getSidebar(normalSidebar, '/multi-sidebar/')).toBe(another) + }) + test('gets / sidebar again', () => { + expect(getSidebar(normalSidebar, '/some-entry.html')).toBe(root) + }) + }) + describe('reversed sidebar sort', () => { + const reversedSidebar = { + '/multi-sidebar/': another, + '/': root + } + test('gets / sidebar', () => { + expect(getSidebar(reversedSidebar, '/')).toBe(root) + }) + test('gets /multi-sidebar/ sidebar', () => { + expect(getSidebar(reversedSidebar, '/multi-sidebar/')).toBe(another) + }) + test('gets / sidebar again', () => { + expect(getSidebar(reversedSidebar, '/some-entry.html')).toBe(root) + }) + }) + describe('nested sidebar sort', () => { + const nested = [ + { + text: 'D', + items: [ + { + text: 'D', + link: '' + } + ] + } + ] + const nestedSidebar = { + '/': root, + '/multi-sidebar/': another, + '/multi-sidebar/nested/': nested + } + test('gets / sidebar', () => { + expect(getSidebar(nestedSidebar, '/')).toBe(root) + }) + test('gets /multi-sidebar/ sidebar', () => { + expect(getSidebar(nestedSidebar, '/multi-sidebar/')).toBe(another) + }) + test('gets /multi-sidebar/nested/ sidebar', () => { + expect(getSidebar(nestedSidebar, '/multi-sidebar/nested/')).toBe(nested) + }) + test('gets / sidebar again', () => { + expect(getSidebar(nestedSidebar, '/some-entry.html')).toBe(root) + }) + }) +}) diff --git a/examples/configured/.vitepress/config.js b/examples/configured/.vitepress/config.js index e027a483b72..6b0795c789c 100644 --- a/examples/configured/.vitepress/config.js +++ b/examples/configured/.vitepress/config.js @@ -24,6 +24,30 @@ export default defineConfig({ link: '/static-data/data' } ] + }, + { + text: 'Multi Sidebar Test', + items: [ + { + text: 'Test Page', + link: '/multi-sidebar/' + } + ] + } + ], + '/multi-sidebar/': [ + { + text: 'Multi Sidebar', + items: [ + { + text: 'Test Page', + link: '/multi-sidebar/' + }, + { + text: 'Back', + link: '/' + } + ] } ] } diff --git a/examples/configured/__test__/multisidebar.spec.ts b/examples/configured/__test__/multisidebar.spec.ts new file mode 100644 index 00000000000..ed7e4f88165 --- /dev/null +++ b/examples/configured/__test__/multisidebar.spec.ts @@ -0,0 +1,40 @@ +import { expect, test } from 'vitest' +import { page, vitePressTestUrl, waitForLayout } from '~utils' + +describe('test multi sidebar sort root', () => { + beforeAll(async () => { + await page.goto( + vitePressTestUrl + '/frontmatter/multiple-levels-outline.html' + ) + await waitForLayout() + }) + + test('using / sidebar', async () => { + const sidebarLocator = await page.locator( + '.VPSidebarGroup .title .title-text' + ) + + const sidebarContent = await sidebarLocator.allTextContents() + expect(sidebarContent).toEqual([ + 'Frontmatter', + 'Static Data', + 'Multi Sidebar Test' + ]) + }) +}) + +describe('test multi sidebar sort other', () => { + beforeAll(async () => { + await page.goto(vitePressTestUrl + '/multi-sidebar/index.html') + await waitForLayout() + }) + + test('using /multi-sidebar/ sidebar', async () => { + const sidebarLocator = await page.locator( + '.VPSidebarGroup .title .title-text' + ) + + const sidebarContent = await sidebarLocator.allTextContents() + expect(sidebarContent).toEqual(['Multi Sidebar']) + }) +}) diff --git a/examples/configured/index.md b/examples/configured/index.md index 5cc1ad4acf2..5319d12d6f6 100644 --- a/examples/configured/index.md +++ b/examples/configured/index.md @@ -1,3 +1,3 @@ # Full Configured VitePress Example -WIP \ No newline at end of file +WIP diff --git a/examples/configured/multi-sidebar/index.md b/examples/configured/multi-sidebar/index.md new file mode 100644 index 00000000000..c5d8b94953b --- /dev/null +++ b/examples/configured/multi-sidebar/index.md @@ -0,0 +1,5 @@ +--- +title: Multi Sidebar Test +--- + +# Multi Sidebar Test diff --git a/src/client/theme-default/support/sidebar.ts b/src/client/theme-default/support/sidebar.ts index b55fa1356f2..80971064c96 100644 --- a/src/client/theme-default/support/sidebar.ts +++ b/src/client/theme-default/support/sidebar.ts @@ -15,16 +15,22 @@ export function getSidebar( return sidebar } + if (sidebar == null) { + return [] + } + path = ensureStartingSlash(path) - for (const dir in sidebar) { - // make sure the multi sidebar key starts with slash too - if (path.startsWith(ensureStartingSlash(dir))) { - return sidebar[dir] - } - } + const dir = Object.keys(sidebar) + .sort((a, b) => { + return b.split('/').length - a.split('/').length + }) + .find((dir) => { + // make sure the multi sidebar key starts with slash too + return path.startsWith(ensureStartingSlash(dir)) + }) - return [] + return dir ? sidebar[dir] : [] } export function getFlatSideBarLinks(sidebar: DefaultTheme.SidebarGroup[]) {