This commit is contained in:
ozakione 2024-04-17 17:55:49 +02:00
parent 5b6626bcf4
commit 8c12b1c619
16 changed files with 126 additions and 193 deletions

View file

@ -19,27 +19,27 @@ import type {
ShowcaseItem,
} from '@docusaurus/plugin-content-showcase';
export function filterUsers({
users,
export function filterItems({
items,
tags,
operator,
searchName,
}: {
users: ShowcaseItem[];
items: ShowcaseItem[];
tags: TagType[];
operator: Operator;
searchName: string | undefined | null;
}): ShowcaseItem[] {
if (searchName) {
// eslint-disable-next-line no-param-reassign
users = users.filter((user) =>
items = items.filter((user) =>
user.title.toLowerCase().includes(searchName.toLowerCase()),
);
}
if (tags.length === 0) {
return users;
return items;
}
return users.filter((user) => {
return items.filter((user) => {
if (user.tags.length === 0) {
return false;
}
@ -71,19 +71,19 @@ export function useOperator(): [Operator, () => void] {
return [operator, toggleOperator];
}
export function useFilteredUsers(users: ShowcaseItem[]): ShowcaseItem[] {
export function useFilteredItems(items: ShowcaseItem[]): ShowcaseItem[] {
const [tags] = useTags();
const [searchName] = useSearchName() ?? [''];
const [operator] = useOperator();
return useMemo(
() =>
filterUsers({
users,
filterItems({
items,
tags: tags as TagType[],
operator,
searchName,
}),
[users, tags, operator, searchName],
[items, tags, operator, searchName],
);
}
@ -122,108 +122,7 @@ export type Tag = {
color: string;
};
export const Tags: {[type in TagType]: Tag} = {
favorite: {
label: translate({message: 'Favorite'}),
description: translate({
message:
'Our favorite Docusaurus sites that you must absolutely check out!',
id: 'showcase.tag.favorite.description',
}),
color: '#e9669e',
},
opensource: {
label: translate({message: 'Open-Source'}),
description: translate({
message: 'Open-Source Docusaurus sites can be useful for inspiration!',
id: 'showcase.tag.opensource.description',
}),
color: '#39ca30',
},
product: {
label: translate({message: 'Product'}),
description: translate({
message: 'Docusaurus sites associated to a commercial product!',
id: 'showcase.tag.product.description',
}),
color: '#dfd545',
},
design: {
label: translate({message: 'Design'}),
description: translate({
message:
'Beautiful Docusaurus sites, polished and standing out from the initial template!',
id: 'showcase.tag.design.description',
}),
color: '#a44fb7',
},
i18n: {
label: translate({message: 'I18n'}),
description: translate({
message:
'Translated Docusaurus sites using the internationalization support with more than 1 locale.',
id: 'showcase.tag.i18n.description',
}),
color: '#127f82',
},
versioning: {
label: translate({message: 'Versioning'}),
description: translate({
message:
'Docusaurus sites using the versioning feature of the docs plugin to manage multiple versions.',
id: 'showcase.tag.versioning.description',
}),
color: '#fe6829',
},
large: {
label: translate({message: 'Large'}),
description: translate({
message:
'Very large Docusaurus sites, including many more pages than the average!',
id: 'showcase.tag.large.description',
}),
color: '#8c2f00',
},
meta: {
label: translate({message: 'Meta'}),
description: translate({
message: 'Docusaurus sites of Meta (formerly Facebook) projects',
id: 'showcase.tag.meta.description',
}),
color: '#4267b2', // Facebook blue
},
personal: {
label: translate({message: 'Personal'}),
description: translate({
message:
'Personal websites, blogs and digital gardens built with Docusaurus',
id: 'showcase.tag.personal.description',
}),
color: '#14cfc3',
},
rtl: {
label: translate({message: 'RTL Direction'}),
description: translate({
message:
'Docusaurus sites using the right-to-left reading direction support.',
id: 'showcase.tag.rtl.description',
}),
color: '#ffcfc3',
},
};
export const TagList = Object.keys(Tags) as TagType[];
export function sortUsers(params: ShowcaseItem[]): ShowcaseItem[] {
export function sortItems(params: ShowcaseItem[]): ShowcaseItem[] {
let result = params;
// Sort by site name
result = sortBy(result, (user) => user.title.toLowerCase());
@ -231,5 +130,3 @@ export function sortUsers(params: ShowcaseItem[]): ShowcaseItem[] {
result = sortBy(result, (user) => !user.tags.includes('favorite'));
return result;
}
// export const sortedUsers = sortUsers();

View file

@ -37,17 +37,17 @@ export default async function pluginContentShowcase(
contentPath: path.resolve(siteDir, sitePath),
contentPathLocalized: getPluginI18nPath({
localizationDir,
pluginName: 'docusaurus-plugin-content-pages',
pluginName: 'docusaurus-plugin-content-showcase',
pluginId: id,
}),
};
const tagList = await getTagsList({
const {tags: validatedTags, tagkeys} = await getTagsList({
configTags: tags,
configPath: contentPaths.contentPath,
});
const showcaseItemSchema = createShowcaseItemSchema(tagList);
const showcaseItemSchema = createShowcaseItemSchema(tagkeys);
return {
name: 'docusaurus-plugin-content-showcase',
@ -80,6 +80,7 @@ export default async function pluginContentShowcase(
await processContentLoaded({
content,
tags: validatedTags,
routeBasePath,
addRoute,
});

View file

@ -5,16 +5,21 @@
* LICENSE file in the root directory of this source tree.
*/
import type {ShowcaseItems} from '@docusaurus/plugin-content-showcase';
import type {
ShowcaseItems,
TagsOption,
} from '@docusaurus/plugin-content-showcase';
import type {PluginContentLoadedActions} from '@docusaurus/types';
export async function processContentLoaded({
content,
tags,
routeBasePath,
addRoute,
}: {
content: ShowcaseItems;
routeBasePath: string;
tags: TagsOption;
addRoute: PluginContentLoadedActions['addRoute'];
}): Promise<void> {
addRoute({
@ -22,6 +27,7 @@ export async function processContentLoaded({
component: '@theme/Showcase',
props: {
items: content.items,
tags,
},
exact: true,
});

View file

@ -17,6 +17,7 @@ export const DEFAULT_OPTIONS: PluginOptions = {
include: ['**/*.{yml,yaml}'],
// TODO exclude won't work if user pass a custom file name
exclude: [...GlobExcludeDefault, 'tags.*'],
screenshotApi: 'https://slorber-api-screenshot.netlify.app',
tags: 'tags.yml',
};
@ -28,6 +29,7 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
tags: Joi.alternatives()
.try(Joi.string().default(DEFAULT_OPTIONS.tags), tagSchema)
.default(DEFAULT_OPTIONS.tags),
screenshotApi: Joi.string().default(DEFAULT_OPTIONS.screenshotApi),
});
export function validateOptions({

View file

@ -32,7 +32,7 @@ declare module '@docusaurus/plugin-content-showcase' {
| 'rtl';
export type TagsOption = {
[tagName: string]: Tag;
[type in TagType]: Tag;
};
export type PluginOptions = {
@ -42,6 +42,7 @@ declare module '@docusaurus/plugin-content-showcase' {
include: string[];
exclude: string[];
tags: string | TagsOption;
screenshotApi: string;
};
export type ShowcaseItem = {

View file

@ -9,7 +9,10 @@ import fs from 'fs-extra';
import path from 'path';
import Yaml from 'js-yaml';
import {Joi} from '@docusaurus/utils-validation';
import type {PluginOptions} from '@docusaurus/plugin-content-showcase';
import type {
PluginOptions,
TagsOption,
} from '@docusaurus/plugin-content-showcase';
export const tagSchema = Joi.object().pattern(
Joi.string(),
@ -35,7 +38,7 @@ export async function getTagsList({
}: {
configTags: PluginOptions['tags'];
configPath: PluginOptions['path'];
}): Promise<string[]> {
}): Promise<{tagkeys: string[]; tags: TagsOption}> {
if (typeof configTags === 'object') {
const tags = tagSchema.validate(configTags);
if (tags.error) {
@ -44,7 +47,10 @@ export async function getTagsList({
{cause: tags},
);
}
return Object.keys(tags.value);
return {
tagkeys: Object.keys(tags.value),
tags: tags.value,
};
}
const tagsPath = path.resolve(configPath, configTags);
@ -61,8 +67,10 @@ export async function getTagsList({
);
}
const tagLabels = Object.keys(tags.value);
return tagLabels;
return {
tagkeys: Object.keys(tags.value),
tags: tags.value,
};
} catch (error) {
throw new Error(`Failed to read tags file for showcase`, {cause: error});
}