refactor: split and cleanup theme/DocPage (#7006)

This commit is contained in:
Sébastien Lorber 2022-03-25 19:58:28 +01:00 committed by GitHub
parent 2964e6f65d
commit 1b974e8b1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 299 additions and 163 deletions

View file

@ -13,19 +13,24 @@ import type {PropSidebar} from '@docusaurus/plugin-content-docs';
describe('useDocsSidebar', () => {
it('throws if context provider is missing', () => {
expect(
() => renderHook(() => useDocsSidebar()).result.current,
() => renderHook(() => useDocsSidebar()).result.current?.items,
).toThrowErrorMatchingInlineSnapshot(
`"Hook useDocsSidebar is called outside the <DocsSidebarProvider>. "`,
);
});
it('reads value from context provider', () => {
const sidebar: PropSidebar = [];
const name = 'mySidebarName';
const items: PropSidebar = [];
const {result} = renderHook(() => useDocsSidebar(), {
wrapper: ({children}) => (
<DocsSidebarProvider sidebar={sidebar}>{children}</DocsSidebarProvider>
<DocsSidebarProvider name={name} items={items}>
{children}
</DocsSidebarProvider>
),
});
expect(result.current).toBe(sidebar);
expect(result.current).toBeDefined();
expect(result.current!.name).toBe(name);
expect(result.current!.items).toBe(items);
});
});

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import React, {type ReactNode, useContext} from 'react';
import React, {useMemo, useContext, type ReactNode} from 'react';
import type {PropSidebar} from '@docusaurus/plugin-content-docs';
import {ReactContextError} from '../utils/reactUtils';
@ -13,30 +13,44 @@ import {ReactContextError} from '../utils/reactUtils';
// Inspired by https://github.com/jamiebuilds/unstated-next/blob/master/src/unstated-next.tsx
const EmptyContext: unique symbol = Symbol('EmptyContext');
const Context = React.createContext<PropSidebar | null | typeof EmptyContext>(
EmptyContext,
);
type SidebarContextValue = {name: string; items: PropSidebar};
const Context = React.createContext<
SidebarContextValue | null | typeof EmptyContext
>(EmptyContext);
/**
* Provide the current sidebar to your children.
*/
export function DocsSidebarProvider({
children,
sidebar,
name,
items,
}: {
children: ReactNode;
sidebar: PropSidebar | null;
name: string | undefined;
items: PropSidebar | undefined;
}): JSX.Element {
return <Context.Provider value={sidebar}>{children}</Context.Provider>;
const stableValue: SidebarContextValue | null = useMemo(
() =>
name && items
? {
name,
items,
}
: null,
[name, items],
);
return <Context.Provider value={stableValue}>{children}</Context.Provider>;
}
/**
* Gets the sidebar that's currently displayed, or `null` if there isn't one
* Gets the sidebar data that's currently displayed, or `null` if there isn't one
*/
export function useDocsSidebar(): PropSidebar | null {
const sidebar = useContext(Context);
if (sidebar === EmptyContext) {
export function useDocsSidebar(): SidebarContextValue | null {
const value = useContext(Context);
if (value === EmptyContext) {
throw new ReactContextError('DocsSidebarProvider');
}
return sidebar;
return value;
}

View file

@ -307,7 +307,7 @@ describe('useSidebarBreadcrumbs', () => {
},
},
}}>
<DocsSidebarProvider sidebar={sidebar}>
<DocsSidebarProvider name="sidebarName" items={sidebar}>
{children}
</DocsSidebarProvider>
</Context.Provider>
@ -430,7 +430,7 @@ describe('useCurrentSidebarCategory', () => {
(sidebar?: PropSidebar) => (location: string) =>
renderHook(() => useCurrentSidebarCategory(), {
wrapper: ({children}) => (
<DocsSidebarProvider sidebar={sidebar}>
<DocsSidebarProvider name="sidebarName" items={sidebar}>
<StaticRouter location={location}>{children}</StaticRouter>
</DocsSidebarProvider>
),

View file

@ -105,7 +105,7 @@ export function useCurrentSidebarCategory(): PropSidebarItemCategory {
if (!sidebar) {
throw new Error('Unexpected: cant find current sidebar in context');
}
const category = findSidebarCategory(sidebar, (item) =>
const category = findSidebarCategory(sidebar.items, (item) =>
isSamePath(item.href, pathname),
);
if (!category) {
@ -174,7 +174,7 @@ export function useSidebarBreadcrumbs(): PropSidebarBreadcrumbsItem[] | null {
return false;
}
extract(sidebar);
extract(sidebar.items);
return breadcrumbs.reverse();
}