mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-30 10:48:05 +02:00
screenshot api
This commit is contained in:
parent
510539fc96
commit
c8b7e6d5df
8 changed files with 108 additions and 32 deletions
|
@ -31,7 +31,15 @@ export default async function pluginContentShowcase(
|
|||
): Promise<Plugin<ShowcaseItems>> {
|
||||
const {siteDir, localizationDir} = context;
|
||||
// todo check for better naming of path: sitePath
|
||||
const {include, exclude, tags, routeBasePath, path: sitePath, id} = options;
|
||||
const {
|
||||
include,
|
||||
exclude,
|
||||
tags,
|
||||
routeBasePath,
|
||||
path: sitePath,
|
||||
id,
|
||||
screenshotApi,
|
||||
} = options;
|
||||
|
||||
const contentPaths: ShowcaseContentPaths = {
|
||||
contentPath: path.resolve(siteDir, sitePath),
|
||||
|
@ -81,6 +89,7 @@ export default async function pluginContentShowcase(
|
|||
await processContentLoaded({
|
||||
content,
|
||||
tags: validatedTags,
|
||||
screenshotApi,
|
||||
routeBasePath,
|
||||
addRoute,
|
||||
});
|
||||
|
|
|
@ -15,11 +15,13 @@ export async function processContentLoaded({
|
|||
content,
|
||||
tags,
|
||||
routeBasePath,
|
||||
screenshotApi,
|
||||
addRoute,
|
||||
}: {
|
||||
content: ShowcaseItems;
|
||||
routeBasePath: string;
|
||||
tags: TagsOption;
|
||||
screenshotApi: string;
|
||||
addRoute: PluginContentLoadedActions['addRoute'];
|
||||
}): Promise<void> {
|
||||
addRoute({
|
||||
|
@ -28,6 +30,7 @@ export async function processContentLoaded({
|
|||
props: {
|
||||
items: content.items,
|
||||
tags,
|
||||
screenshotApi,
|
||||
},
|
||||
exact: true,
|
||||
});
|
||||
|
|
|
@ -256,6 +256,7 @@ declare module '@theme/Showcase' {
|
|||
export type Props = {
|
||||
items: ShowcaseItem[];
|
||||
tags: TagsOption;
|
||||
screenshotApi: string;
|
||||
};
|
||||
|
||||
export default function Showcase(props: Props): JSX.Element;
|
||||
|
|
|
@ -10,7 +10,10 @@ import clsx from 'clsx';
|
|||
import Link from '@docusaurus/Link';
|
||||
import Translate from '@docusaurus/Translate';
|
||||
import {sortBy} from '@docusaurus/plugin-content-showcase/client';
|
||||
import {useShowcaseTags} from '@docusaurus/theme-common/internal';
|
||||
import {
|
||||
useShowcaseTags,
|
||||
useShowcaseApiScreenshot,
|
||||
} from '@docusaurus/theme-common/internal';
|
||||
import Heading from '@theme/Heading';
|
||||
import FavoriteIcon from '@theme/Showcase/FavoriteIcon';
|
||||
import type {ShowcaseItem, TagType} from '@docusaurus/plugin-content-showcase';
|
||||
|
@ -36,6 +39,7 @@ function TagItem({
|
|||
);
|
||||
}
|
||||
|
||||
// TODO move tag reorder logic into hook
|
||||
function ShowcaseCardTag({tags}: {tags: TagType[]}) {
|
||||
const Tags = useShowcaseTags();
|
||||
const TagList = Object.keys(Tags) as TagType[];
|
||||
|
@ -56,18 +60,13 @@ function ShowcaseCardTag({tags}: {tags: TagType[]}) {
|
|||
);
|
||||
}
|
||||
|
||||
function getCardImage(item: ShowcaseItem): string {
|
||||
return (
|
||||
item.preview ??
|
||||
// TODO make it configurable
|
||||
`https://slorber-api-screenshot.netlify.app/${encodeURIComponent(
|
||||
item.website,
|
||||
)}/showcase`
|
||||
);
|
||||
function getCardImage(item: ShowcaseItem, api: string): string {
|
||||
return item.preview ?? `${api}/${encodeURIComponent(item.website)}/showcase`;
|
||||
}
|
||||
|
||||
function ShowcaseCard({item}: {item: ShowcaseItem}) {
|
||||
const image = getCardImage(item);
|
||||
const api = useShowcaseApiScreenshot();
|
||||
const image = getCardImage(item, api);
|
||||
return (
|
||||
<li key={item.title} className="card shadow--md">
|
||||
<div className={clsx('card__image', styles.showcaseCardImage)}>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import Translate, {translate} from '@docusaurus/Translate';
|
||||
import Link from '@docusaurus/Link';
|
||||
import {TagsProvider, ItemsProvider} from '@docusaurus/theme-common/internal';
|
||||
import {ShowcaseProvider} from '@docusaurus/theme-common/internal';
|
||||
import Layout from '@theme/Layout';
|
||||
import Heading from '@theme/Heading';
|
||||
import ShowcaseSearchBar from '@theme/Showcase/ShowcaseSearchBar';
|
||||
|
@ -37,8 +37,10 @@ function ShowcaseHeader() {
|
|||
|
||||
export default function Showcase(props: Props): JSX.Element {
|
||||
return (
|
||||
<ItemsProvider items={props.items}>
|
||||
<TagsProvider tags={props.tags}>
|
||||
<ShowcaseProvider
|
||||
items={props.items}
|
||||
tags={props.tags}
|
||||
screenshotApi={props.screenshotApi}>
|
||||
<Layout title={TITLE} description={DESCRIPTION}>
|
||||
<main className="margin-vert--lg">
|
||||
<ShowcaseHeader />
|
||||
|
@ -51,7 +53,6 @@ export default function Showcase(props: Props): JSX.Element {
|
|||
<ShowcaseCards />
|
||||
</main>
|
||||
</Layout>
|
||||
</TagsProvider>
|
||||
</ItemsProvider>
|
||||
</ShowcaseProvider>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,18 +12,31 @@ import type {
|
|||
TagsOption,
|
||||
} from '@docusaurus/plugin-content-showcase';
|
||||
|
||||
// duplicated from theme classic showcase
|
||||
type Props = {
|
||||
items: ShowcaseItem[];
|
||||
tags: TagsOption;
|
||||
screenshotApi: string;
|
||||
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]);
|
||||
}
|
||||
|
||||
export function ItemsProvider({
|
||||
function ItemsProvider({
|
||||
children,
|
||||
items,
|
||||
}: {
|
||||
|
@ -38,7 +51,20 @@ export function ItemsProvider({
|
|||
);
|
||||
}
|
||||
|
||||
export function TagsProvider({
|
||||
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,
|
||||
}: {
|
||||
|
@ -51,6 +77,23 @@ export function TagsProvider({
|
|||
);
|
||||
}
|
||||
|
||||
export function ShowcaseProvider({
|
||||
items,
|
||||
tags,
|
||||
screenshotApi,
|
||||
children,
|
||||
}: Props): JSX.Element {
|
||||
return (
|
||||
<ItemsProvider items={items}>
|
||||
<TagsProvider tags={tags}>
|
||||
<ApiScreenshotProvider api={screenshotApi}>
|
||||
{children}
|
||||
</ApiScreenshotProvider>
|
||||
</TagsProvider>
|
||||
</ItemsProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useShowcaseItems(): ShowcaseItem[] {
|
||||
const showcaseItems = useContext(ItemsContext);
|
||||
if (showcaseItems === null) {
|
||||
|
@ -59,6 +102,14 @@ export function useShowcaseItems(): ShowcaseItem[] {
|
|||
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) {
|
||||
|
|
|
@ -27,10 +27,10 @@ export {DocsSidebarProvider, useDocsSidebar} from './contexts/docsSidebar';
|
|||
|
||||
export {DocProvider, useDoc, type DocContextValue} from './contexts/doc';
|
||||
export {
|
||||
ItemsProvider,
|
||||
TagsProvider,
|
||||
useShowcaseItems,
|
||||
useShowcaseTags,
|
||||
useShowcaseApiScreenshot,
|
||||
ShowcaseProvider,
|
||||
} from './contexts/showcase';
|
||||
export {
|
||||
BlogPostProvider,
|
||||
|
|
12
website/showcase/tags.yml
Normal file
12
website/showcase/tags.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
favorite:
|
||||
label: 'Favorite'
|
||||
description:
|
||||
message: 'Our favorite Docusaurus sites that you must absolutely check out!'
|
||||
id: 'showcase.tag.favorite.description'
|
||||
color: '#e9669e'
|
||||
opensource:
|
||||
label: 'Open Source'
|
||||
description:
|
||||
message: 'These sites are open source, so you can learn from them!'
|
||||
id: 'showcase.tag.opensource.description'
|
||||
color: '#f6993f'
|
Loading…
Add table
Reference in a new issue