refactor(theme): split BlogPostItem into smaller theme subcomponents (#7716)

This commit is contained in:
Sébastien Lorber 2022-07-08 13:28:53 +02:00 committed by GitHub
parent c7f18801da
commit c3ff131110
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 938 additions and 600 deletions

View file

@ -0,0 +1,80 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, {useMemo, type ReactNode, useContext} from 'react';
import {ReactContextError} from '../utils/reactUtils';
import type {PropBlogPostContent} from '@docusaurus/plugin-content-blog';
/**
* The React context value returned by the `useBlogPost()` hook.
* It contains useful data related to the currently browsed blog post.
*/
export type BlogPostContextValue = Pick<
PropBlogPostContent,
'metadata' | 'frontMatter' | 'assets' | 'toc'
> & {
readonly isBlogPostPage: boolean;
};
const Context = React.createContext<BlogPostContextValue | null>(null);
/**
* Note: we don't use `PropBlogPostContent` as context value on purpose. Metadata is
* currently stored inside the MDX component, but we may want to change that in
* the future.
*/
function useContextValue({
content,
isBlogPostPage,
}: {
content: PropBlogPostContent;
isBlogPostPage: boolean;
}): BlogPostContextValue {
return useMemo(
() => ({
metadata: content.metadata,
frontMatter: content.frontMatter,
assets: content.assets,
toc: content.toc,
isBlogPostPage,
}),
[content, isBlogPostPage],
);
}
/**
* This is a very thin layer around the `content` received from the MDX loader.
* It provides metadata about the blog post to the children tree.
*/
export function BlogPostProvider({
children,
content,
isBlogPostPage = false,
}: {
children: ReactNode;
content: PropBlogPostContent;
isBlogPostPage?: boolean;
}): JSX.Element {
const contextValue = useContextValue({content, isBlogPostPage});
return <Context.Provider value={contextValue}>{children}</Context.Provider>;
}
/**
* Returns the data of the currently browsed blog post. Gives access to
* front matter, metadata, TOC, etc.
* When swizzling a low-level component (e.g. the "Edit this page" link)
* and you need some extra metadata, you don't have to drill the props
* all the way through the component tree: simply use this hook instead.
*/
export function useBlogPost(): BlogPostContextValue {
const blogPost = useContext(Context);
if (blogPost === null) {
throw new ReactContextError('BlogPostProvider');
}
return blogPost;
}

View file

@ -42,8 +42,7 @@ function useContextValue(content: PropDocContent): DocContextValue {
/**
* This is a very thin layer around the `content` received from the MDX loader.
* It provides the component to be rendered and other metadata about the doc to
* the children.
* It provides metadata about the doc to the children tree.
*/
export function DocProvider({
children,

View file

@ -24,7 +24,13 @@ export {
} from './contexts/docSidebarItemsExpandedState';
export {DocsVersionProvider, useDocsVersion} from './contexts/docsVersion';
export {DocsSidebarProvider, useDocsSidebar} from './contexts/docsSidebar';
export {DocProvider, useDoc, type DocContextValue} from './contexts/doc';
export {
BlogPostProvider,
useBlogPost,
type BlogPostContextValue,
} from './contexts/blogPost';
export {
useDocsPreferredVersionByPluginId,