Skip to content

Commit

Permalink
fix(plugin-docs,theme): refactor docs plugin routes and component tree (
Browse files Browse the repository at this point in the history
  • Loading branch information
slorber committed Aug 18, 2022
1 parent c29218e commit 3b9b497
Show file tree
Hide file tree
Showing 35 changed files with 1,175 additions and 843 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ describe('normalizeDocsPluginOptions', () => {
sidebarPath: 'my-sidebar', // Path to sidebar configuration for showing a list of markdown pages.
sidebarItemsGenerator: DefaultSidebarItemsGenerator,
numberPrefixParser: DefaultNumberPrefixParser,
docLayoutComponent: '@theme/DocPage',
docsRootComponent: '@theme/DocsRoot',
docVersionRootComponent: '@theme/DocVersionRoot',
docRootComponent: '@theme/DocRoot',
docItemComponent: '@theme/DocItem',
docTagDocListComponent: '@theme/DocTagDocListPage',
docTagsListComponent: '@theme/DocTagsListPage',
Expand Down
111 changes: 12 additions & 99 deletions packages/docusaurus-plugin-content-docs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,18 @@ import {
addDocNavigation,
type DocEnv,
} from './docs';
import {readVersionsMetadata} from './versions';
import {readVersionsMetadata, toFullVersion} from './versions';
import {cliDocsVersionCommand} from './cli';
import {VERSIONS_JSON_FILE} from './constants';
import {toGlobalDataVersion} from './globalData';
import {toTagDocListProp} from './props';
import {getCategoryGeneratedIndexMetadataList} from './categoryGeneratedIndex';
import {
translateLoadedContent,
getLoadedContentTranslationFiles,
} from './translations';
import {getVersionTags} from './tags';
import {createVersionRoutes} from './routes';
import {createAllRoutes} from './routes';
import {createSidebarsUtils} from './sidebars/utils';

import type {
PropTagsListPage,
PluginOptions,
DocMetadataBase,
VersionMetadata,
Expand All @@ -55,7 +51,6 @@ import type {
SourceToPermalink,
DocFile,
DocsMarkdownOption,
VersionTag,
FullVersion,
} from './types';
import type {RuleSetRule} from 'webpack';
Expand Down Expand Up @@ -209,102 +204,20 @@ export default async function pluginContentDocs(
},

async contentLoaded({content, actions}) {
const {loadedVersions} = content;
const {
docLayoutComponent,
docItemComponent,
docCategoryGeneratedIndexComponent,
breadcrumbs,
} = options;
const {addRoute, createData, setGlobalData} = actions;
const versions: FullVersion[] = loadedVersions.map((version) => {
const sidebarsUtils = createSidebarsUtils(version.sidebars);
return {
...version,
sidebarsUtils,
categoryGeneratedIndices: getCategoryGeneratedIndexMetadataList({
docs: version.docs,
sidebarsUtils,
}),
};
const versions: FullVersion[] = content.loadedVersions.map(toFullVersion);

await createAllRoutes({
baseUrl,
versions,
options,
actions,
aliasedSource,
});

async function createVersionTagsRoutes(version: FullVersion) {
const versionTags = getVersionTags(version.docs);

// TODO tags should be a sub route of the version route
async function createTagsListPage() {
const tagsProp: PropTagsListPage['tags'] = Object.values(
versionTags,
).map((tagValue) => ({
label: tagValue.label,
permalink: tagValue.permalink,
count: tagValue.docIds.length,
}));

// Only create /tags page if there are tags.
if (tagsProp.length > 0) {
const tagsPropPath = await createData(
`${docuHash(`tags-list-${version.versionName}-prop`)}.json`,
JSON.stringify(tagsProp, null, 2),
);
addRoute({
path: version.tagsPath,
exact: true,
component: options.docTagsListComponent,
modules: {
tags: aliasedSource(tagsPropPath),
},
});
}
}

// TODO tags should be a sub route of the version route
async function createTagDocListPage(tag: VersionTag) {
const tagProps = toTagDocListProp({
allTagsPath: version.tagsPath,
tag,
docs: version.docs,
});
const tagPropPath = await createData(
`${docuHash(`tag-${tag.permalink}`)}.json`,
JSON.stringify(tagProps, null, 2),
);
addRoute({
path: tag.permalink,
component: options.docTagDocListComponent,
exact: true,
modules: {
tag: aliasedSource(tagPropPath),
},
});
}

await createTagsListPage();
await Promise.all(Object.values(versionTags).map(createTagDocListPage));
}

await Promise.all(
versions.map((version) =>
createVersionRoutes({
version,
docItemComponent,
docLayoutComponent,
docCategoryGeneratedIndexComponent,
pluginId,
aliasedSource,
actions,
}),
),
);

// TODO tags should be a sub route of the version route
await Promise.all(versions.map(createVersionTagsRoutes));

setGlobalData({
actions.setGlobalData({
path: normalizeUrl([baseUrl, options.routeBasePath]),
versions: versions.map(toGlobalDataVersion),
breadcrumbs,
breadcrumbs: options.breadcrumbs,
});
},

Expand Down
10 changes: 8 additions & 2 deletions packages/docusaurus-plugin-content-docs/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ export const DEFAULT_OPTIONS: Omit<PluginOptions, 'id' | 'sidebarPath'> = {
exclude: GlobExcludeDefault,
sidebarItemsGenerator: DefaultSidebarItemsGenerator,
numberPrefixParser: DefaultNumberPrefixParser,
docLayoutComponent: '@theme/DocPage',
docsRootComponent: '@theme/DocsRoot',
docVersionRootComponent: '@theme/DocVersionRoot',
docRootComponent: '@theme/DocRoot',
docItemComponent: '@theme/DocItem',
docTagDocListComponent: '@theme/DocTagDocListPage',
docTagsListComponent: '@theme/DocTagsListPage',
Expand Down Expand Up @@ -104,7 +106,11 @@ const OptionsSchema = Joi.object<PluginOptions>({
}),
)
.default(() => DEFAULT_OPTIONS.numberPrefixParser),
docLayoutComponent: Joi.string().default(DEFAULT_OPTIONS.docLayoutComponent),
docsRootComponent: Joi.string().default(DEFAULT_OPTIONS.docsRootComponent),
docVersionRootComponent: Joi.string().default(
DEFAULT_OPTIONS.docVersionRootComponent,
),
docRootComponent: Joi.string().default(DEFAULT_OPTIONS.docRootComponent),
docItemComponent: Joi.string().default(DEFAULT_OPTIONS.docItemComponent),
docTagsListComponent: Joi.string().default(
DEFAULT_OPTIONS.docTagsListComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,24 @@ declare module '@docusaurus/plugin-content-docs' {
*/
exclude: string[];
/**
* Root layout component of each doc page. Provides the version data
* context, and is not unmounted when switching docs.
* Parent component of all the docs plugin pages (including all versions).
* Stays mounted when navigation between docs pages and versions.
*/
docLayoutComponent: string;
docsRootComponent: string;
/**
* Parent component of all docs pages of an individual version:
* - docs pages with sidebars
* - tags pages
* Stays mounted when navigation between pages of that specific version.
*/
docVersionRootComponent: string;
/**
* Parent component of all docs pages with sidebars:
* - regular docs pages
* - category generated index pages
* Stays mounted when navigation between such pages.
*/
docRootComponent: string;
/** Main doc container, with TOC, pagination, etc. */
docItemComponent: string;
/** Root component of the "docs containing tag X" page. */
Expand Down Expand Up @@ -610,14 +624,32 @@ declare module '@theme/DocBreadcrumbs' {
export default function DocBreadcrumbs(): JSX.Element;
}

declare module '@theme/DocPage' {
declare module '@theme/DocsRoot' {
import type {RouteConfigComponentProps} from 'react-router-config';
import type {Required} from 'utility-types';

export interface Props extends Required<RouteConfigComponentProps, 'route'> {}

export default function DocsRoot(props: Props): JSX.Element;
}

declare module '@theme/DocVersionRoot' {
import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs';
import type {RouteConfigComponentProps} from 'react-router-config';
import type {Required} from 'utility-types';

export interface Props extends Required<RouteConfigComponentProps, 'route'> {
readonly versionMetadata: PropVersionMetadata;
readonly version: PropVersionMetadata;
}

export default function DocPage(props: Props): JSX.Element;
export default function DocVersionRoot(props: Props): JSX.Element;
}

declare module '@theme/DocRoot' {
import type {RouteConfigComponentProps} from 'react-router-config';
import type {Required} from 'utility-types';

export interface Props extends Required<RouteConfigComponentProps, 'route'> {}

export default function DocRoot(props: Props): JSX.Element;
}
13 changes: 12 additions & 1 deletion packages/docusaurus-plugin-content-docs/src/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import _ from 'lodash';
import {createDocsByIdIndex} from './docs';
import type {VersionTag} from './types';
import type {VersionTag, VersionTags} from './types';
import type {
SidebarItemDoc,
SidebarItem,
Expand All @@ -21,6 +21,7 @@ import type {
PropSidebarItemCategory,
PropTagDocList,
PropTagDocListDoc,
PropTagsListPage,
PropSidebarItemLink,
PropVersionDocs,
DocMetadata,
Expand Down Expand Up @@ -181,3 +182,13 @@ export function toTagDocListProp({
items: toDocListProp(),
};
}

export function toTagsListTagsProp(
versionTags: VersionTags,
): PropTagsListPage['tags'] {
return Object.values(versionTags).map((tagValue) => ({
label: tagValue.label,
permalink: tagValue.permalink,
count: tagValue.docIds.length,
}));
}

0 comments on commit 3b9b497

Please sign in to comment.