Skip to content

Commit

Permalink
fix(theme): Fix <DocCardList> usage on docs at root of a sidebar (#…
Browse files Browse the repository at this point in the history
…10847)

Fix `<DocCardList>` usage on docs at root of a sidebar
  • Loading branch information
slorber authored Jan 16, 2025
1 parent e59355b commit 67207bc
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
useDocById,
findSidebarCategory,
useCurrentSidebarCategory,
useCurrentSidebarSiblings,
useSidebarBreadcrumbs,
isVisibleSidebarItem,
} from '../docsUtils';
Expand Down Expand Up @@ -780,3 +781,128 @@ describe('useCurrentSidebarCategory', () => {
);
});
});

describe('useCurrentSidebarSiblings', () => {
const createUseCurrentSidebarSiblingsMock =
(sidebar?: PropSidebar) => (location: string) =>
renderHook(() => useCurrentSidebarSiblings(), {
wrapper: ({children}) => (
<DocsSidebarProvider name="sidebarName" items={sidebar}>
<StaticRouter location={location}>{children}</StaticRouter>
</DocsSidebarProvider>
),
}).result.current;

it('works for sidebar category', () => {
const category: PropSidebarItemCategory = testCategory({
href: '/cat',
items: [testLink(), testLink()],
});
const sidebar: PropSidebar = [
testLink(),
testLink(),
category,
testCategory(),
];

const mockUseCurrentSidebarCategory =
createUseCurrentSidebarSiblingsMock(sidebar);

expect(mockUseCurrentSidebarCategory('/cat')).toEqual(category.items);
});

it('works for sidebar root', () => {
const category: PropSidebarItemCategory = testCategory({
href: '/cat',
items: [testLink(), testLink()],
});
const sidebar: PropSidebar = [
testLink({href: '/rootLink'}),
testLink(),
category,
testCategory(),
];

const mockUseCurrentSidebarCategory =
createUseCurrentSidebarSiblingsMock(sidebar);

expect(mockUseCurrentSidebarCategory('/rootLink')).toEqual(sidebar);
});

it('works for nested sidebar category', () => {
const category2: PropSidebarItemCategory = testCategory({
href: '/cat2',
items: [testLink(), testCategory()],
});
const category1: PropSidebarItemCategory = testCategory({
href: '/cat1',
items: [testLink(), testLink(), category2, testCategory()],
});
const sidebar: PropSidebar = [
testLink(),
testLink(),
category1,
testCategory(),
];

const mockUseCurrentSidebarCategory =
createUseCurrentSidebarSiblingsMock(sidebar);

expect(mockUseCurrentSidebarCategory('/cat2')).toEqual(category2.items);
});

it('works for category link item', () => {
const link = testLink({href: '/my/link/path'});
const category: PropSidebarItemCategory = testCategory({
href: '/cat1',
items: [testLink(), testLink(), link, testCategory()],
});
const sidebar: PropSidebar = [
testLink(),
testLink(),
category,
testCategory(),
];

const mockUseCurrentSidebarCategory =
createUseCurrentSidebarSiblingsMock(sidebar);

expect(mockUseCurrentSidebarCategory('/my/link/path')).toEqual(
category.items,
);
});

it('works for nested category link item', () => {
const link = testLink({href: '/my/link/path'});
const category2: PropSidebarItemCategory = testCategory({
href: '/cat2',
items: [testLink(), testLink(), link, testCategory()],
});
const category1: PropSidebarItemCategory = testCategory({
href: '/cat1',
items: [testLink(), testLink(), category2, testCategory()],
});
const sidebar: PropSidebar = [
testLink(),
testLink(),
category1,
testCategory(),
];

const mockUseCurrentSidebarCategory =
createUseCurrentSidebarSiblingsMock(sidebar);

expect(mockUseCurrentSidebarCategory('/my/link/path')).toEqual(
category2.items,
);
});

it('throws when sidebar is missing', () => {
const mockUseCurrentSidebarCategory = createUseCurrentSidebarSiblingsMock();
expect(() =>
mockUseCurrentSidebarCategory('/cat'),
).toThrowErrorMatchingInlineSnapshot(
`"Unexpected: cant find current sidebar in context"`,
);
});
});
19 changes: 19 additions & 0 deletions packages/docusaurus-plugin-content-docs/src/client/docsUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,25 @@ export function useCurrentSidebarCategory(): PropSidebarItemCategory {
return deepestCategory;
}

/**
* Gets the category associated with the current location. Should only be used
* on category index pages.
*/
export function useCurrentSidebarSiblings(): PropSidebarItem[] {
const {pathname} = useLocation();
const sidebar = useDocsSidebar();
if (!sidebar) {
throw new Error('Unexpected: cant find current sidebar in context');
}
const categoryBreadcrumbs = getSidebarBreadcrumbs({
sidebarItems: sidebar.items,
pathname,
onlyCategories: true,
});
const deepestCategory = categoryBreadcrumbs.slice(-1)[0];
return deepestCategory?.items ?? sidebar.items;
}

const isActive = (testedPath: string | undefined, activePath: string) =>
typeof testedPath !== 'undefined' && isSamePath(testedPath, activePath);
const containsActiveSidebarItem = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export {
useLayoutDocsSidebar,
useDocRootMetadata,
useCurrentSidebarCategory,
useCurrentSidebarSiblings,
filterDocCardListItems,
} from './docsUtils';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
import React, {type ReactNode} from 'react';
import clsx from 'clsx';
import {
useCurrentSidebarCategory,
useCurrentSidebarSiblings,
filterDocCardListItems,
} from '@docusaurus/plugin-content-docs/client';
import DocCard from '@theme/DocCard';
import type {Props} from '@theme/DocCardList';

function DocCardListForCurrentSidebarCategory({className}: Props) {
const category = useCurrentSidebarCategory();
return <DocCardList items={category.items} className={className} />;
const items = useCurrentSidebarSiblings();
return <DocCardList items={items} className={className} />;
}

export default function DocCardList(props: Props): ReactNode {
Expand Down
6 changes: 6 additions & 0 deletions website/_dogfooding/_docs tests/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ This Docusaurus docs plugin instance is meant to test fancy edge-cases that regu
- [/tests/docs](/tests/docs)
- [/tests/blog](/tests/blog)
- [/tests/pages](/tests/pages)

---

import DocCardList from '@theme/DocCardList';

<DocCardList />

0 comments on commit 67207bc

Please sign in to comment.