mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-10 15:47:23 +02:00
feat(v2): docs version banner configuration option (#5052)
* refactor DocVersionBanner => versionMetadata prop should be forwarded instead of using "useActiveVersion" + global data * docs version banner configuration * add doc for versions.banner * fix tests * improve docs plugin option api doc
This commit is contained in:
parent
f47826297c
commit
364051f232
13 changed files with 187 additions and 83 deletions
|
@ -405,6 +405,7 @@ Object {
|
||||||
\\"pluginId\\": \\"default\\",
|
\\"pluginId\\": \\"default\\",
|
||||||
\\"version\\": \\"current\\",
|
\\"version\\": \\"current\\",
|
||||||
\\"label\\": \\"Next\\",
|
\\"label\\": \\"Next\\",
|
||||||
|
\\"banner\\": \\"none\\",
|
||||||
\\"isLast\\": true,
|
\\"isLast\\": true,
|
||||||
\\"docsSidebars\\": {
|
\\"docsSidebars\\": {
|
||||||
\\"docs\\": [
|
\\"docs\\": [
|
||||||
|
@ -872,6 +873,7 @@ Object {
|
||||||
\\"pluginId\\": \\"community\\",
|
\\"pluginId\\": \\"community\\",
|
||||||
\\"version\\": \\"1.0.0\\",
|
\\"version\\": \\"1.0.0\\",
|
||||||
\\"label\\": \\"1.0.0\\",
|
\\"label\\": \\"1.0.0\\",
|
||||||
|
\\"banner\\": \\"none\\",
|
||||||
\\"isLast\\": true,
|
\\"isLast\\": true,
|
||||||
\\"docsSidebars\\": {
|
\\"docsSidebars\\": {
|
||||||
\\"version-1.0.0/community\\": [
|
\\"version-1.0.0/community\\": [
|
||||||
|
@ -890,6 +892,7 @@ Object {
|
||||||
\\"pluginId\\": \\"community\\",
|
\\"pluginId\\": \\"community\\",
|
||||||
\\"version\\": \\"current\\",
|
\\"version\\": \\"current\\",
|
||||||
\\"label\\": \\"Next\\",
|
\\"label\\": \\"Next\\",
|
||||||
|
\\"banner\\": \\"unreleased\\",
|
||||||
\\"isLast\\": false,
|
\\"isLast\\": false,
|
||||||
\\"docsSidebars\\": {
|
\\"docsSidebars\\": {
|
||||||
\\"community\\": [
|
\\"community\\": [
|
||||||
|
@ -1402,6 +1405,7 @@ Object {
|
||||||
\\"pluginId\\": \\"default\\",
|
\\"pluginId\\": \\"default\\",
|
||||||
\\"version\\": \\"1.0.0\\",
|
\\"version\\": \\"1.0.0\\",
|
||||||
\\"label\\": \\"1.0.0\\",
|
\\"label\\": \\"1.0.0\\",
|
||||||
|
\\"banner\\": \\"unmaintained\\",
|
||||||
\\"isLast\\": false,
|
\\"isLast\\": false,
|
||||||
\\"docsSidebars\\": {
|
\\"docsSidebars\\": {
|
||||||
\\"version-1.0.0/docs\\": [
|
\\"version-1.0.0/docs\\": [
|
||||||
|
@ -1446,6 +1450,7 @@ Object {
|
||||||
\\"pluginId\\": \\"default\\",
|
\\"pluginId\\": \\"default\\",
|
||||||
\\"version\\": \\"1.0.1\\",
|
\\"version\\": \\"1.0.1\\",
|
||||||
\\"label\\": \\"1.0.1\\",
|
\\"label\\": \\"1.0.1\\",
|
||||||
|
\\"banner\\": \\"none\\",
|
||||||
\\"isLast\\": true,
|
\\"isLast\\": true,
|
||||||
\\"docsSidebars\\": {
|
\\"docsSidebars\\": {
|
||||||
\\"version-1.0.1/docs\\": [
|
\\"version-1.0.1/docs\\": [
|
||||||
|
@ -1484,6 +1489,7 @@ Object {
|
||||||
\\"pluginId\\": \\"default\\",
|
\\"pluginId\\": \\"default\\",
|
||||||
\\"version\\": \\"current\\",
|
\\"version\\": \\"current\\",
|
||||||
\\"label\\": \\"Next\\",
|
\\"label\\": \\"Next\\",
|
||||||
|
\\"banner\\": \\"unreleased\\",
|
||||||
\\"isLast\\": false,
|
\\"isLast\\": false,
|
||||||
\\"docsSidebars\\": {
|
\\"docsSidebars\\": {
|
||||||
\\"docs\\": [
|
\\"docs\\": [
|
||||||
|
@ -1522,6 +1528,7 @@ Object {
|
||||||
\\"pluginId\\": \\"default\\",
|
\\"pluginId\\": \\"default\\",
|
||||||
\\"version\\": \\"withSlugs\\",
|
\\"version\\": \\"withSlugs\\",
|
||||||
\\"label\\": \\"withSlugs\\",
|
\\"label\\": \\"withSlugs\\",
|
||||||
|
\\"banner\\": \\"unmaintained\\",
|
||||||
\\"isLast\\": false,
|
\\"isLast\\": false,
|
||||||
\\"docsSidebars\\": {
|
\\"docsSidebars\\": {
|
||||||
\\"version-1.0.1/docs\\": [
|
\\"version-1.0.1/docs\\": [
|
||||||
|
|
|
@ -21,6 +21,7 @@ const DefaultI18N: I18n = {
|
||||||
currentLocale: 'en',
|
currentLocale: 'en',
|
||||||
locales: ['en'],
|
locales: ['en'],
|
||||||
defaultLocale: 'en',
|
defaultLocale: 'en',
|
||||||
|
localeConfigs: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('version paths', () => {
|
describe('version paths', () => {
|
||||||
|
@ -79,6 +80,7 @@ describe('simple site', () => {
|
||||||
versionLabel: 'Next',
|
versionLabel: 'Next',
|
||||||
versionName: 'current',
|
versionName: 'current',
|
||||||
versionPath: '/docs',
|
versionPath: '/docs',
|
||||||
|
versionBanner: 'none',
|
||||||
};
|
};
|
||||||
return {simpleSiteDir, defaultOptions, defaultContext, vCurrent};
|
return {simpleSiteDir, defaultOptions, defaultContext, vCurrent};
|
||||||
}
|
}
|
||||||
|
@ -233,6 +235,7 @@ describe('versioned site, pluginId=default', () => {
|
||||||
versionLabel: 'Next',
|
versionLabel: 'Next',
|
||||||
versionName: 'current',
|
versionName: 'current',
|
||||||
versionPath: '/docs/next',
|
versionPath: '/docs/next',
|
||||||
|
versionBanner: 'unreleased',
|
||||||
};
|
};
|
||||||
|
|
||||||
const v101: VersionMetadata = {
|
const v101: VersionMetadata = {
|
||||||
|
@ -250,6 +253,7 @@ describe('versioned site, pluginId=default', () => {
|
||||||
versionLabel: '1.0.1',
|
versionLabel: '1.0.1',
|
||||||
versionName: '1.0.1',
|
versionName: '1.0.1',
|
||||||
versionPath: '/docs',
|
versionPath: '/docs',
|
||||||
|
versionBanner: 'none',
|
||||||
};
|
};
|
||||||
|
|
||||||
const v100: VersionMetadata = {
|
const v100: VersionMetadata = {
|
||||||
|
@ -267,6 +271,7 @@ describe('versioned site, pluginId=default', () => {
|
||||||
versionLabel: '1.0.0',
|
versionLabel: '1.0.0',
|
||||||
versionName: '1.0.0',
|
versionName: '1.0.0',
|
||||||
versionPath: '/docs/1.0.0',
|
versionPath: '/docs/1.0.0',
|
||||||
|
versionBanner: 'unmaintained',
|
||||||
};
|
};
|
||||||
|
|
||||||
const vwithSlugs: VersionMetadata = {
|
const vwithSlugs: VersionMetadata = {
|
||||||
|
@ -287,6 +292,7 @@ describe('versioned site, pluginId=default', () => {
|
||||||
versionLabel: 'withSlugs',
|
versionLabel: 'withSlugs',
|
||||||
versionName: 'withSlugs',
|
versionName: 'withSlugs',
|
||||||
versionPath: '/docs/withSlugs',
|
versionPath: '/docs/withSlugs',
|
||||||
|
versionBanner: 'unmaintained',
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -357,9 +363,11 @@ describe('versioned site, pluginId=default', () => {
|
||||||
versions: {
|
versions: {
|
||||||
current: {
|
current: {
|
||||||
path: 'current-path',
|
path: 'current-path',
|
||||||
|
banner: 'unmaintained',
|
||||||
},
|
},
|
||||||
'1.0.0': {
|
'1.0.0': {
|
||||||
label: '1.0.0-label',
|
label: '1.0.0-label',
|
||||||
|
banner: 'unreleased',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -367,12 +375,17 @@ describe('versioned site, pluginId=default', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(versionsMetadata).toEqual([
|
expect(versionsMetadata).toEqual([
|
||||||
{...vCurrent, versionPath: '/docs/current-path'},
|
{
|
||||||
|
...vCurrent,
|
||||||
|
versionPath: '/docs/current-path',
|
||||||
|
versionBanner: 'unmaintained',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
...v101,
|
...v101,
|
||||||
isLast: false,
|
isLast: false,
|
||||||
routePriority: undefined,
|
routePriority: undefined,
|
||||||
versionPath: '/docs/1.0.1',
|
versionPath: '/docs/1.0.1',
|
||||||
|
versionBanner: 'unreleased',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
...v100,
|
...v100,
|
||||||
|
@ -380,6 +393,7 @@ describe('versioned site, pluginId=default', () => {
|
||||||
routePriority: -1,
|
routePriority: -1,
|
||||||
versionLabel: '1.0.0-label',
|
versionLabel: '1.0.0-label',
|
||||||
versionPath: '/docs',
|
versionPath: '/docs',
|
||||||
|
versionBanner: 'unreleased',
|
||||||
},
|
},
|
||||||
vwithSlugs,
|
vwithSlugs,
|
||||||
]);
|
]);
|
||||||
|
@ -510,7 +524,13 @@ describe('versioned site, pluginId=default', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(versionsMetadata).toEqual([
|
expect(versionsMetadata).toEqual([
|
||||||
{...vCurrent, isLast: true, routePriority: -1, versionPath: '/docs'},
|
{
|
||||||
|
...vCurrent,
|
||||||
|
isLast: true,
|
||||||
|
routePriority: -1,
|
||||||
|
versionPath: '/docs',
|
||||||
|
versionBanner: 'none',
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -631,6 +651,7 @@ describe('versioned site, pluginId=community', () => {
|
||||||
versionLabel: 'Next',
|
versionLabel: 'Next',
|
||||||
versionName: 'current',
|
versionName: 'current',
|
||||||
versionPath: '/communityBasePath/next',
|
versionPath: '/communityBasePath/next',
|
||||||
|
versionBanner: 'unreleased',
|
||||||
};
|
};
|
||||||
|
|
||||||
const v100: VersionMetadata = {
|
const v100: VersionMetadata = {
|
||||||
|
@ -651,6 +672,7 @@ describe('versioned site, pluginId=community', () => {
|
||||||
versionLabel: '1.0.0',
|
versionLabel: '1.0.0',
|
||||||
versionName: '1.0.0',
|
versionName: '1.0.0',
|
||||||
versionPath: '/communityBasePath',
|
versionPath: '/communityBasePath',
|
||||||
|
versionBanner: 'none',
|
||||||
};
|
};
|
||||||
|
|
||||||
return {versionedSiteDir, defaultOptions, defaultContext, vCurrent, v100};
|
return {versionedSiteDir, defaultOptions, defaultContext, vCurrent, v100};
|
||||||
|
@ -695,6 +717,7 @@ describe('versioned site, pluginId=community', () => {
|
||||||
isLast: true,
|
isLast: true,
|
||||||
routePriority: -1,
|
routePriority: -1,
|
||||||
versionPath: '/communityBasePath',
|
versionPath: '/communityBasePath',
|
||||||
|
versionBanner: 'none',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
|
@ -350,14 +350,13 @@ describe('docsClientUtils', () => {
|
||||||
latestVersionSuggestion: version2,
|
latestVersionSuggestion: version2,
|
||||||
});
|
});
|
||||||
|
|
||||||
// nothing to suggest, we are already on latest version
|
|
||||||
expect(getDocVersionSuggestions(data, '/docs/')).toEqual({
|
expect(getDocVersionSuggestions(data, '/docs/')).toEqual({
|
||||||
latestDocSuggestion: undefined,
|
latestDocSuggestion: version2.docs[0],
|
||||||
latestVersionSuggestion: undefined,
|
latestVersionSuggestion: version2,
|
||||||
});
|
});
|
||||||
expect(getDocVersionSuggestions(data, '/docs/doc2')).toEqual({
|
expect(getDocVersionSuggestions(data, '/docs/doc2')).toEqual({
|
||||||
latestDocSuggestion: undefined,
|
latestDocSuggestion: version2.docs[1],
|
||||||
latestVersionSuggestion: undefined,
|
latestVersionSuggestion: version2,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(getDocVersionSuggestions(data, '/docs/version1/')).toEqual({
|
expect(getDocVersionSuggestions(data, '/docs/version1/')).toEqual({
|
||||||
|
|
|
@ -140,10 +140,10 @@ export const getActiveDocContext = (
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DocVersionSuggestions = {
|
export type DocVersionSuggestions = {
|
||||||
|
// suggest the latest version
|
||||||
|
latestVersionSuggestion: GlobalVersion;
|
||||||
// suggest the same doc, in latest version (if exist)
|
// suggest the same doc, in latest version (if exist)
|
||||||
latestDocSuggestion?: GlobalDoc;
|
latestDocSuggestion?: GlobalDoc;
|
||||||
// suggest the latest version
|
|
||||||
latestVersionSuggestion?: GlobalVersion;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDocVersionSuggestions = (
|
export const getDocVersionSuggestions = (
|
||||||
|
@ -152,17 +152,7 @@ export const getDocVersionSuggestions = (
|
||||||
): DocVersionSuggestions => {
|
): DocVersionSuggestions => {
|
||||||
const latestVersion = getLatestVersion(data);
|
const latestVersion = getLatestVersion(data);
|
||||||
const activeDocContext = getActiveDocContext(data, pathname);
|
const activeDocContext = getActiveDocContext(data, pathname);
|
||||||
|
const latestDocSuggestion: GlobalDoc | undefined =
|
||||||
// We only suggest another doc/version if user is not using the latest version
|
activeDocContext?.alternateDocVersions[latestVersion.name];
|
||||||
const isNotOnLatestVersion = activeDocContext.activeVersion !== latestVersion;
|
return {latestDocSuggestion, latestVersionSuggestion: latestVersion};
|
||||||
|
|
||||||
const latestDocSuggestion: GlobalDoc | undefined = isNotOnLatestVersion
|
|
||||||
? activeDocContext?.alternateDocVersions[latestVersion.name]
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
const latestVersionSuggestion = isNotOnLatestVersion
|
|
||||||
? latestVersion
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
return {latestDocSuggestion, latestVersionSuggestion};
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,6 +49,7 @@ export const DEFAULT_OPTIONS: Omit<PluginOptions, 'id' | 'sidebarPath'> = {
|
||||||
const VersionOptionsSchema = Joi.object({
|
const VersionOptionsSchema = Joi.object({
|
||||||
path: Joi.string().allow('').optional(),
|
path: Joi.string().allow('').optional(),
|
||||||
label: Joi.string().optional(),
|
label: Joi.string().optional(),
|
||||||
|
banner: Joi.string().equal('none', 'unreleased', 'unmaintained').optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const VersionsOptionsSchema = Joi.object()
|
const VersionsOptionsSchema = Joi.object()
|
||||||
|
@ -101,6 +102,7 @@ export const OptionsSchema = Joi.object({
|
||||||
showLastUpdateAuthor: Joi.bool().default(
|
showLastUpdateAuthor: Joi.bool().default(
|
||||||
DEFAULT_OPTIONS.showLastUpdateAuthor,
|
DEFAULT_OPTIONS.showLastUpdateAuthor,
|
||||||
),
|
),
|
||||||
|
// TODO deprecated, excludeNextVersionDocs replaced by includeCurrentVersion
|
||||||
excludeNextVersionDocs: Joi.bool().default(
|
excludeNextVersionDocs: Joi.bool().default(
|
||||||
DEFAULT_OPTIONS.excludeNextVersionDocs,
|
DEFAULT_OPTIONS.excludeNextVersionDocs,
|
||||||
),
|
),
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
|
|
||||||
declare module '@docusaurus/plugin-content-docs-types' {
|
declare module '@docusaurus/plugin-content-docs-types' {
|
||||||
|
import type {VersionBanner} from './types';
|
||||||
|
|
||||||
export type PermalinkToSidebar = {
|
export type PermalinkToSidebar = {
|
||||||
[permalink: string]: string;
|
[permalink: string]: string;
|
||||||
};
|
};
|
||||||
|
@ -16,6 +18,7 @@ declare module '@docusaurus/plugin-content-docs-types' {
|
||||||
pluginId: string;
|
pluginId: string;
|
||||||
version: string;
|
version: string;
|
||||||
label: string;
|
label: string;
|
||||||
|
banner: VersionBanner;
|
||||||
isLast: boolean;
|
isLast: boolean;
|
||||||
docsSidebars: PropSidebars;
|
docsSidebars: PropSidebars;
|
||||||
permalinkToSidebar: PermalinkToSidebar;
|
permalinkToSidebar: PermalinkToSidebar;
|
||||||
|
@ -83,6 +86,7 @@ declare module '@theme/DocItem' {
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
readonly route: DocumentRoute;
|
readonly route: DocumentRoute;
|
||||||
|
readonly versionMetadata: PropVersionMetadata;
|
||||||
readonly content: {
|
readonly content: {
|
||||||
readonly frontMatter: FrontMatter;
|
readonly frontMatter: FrontMatter;
|
||||||
readonly metadata: Metadata;
|
readonly metadata: Metadata;
|
||||||
|
@ -96,6 +100,17 @@ declare module '@theme/DocItem' {
|
||||||
export default DocItem;
|
export default DocItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module '@theme/DocVersionBanner' {
|
||||||
|
import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs-types';
|
||||||
|
|
||||||
|
export type Props = {
|
||||||
|
readonly versionMetadata: PropVersionMetadata;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DocVersionBanner: (props: Props) => JSX.Element;
|
||||||
|
export default DocVersionBanner;
|
||||||
|
}
|
||||||
|
|
||||||
declare module '@theme/DocPage' {
|
declare module '@theme/DocPage' {
|
||||||
import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs-types';
|
import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs-types';
|
||||||
import type {DocumentRoute} from '@theme/DocItem';
|
import type {DocumentRoute} from '@theme/DocItem';
|
||||||
|
|
|
@ -74,6 +74,7 @@ export function toVersionMetadataProp(
|
||||||
pluginId,
|
pluginId,
|
||||||
version: loadedVersion.versionName,
|
version: loadedVersion.versionName,
|
||||||
label: loadedVersion.versionLabel,
|
label: loadedVersion.versionLabel,
|
||||||
|
banner: loadedVersion.versionBanner,
|
||||||
isLast: loadedVersion.isLast,
|
isLast: loadedVersion.isLast,
|
||||||
docsSidebars: toSidebarsProp(loadedVersion),
|
docsSidebars: toSidebarsProp(loadedVersion),
|
||||||
permalinkToSidebar: loadedVersion.permalinkToSidebar,
|
permalinkToSidebar: loadedVersion.permalinkToSidebar,
|
||||||
|
|
|
@ -30,6 +30,7 @@ export type VersionMetadata = ContentPaths & {
|
||||||
versionPath: string; // /baseUrl/docs/1.0.0
|
versionPath: string; // /baseUrl/docs/1.0.0
|
||||||
versionEditUrl?: string | undefined;
|
versionEditUrl?: string | undefined;
|
||||||
versionEditUrlLocalized?: string | undefined;
|
versionEditUrlLocalized?: string | undefined;
|
||||||
|
versionBanner: VersionBanner;
|
||||||
isLast: boolean;
|
isLast: boolean;
|
||||||
sidebarFilePath: string | false | undefined; // versioned_sidebars/1.0.0.json
|
sidebarFilePath: string | false | undefined; // versioned_sidebars/1.0.0.json
|
||||||
routePriority: number | undefined; // -1 for the latest docs
|
routePriority: number | undefined; // -1 for the latest docs
|
||||||
|
@ -59,9 +60,13 @@ export type PathOptions = {
|
||||||
sidebarPath?: string | false | undefined;
|
sidebarPath?: string | false | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO support custom version banner? {type: "error", content: "html content"}
|
||||||
|
export type VersionBanner = 'none' | 'unreleased' | 'unmaintained';
|
||||||
|
|
||||||
export type VersionOptions = {
|
export type VersionOptions = {
|
||||||
path?: string;
|
path?: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
|
banner?: VersionBanner;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type VersionsOptions = {
|
export type VersionsOptions = {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import {
|
import {
|
||||||
PluginOptions,
|
PluginOptions,
|
||||||
|
VersionBanner,
|
||||||
VersionMetadata,
|
VersionMetadata,
|
||||||
VersionOptions,
|
VersionOptions,
|
||||||
VersionsOptions,
|
VersionsOptions,
|
||||||
|
@ -255,14 +256,64 @@ function getVersionEditUrls({
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDefaultVersionBanner({
|
||||||
|
versionName,
|
||||||
|
versionNames,
|
||||||
|
lastVersionName,
|
||||||
|
}: {
|
||||||
|
versionName: string;
|
||||||
|
versionNames: string[];
|
||||||
|
lastVersionName: string;
|
||||||
|
}): VersionBanner {
|
||||||
|
// Current version: good, no banner
|
||||||
|
if (versionName === lastVersionName) {
|
||||||
|
return 'none';
|
||||||
|
}
|
||||||
|
// Upcoming versions: unreleased banner
|
||||||
|
else if (
|
||||||
|
versionNames.indexOf(versionName) < versionNames.indexOf(lastVersionName)
|
||||||
|
) {
|
||||||
|
return 'unreleased';
|
||||||
|
}
|
||||||
|
// Older versions: display unmaintained banner
|
||||||
|
else {
|
||||||
|
return 'unmaintained';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVersionBanner({
|
||||||
|
versionName,
|
||||||
|
versionNames,
|
||||||
|
lastVersionName,
|
||||||
|
options,
|
||||||
|
}: {
|
||||||
|
versionName: string;
|
||||||
|
versionNames: string[];
|
||||||
|
lastVersionName: string;
|
||||||
|
options: Pick<PluginOptions, 'versions'>;
|
||||||
|
}): VersionBanner {
|
||||||
|
const versionOptionBanner = options.versions[versionName]?.banner;
|
||||||
|
|
||||||
|
return (
|
||||||
|
versionOptionBanner ??
|
||||||
|
getDefaultVersionBanner({
|
||||||
|
versionName,
|
||||||
|
versionNames,
|
||||||
|
lastVersionName,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function createVersionMetadata({
|
function createVersionMetadata({
|
||||||
versionName,
|
versionName,
|
||||||
isLast,
|
versionNames,
|
||||||
|
lastVersionName,
|
||||||
context,
|
context,
|
||||||
options,
|
options,
|
||||||
}: {
|
}: {
|
||||||
versionName: string;
|
versionName: string;
|
||||||
isLast: boolean;
|
versionNames: string[];
|
||||||
|
lastVersionName: string;
|
||||||
context: Pick<LoadContext, 'siteDir' | 'baseUrl' | 'i18n'>;
|
context: Pick<LoadContext, 'siteDir' | 'baseUrl' | 'i18n'>;
|
||||||
options: Pick<
|
options: Pick<
|
||||||
PluginOptions,
|
PluginOptions,
|
||||||
|
@ -285,6 +336,8 @@ function createVersionMetadata({
|
||||||
options,
|
options,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isLast = versionName === lastVersionName;
|
||||||
|
|
||||||
// retro-compatible values
|
// retro-compatible values
|
||||||
const defaultVersionLabel =
|
const defaultVersionLabel =
|
||||||
versionName === CURRENT_VERSION_NAME ? 'Next' : versionName;
|
versionName === CURRENT_VERSION_NAME ? 'Next' : versionName;
|
||||||
|
@ -321,6 +374,12 @@ function createVersionMetadata({
|
||||||
versionPath,
|
versionPath,
|
||||||
versionEditUrl: versionEditUrls?.versionEditUrl,
|
versionEditUrl: versionEditUrls?.versionEditUrl,
|
||||||
versionEditUrlLocalized: versionEditUrls?.versionEditUrlLocalized,
|
versionEditUrlLocalized: versionEditUrls?.versionEditUrlLocalized,
|
||||||
|
versionBanner: getVersionBanner({
|
||||||
|
versionName,
|
||||||
|
versionNames,
|
||||||
|
lastVersionName,
|
||||||
|
options,
|
||||||
|
}),
|
||||||
isLast,
|
isLast,
|
||||||
routePriority,
|
routePriority,
|
||||||
sidebarFilePath,
|
sidebarFilePath,
|
||||||
|
@ -486,7 +545,8 @@ export function readVersionsMetadata({
|
||||||
const versionsMetadata = versionNames.map((versionName) =>
|
const versionsMetadata = versionNames.map((versionName) =>
|
||||||
createVersionMetadata({
|
createVersionMetadata({
|
||||||
versionName,
|
versionName,
|
||||||
isLast: versionName === lastVersionName,
|
versionNames,
|
||||||
|
lastVersionName,
|
||||||
context,
|
context,
|
||||||
options,
|
options,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import DocPaginator from '@theme/DocPaginator';
|
import DocPaginator from '@theme/DocPaginator';
|
||||||
import DocVersionSuggestions from '@theme/DocVersionSuggestions';
|
import DocVersionBanner from '@theme/DocVersionBanner';
|
||||||
import Seo from '@theme/Seo';
|
import Seo from '@theme/Seo';
|
||||||
import LastUpdated from '@theme/LastUpdated';
|
import LastUpdated from '@theme/LastUpdated';
|
||||||
import type {Props} from '@theme/DocItem';
|
import type {Props} from '@theme/DocItem';
|
||||||
|
@ -17,14 +17,10 @@ import {MainHeading} from '@theme/Heading';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
import {
|
import {useActivePlugin, useVersions} from '@theme/hooks/useDocs';
|
||||||
useActivePlugin,
|
|
||||||
useVersions,
|
|
||||||
useActiveVersion,
|
|
||||||
} from '@theme/hooks/useDocs';
|
|
||||||
|
|
||||||
function DocItem(props: Props): JSX.Element {
|
function DocItem(props: Props): JSX.Element {
|
||||||
const {content: DocContent} = props;
|
const {content: DocContent, versionMetadata} = props;
|
||||||
const {metadata, frontMatter} = DocContent;
|
const {metadata, frontMatter} = DocContent;
|
||||||
const {
|
const {
|
||||||
image,
|
image,
|
||||||
|
@ -43,7 +39,6 @@ function DocItem(props: Props): JSX.Element {
|
||||||
|
|
||||||
const {pluginId} = useActivePlugin({failfast: true});
|
const {pluginId} = useActivePlugin({failfast: true});
|
||||||
const versions = useVersions(pluginId);
|
const versions = useVersions(pluginId);
|
||||||
const version = useActiveVersion(pluginId);
|
|
||||||
|
|
||||||
// If site is not versioned or only one version is included
|
// If site is not versioned or only one version is included
|
||||||
// we don't show the version badge
|
// we don't show the version badge
|
||||||
|
@ -65,12 +60,12 @@ function DocItem(props: Props): JSX.Element {
|
||||||
className={clsx('col', {
|
className={clsx('col', {
|
||||||
[styles.docItemCol]: !hideTableOfContents,
|
[styles.docItemCol]: !hideTableOfContents,
|
||||||
})}>
|
})}>
|
||||||
<DocVersionSuggestions />
|
<DocVersionBanner versionMetadata={versionMetadata} />
|
||||||
<div className={styles.docItemContainer}>
|
<div className={styles.docItemContainer}>
|
||||||
<article>
|
<article>
|
||||||
{showVersionBadge && (
|
{showVersionBadge && (
|
||||||
<span className="badge badge--secondary">
|
<span className="badge badge--secondary">
|
||||||
Version: {version.label}
|
Version: {versionMetadata.label}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -174,7 +174,7 @@ function DocPage(props: Props): JSX.Element {
|
||||||
<DocPageContent
|
<DocPageContent
|
||||||
currentDocRoute={currentDocRoute}
|
currentDocRoute={currentDocRoute}
|
||||||
versionMetadata={versionMetadata}>
|
versionMetadata={versionMetadata}>
|
||||||
{renderRoutes(docRoutes)}
|
{renderRoutes(docRoutes, {versionMetadata})}
|
||||||
</DocPageContent>
|
</DocPageContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,31 +5,31 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React, {ComponentType} from 'react';
|
||||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
import Translate from '@docusaurus/Translate';
|
import Translate from '@docusaurus/Translate';
|
||||||
import {
|
import {useActivePlugin, useDocVersionSuggestions} from '@theme/hooks/useDocs';
|
||||||
useActivePlugin,
|
|
||||||
useActiveVersion,
|
|
||||||
useDocVersionSuggestions,
|
|
||||||
} from '@theme/hooks/useDocs';
|
|
||||||
import {useDocsPreferredVersion} from '@docusaurus/theme-common';
|
import {useDocsPreferredVersion} from '@docusaurus/theme-common';
|
||||||
|
|
||||||
|
import type {Props} from '@theme/DocVersionBanner';
|
||||||
|
|
||||||
|
type BannerLabelComponentProps = {
|
||||||
|
siteTitle: string;
|
||||||
|
versionMetadata: Props['versionMetadata'];
|
||||||
|
};
|
||||||
|
|
||||||
function UnreleasedVersionLabel({
|
function UnreleasedVersionLabel({
|
||||||
siteTitle,
|
siteTitle,
|
||||||
versionLabel,
|
versionMetadata,
|
||||||
}: {
|
}: BannerLabelComponentProps) {
|
||||||
siteTitle: string;
|
|
||||||
versionLabel: string;
|
|
||||||
}) {
|
|
||||||
return (
|
return (
|
||||||
<Translate
|
<Translate
|
||||||
id="theme.docs.versions.unreleasedVersionLabel"
|
id="theme.docs.versions.unreleasedVersionLabel"
|
||||||
description="The label used to tell the user that he's browsing an unreleased doc version"
|
description="The label used to tell the user that he's browsing an unreleased doc version"
|
||||||
values={{
|
values={{
|
||||||
siteTitle,
|
siteTitle,
|
||||||
versionLabel: <b>{versionLabel}</b>,
|
versionLabel: <b>{versionMetadata.label}</b>,
|
||||||
}}>
|
}}>
|
||||||
{
|
{
|
||||||
'This is unreleased documentation for {siteTitle} {versionLabel} version.'
|
'This is unreleased documentation for {siteTitle} {versionLabel} version.'
|
||||||
|
@ -40,18 +40,15 @@ function UnreleasedVersionLabel({
|
||||||
|
|
||||||
function UnmaintainedVersionLabel({
|
function UnmaintainedVersionLabel({
|
||||||
siteTitle,
|
siteTitle,
|
||||||
versionLabel,
|
versionMetadata,
|
||||||
}: {
|
}: BannerLabelComponentProps) {
|
||||||
siteTitle: string;
|
|
||||||
versionLabel: string;
|
|
||||||
}) {
|
|
||||||
return (
|
return (
|
||||||
<Translate
|
<Translate
|
||||||
id="theme.docs.versions.unmaintainedVersionLabel"
|
id="theme.docs.versions.unmaintainedVersionLabel"
|
||||||
description="The label used to tell the user that he's browsing an unmaintained doc version"
|
description="The label used to tell the user that he's browsing an unmaintained doc version"
|
||||||
values={{
|
values={{
|
||||||
siteTitle,
|
siteTitle,
|
||||||
versionLabel: <b>{versionLabel}</b>,
|
versionLabel: <b>{versionMetadata.label}</b>,
|
||||||
}}>
|
}}>
|
||||||
{
|
{
|
||||||
'This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.'
|
'This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.'
|
||||||
|
@ -60,6 +57,20 @@ function UnmaintainedVersionLabel({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BannerLabelComponents: Record<
|
||||||
|
Props['versionMetadata']['banner'],
|
||||||
|
ComponentType<BannerLabelComponentProps>
|
||||||
|
> = {
|
||||||
|
unreleased: UnreleasedVersionLabel,
|
||||||
|
unmaintained: UnmaintainedVersionLabel,
|
||||||
|
};
|
||||||
|
|
||||||
|
function BannerLabel(props: BannerLabelComponentProps) {
|
||||||
|
const BannerLabelComponent =
|
||||||
|
BannerLabelComponents[props.versionMetadata.banner];
|
||||||
|
return <BannerLabelComponent {...props} />;
|
||||||
|
}
|
||||||
|
|
||||||
function LatestVersionSuggestionLabel({
|
function LatestVersionSuggestionLabel({
|
||||||
versionLabel,
|
versionLabel,
|
||||||
to,
|
to,
|
||||||
|
@ -72,7 +83,7 @@ function LatestVersionSuggestionLabel({
|
||||||
return (
|
return (
|
||||||
<Translate
|
<Translate
|
||||||
id="theme.docs.versions.latestVersionSuggestionLabel"
|
id="theme.docs.versions.latestVersionSuggestionLabel"
|
||||||
description="The label userd to tell the user that he's browsing an unmaintained doc version"
|
description="The label used to tell the user to check the latest version"
|
||||||
values={{
|
values={{
|
||||||
versionLabel,
|
versionLabel,
|
||||||
latestVersionLink: (
|
latestVersionLink: (
|
||||||
|
@ -94,28 +105,22 @@ function LatestVersionSuggestionLabel({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getVersionMainDoc = (version) =>
|
function DocVersionBannerEnabled({versionMetadata}: Props): JSX.Element {
|
||||||
version.docs.find((doc) => doc.id === version.mainDocId);
|
|
||||||
|
|
||||||
function DocVersionSuggestions(): JSX.Element {
|
|
||||||
const {
|
const {
|
||||||
siteConfig: {title: siteTitle},
|
siteConfig: {title: siteTitle},
|
||||||
} = useDocusaurusContext();
|
} = useDocusaurusContext();
|
||||||
const {pluginId} = useActivePlugin({failfast: true});
|
const {pluginId} = useActivePlugin({failfast: true});
|
||||||
|
|
||||||
|
const getVersionMainDoc = (version) =>
|
||||||
|
version.docs.find((doc) => doc.id === version.mainDocId);
|
||||||
|
|
||||||
const {savePreferredVersionName} = useDocsPreferredVersion(pluginId);
|
const {savePreferredVersionName} = useDocsPreferredVersion(pluginId);
|
||||||
|
|
||||||
const activeVersion = useActiveVersion(pluginId);
|
|
||||||
const {
|
const {
|
||||||
latestDocSuggestion,
|
latestDocSuggestion,
|
||||||
latestVersionSuggestion,
|
latestVersionSuggestion,
|
||||||
} = useDocVersionSuggestions(pluginId);
|
} = useDocVersionSuggestions(pluginId);
|
||||||
|
|
||||||
// No suggestion to be made
|
|
||||||
if (!latestVersionSuggestion) {
|
|
||||||
return <></>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to link to same doc in latest version (not always possible)
|
// try to link to same doc in latest version (not always possible)
|
||||||
// fallback to main doc of latest version
|
// fallback to main doc of latest version
|
||||||
const latestVersionSuggestedDoc =
|
const latestVersionSuggestedDoc =
|
||||||
|
@ -124,17 +129,7 @@ function DocVersionSuggestions(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div className="alert alert--warning margin-bottom--md" role="alert">
|
<div className="alert alert--warning margin-bottom--md" role="alert">
|
||||||
<div>
|
<div>
|
||||||
{activeVersion.name === 'current' ? (
|
<BannerLabel siteTitle={siteTitle} versionMetadata={versionMetadata} />
|
||||||
<UnreleasedVersionLabel
|
|
||||||
siteTitle={siteTitle}
|
|
||||||
versionLabel={activeVersion.label}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<UnmaintainedVersionLabel
|
|
||||||
siteTitle={siteTitle}
|
|
||||||
versionLabel={activeVersion.label}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="margin-top--md">
|
<div className="margin-top--md">
|
||||||
<LatestVersionSuggestionLabel
|
<LatestVersionSuggestionLabel
|
||||||
|
@ -147,4 +142,12 @@ function DocVersionSuggestions(): JSX.Element {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DocVersionSuggestions;
|
function DocVersionBanner({versionMetadata}: Props): JSX.Element {
|
||||||
|
if (versionMetadata.banner === 'none') {
|
||||||
|
return <></>;
|
||||||
|
} else {
|
||||||
|
return <DocVersionBannerEnabled versionMetadata={versionMetadata} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DocVersionBanner;
|
|
@ -145,14 +145,14 @@ module.exports = {
|
||||||
/**
|
/**
|
||||||
* By default, versioning is enabled on versioned sites.
|
* By default, versioning is enabled on versioned sites.
|
||||||
* This is a way to explicitly disable the versioning feature.
|
* This is a way to explicitly disable the versioning feature.
|
||||||
|
* This will only include the "current" version (the `/docs` directory)
|
||||||
*/
|
*/
|
||||||
disableVersioning: false,
|
disableVersioning: false,
|
||||||
/**
|
/**
|
||||||
* Skip the next release docs when versioning is enabled.
|
* Include the "current" version of your docs (the `/docs` directory)
|
||||||
* This will not generate HTML files in the production build for documents
|
* Tip: turn it off if the current version is a work-in-progress, not ready to be published
|
||||||
* in `/docs/next` directory, only versioned docs.
|
|
||||||
*/
|
*/
|
||||||
excludeNextVersionDocs: false,
|
includeCurrentVersion: true,
|
||||||
/**
|
/**
|
||||||
* The last version is the one we navigate to in priority on versioned sites
|
* The last version is the one we navigate to in priority on versioned sites
|
||||||
* It is the one displayed by default in docs navbar items
|
* It is the one displayed by default in docs navbar items
|
||||||
|
@ -164,8 +164,10 @@ module.exports = {
|
||||||
lastVersion: undefined,
|
lastVersion: undefined,
|
||||||
/**
|
/**
|
||||||
* The docusaurus versioning defaults don't make sense for all projects
|
* The docusaurus versioning defaults don't make sense for all projects
|
||||||
* This gives the ability customize the label and path of each version
|
* This gives the ability customize the properties of each version independantly
|
||||||
* You may not like that default version
|
* - label: the label of the version
|
||||||
|
* - path: the route path of the version
|
||||||
|
* - banner: the banner to show at the top of a doc of that version: "none" | "unreleased" | "unmaintained"
|
||||||
*/
|
*/
|
||||||
versions: {
|
versions: {
|
||||||
/*
|
/*
|
||||||
|
@ -173,10 +175,12 @@ module.exports = {
|
||||||
current: {
|
current: {
|
||||||
label: 'Android SDK v2.0.0 (WIP)',
|
label: 'Android SDK v2.0.0 (WIP)',
|
||||||
path: 'android-2.0.0',
|
path: 'android-2.0.0',
|
||||||
|
banner: 'none',
|
||||||
},
|
},
|
||||||
'1.0.0': {
|
'1.0.0': {
|
||||||
label: 'Android SDK v1.0.0',
|
label: 'Android SDK v1.0.0',
|
||||||
path: 'android-1.0.0',
|
path: 'android-1.0.0',
|
||||||
|
banner: 'unmaintained',
|
||||||
},
|
},
|
||||||
*/
|
*/
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue