wip routeContext

This commit is contained in:
ozakione 2024-05-16 09:41:34 +02:00
parent 7e417aa77d
commit 8ad074773a
6 changed files with 63 additions and 98 deletions

View file

@ -13,10 +13,12 @@ import {
useQueryStringList,
type ListUpdateFunction,
} from '@docusaurus/theme-common';
import useRouteContext from '@docusaurus/useRouteContext';
import type {
TagType,
Operator,
ShowcaseItem,
TagsOption,
} from '@docusaurus/plugin-content-showcase';
export function filterItems({
@ -130,3 +132,34 @@ export function sortItems(params: ShowcaseItem[]): ShowcaseItem[] {
result = sortBy(result, (user) => !user.tags.includes('favorite'));
return result;
}
export interface ShowcaseContextType {
items: ShowcaseItem[];
tags: TagsOption;
screenshotApi: string;
}
function useShowcase() {
const routeContext = useRouteContext();
console.log('routeContext:', routeContext);
const showcase = routeContext?.data?.showcase;
console.log('showcase:', showcase);
if (!showcase) {
throw new Error(
'showcase-related hooks can only be called on the showcase page',
);
}
return showcase as ShowcaseContextType;
}
export function useShowcaseItems(): ShowcaseItem[] {
return useShowcase().items;
}
export function useShowcaseApiScreenshot(): string {
return useShowcase().screenshotApi;
}
export function useShowcaseTags(): TagsOption {
return useShowcase().tags;
}

View file

@ -9,11 +9,11 @@ import React from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import Translate from '@docusaurus/Translate';
import {sortBy} from '@docusaurus/plugin-content-showcase/client';
import {
sortBy,
useShowcaseTags,
useShowcaseApiScreenshot,
} from '@docusaurus/theme-common/internal';
} from '@docusaurus/plugin-content-showcase/client';
import Heading from '@theme/Heading';
import FavoriteIcon from '@theme/Showcase/FavoriteIcon';
import type {ShowcaseItem, TagType} from '@docusaurus/plugin-content-showcase';

View file

@ -11,8 +11,8 @@ import Translate from '@docusaurus/Translate';
import {
useFilteredItems,
sortItems,
useShowcaseItems,
} from '@docusaurus/plugin-content-showcase/client';
import {useShowcaseItems} from '@docusaurus/theme-common/internal';
import Heading from '@theme/Heading';
import FavoriteIcon from '@theme/Showcase/FavoriteIcon';
import ShowcaseCard from '@theme/Showcase/ShowcaseCard';

View file

@ -11,11 +11,9 @@ import Translate from '@docusaurus/Translate';
import {
useFilteredItems,
useSiteCountPlural,
} from '@docusaurus/plugin-content-showcase/client';
import {
useShowcaseItems,
useShowcaseTags,
} from '@docusaurus/theme-common/internal';
} from '@docusaurus/plugin-content-showcase/client';
import FavoriteIcon from '@theme/Showcase/FavoriteIcon';
import Heading from '@theme/Heading';
import ShowcaseTagSelect from '@theme/Showcase/ShowcaseTagSelect';

View file

@ -5,8 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import React, {useMemo, type ReactNode, useContext} from 'react';
import {ReactContextError} from '../utils/reactUtils';
import React, {createContext, useMemo, type ReactNode} from 'react';
import type {
ShowcaseItem,
TagsOption,
@ -20,100 +19,40 @@ type Props = {
children: ReactNode;
};
const ItemsContext = React.createContext<ShowcaseItem[] | null>(null);
const ApiContext = React.createContext<string | null>(null);
const TagsContext = React.createContext<TagsOption | null>(null);
function useItemsContextValue(content: ShowcaseItem[]): ShowcaseItem[] {
return useMemo(() => content, [content]);
}
function useApiScreenshotContextValue(content: string): string {
return useMemo(() => content, [content]);
}
function useTagsContextValue(tags: TagsOption): TagsOption {
return useMemo(() => tags, [tags]);
}
function ItemsProvider({
children,
items,
}: {
children: ReactNode;
export interface ShowcaseContextType {
items: ShowcaseItem[];
}): JSX.Element {
const contextValue = useItemsContextValue(items);
return (
<ItemsContext.Provider value={contextValue}>
{children}
</ItemsContext.Provider>
);
}
function ApiScreenshotProvider({
children,
api,
}: {
children: ReactNode;
api: string;
}): JSX.Element {
const contextValue = useApiScreenshotContextValue(api);
return (
<ApiContext.Provider value={contextValue}>{children}</ApiContext.Provider>
);
}
function TagsProvider({
children,
tags,
}: {
children: ReactNode;
tags: TagsOption;
}): JSX.Element {
const contextValue = useTagsContextValue(tags);
return (
<TagsContext.Provider value={contextValue}>{children}</TagsContext.Provider>
);
screenshotApi: string;
}
const ShowcaseContext = createContext<ShowcaseContextType | undefined>(
undefined,
);
// const useShowcaseContext = (): ShowcaseContextType => {
// const context = useContext(ShowcaseContext);
// if (!context) {
// throw new Error(
// 'useShowcaseContext must be used within a ShowcaseProvider',
// );
// }
// return context;
// };
export function ShowcaseProvider({
items,
tags,
screenshotApi,
children,
}: Props): JSX.Element {
const contextValue = useMemo(
() => ({items, tags, screenshotApi}),
[items, tags, screenshotApi],
);
return (
<ItemsProvider items={items}>
<TagsProvider tags={tags}>
<ApiScreenshotProvider api={screenshotApi}>
{children}
</ApiScreenshotProvider>
</TagsProvider>
</ItemsProvider>
<ShowcaseContext.Provider value={contextValue}>
{children}
</ShowcaseContext.Provider>
);
}
export function useShowcaseItems(): ShowcaseItem[] {
const showcaseItems = useContext(ItemsContext);
if (showcaseItems === null) {
throw new ReactContextError('ItemsProvider');
}
return showcaseItems;
}
export function useShowcaseApiScreenshot(): string {
const showcaseItems = useContext(ApiContext);
if (showcaseItems === null) {
throw new ReactContextError('ItemsProvider');
}
return showcaseItems;
}
export function useShowcaseTags(): TagsOption {
const tags = useContext(TagsContext);
if (tags === null) {
throw new ReactContextError('TagsProvider');
}
return tags;
}

View file

@ -26,12 +26,7 @@ export {DocsVersionProvider, useDocsVersion} from './contexts/docsVersion';
export {DocsSidebarProvider, useDocsSidebar} from './contexts/docsSidebar';
export {DocProvider, useDoc, type DocContextValue} from './contexts/doc';
export {
useShowcaseItems,
useShowcaseTags,
useShowcaseApiScreenshot,
ShowcaseProvider,
} from './contexts/showcase';
export {ShowcaseProvider} from './contexts/showcase';
export {
BlogPostProvider,
useBlogPost,