@docusaurus/theme-classic 0.0.0-4238 → 0.0.0-4243
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +4 -1
- package/lib/theme/DocCard/index.js +84 -0
- package/lib/theme/DocCard/styles.module.css +43 -0
- package/lib/theme/DocCardList/index.js +28 -0
- package/lib/theme/DocCategoryGeneratedIndexPage/index.js +57 -0
- package/lib/theme/DocCategoryGeneratedIndexPage/styles.module.css +18 -0
- package/lib/theme/DocItem/index.js +6 -7
- package/lib/theme/DocPage/index.js +16 -9
- package/lib/theme/DocPaginator/index.js +6 -7
- package/lib/theme/DocSidebar/index.js +10 -1
- package/lib/theme/DocSidebarItem/index.js +64 -30
- package/lib/theme/DocSidebarItem/styles.module.css +4 -0
- package/lib/theme/DocVersionBadge/index.js +34 -0
- package/lib/theme/DocVersionBanner/index.js +8 -8
- package/lib/theme-classic.d.ts +5 -4
- package/lib-next/index.js +5 -1
- package/lib-next/theme/DocCard/index.js +80 -0
- package/lib-next/theme/DocCard/styles.module.css +43 -0
- package/lib-next/theme/DocCardList/index.js +19 -0
- package/lib-next/theme/DocCategoryGeneratedIndexPage/index.js +49 -0
- package/lib-next/theme/DocCategoryGeneratedIndexPage/styles.module.css +18 -0
- package/lib-next/theme/DocItem/index.js +5 -12
- package/lib-next/theme/DocPage/index.js +31 -14
- package/lib-next/theme/DocPaginator/index.js +7 -11
- package/lib-next/theme/DocSidebar/index.js +10 -1
- package/lib-next/theme/DocSidebarItem/index.js +78 -37
- package/lib-next/theme/DocSidebarItem/styles.module.css +4 -0
- package/lib-next/theme/DocVersionBadge/index.js +27 -0
- package/lib-next/theme/DocVersionBanner/index.js +12 -5
- package/lib-next/theme-classic.d.ts +5 -4
- package/package.json +13 -13
- package/src/index.ts +9 -4
- package/src/theme/DocCard/index.tsx +100 -0
- package/src/theme/DocCard/styles.module.css +43 -0
- package/src/theme/DocCardList/index.tsx +27 -0
- package/src/theme/DocCategoryGeneratedIndexPage/index.tsx +53 -0
- package/src/theme/DocCategoryGeneratedIndexPage/styles.module.css +18 -0
- package/src/theme/DocItem/index.tsx +5 -12
- package/src/theme/DocPage/index.tsx +28 -12
- package/src/theme/DocPaginator/index.tsx +9 -13
- package/src/theme/DocSidebar/index.tsx +9 -1
- package/src/theme/DocSidebarItem/index.tsx +77 -38
- package/src/theme/DocSidebarItem/styles.module.css +4 -0
- package/src/theme/DocVersionBadge/index.tsx +30 -0
- package/src/theme/DocVersionBanner/index.tsx +23 -7
- package/src/theme-classic.d.ts +5 -4
- package/src/translations.ts +2 -0
package/lib-next/index.js
CHANGED
|
@@ -123,7 +123,11 @@ export default function docusaurusThemeClassic(
|
|
|
123
123
|
getTranslationFiles({
|
|
124
124
|
themeConfig,
|
|
125
125
|
}),
|
|
126
|
-
translateThemeConfig
|
|
126
|
+
translateThemeConfig: (params) =>
|
|
127
|
+
translateThemeConfig({
|
|
128
|
+
themeConfig: params.themeConfig,
|
|
129
|
+
translationFiles: params.translationFiles,
|
|
130
|
+
}),
|
|
127
131
|
|
|
128
132
|
getDefaultCodeTranslationMessages() {
|
|
129
133
|
return readDefaultCodeTranslationMessages({
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import Link from '@docusaurus/Link';
|
|
9
|
+
import {findFirstCategoryLink, useDocById} from '@docusaurus/theme-common';
|
|
10
|
+
import clsx from 'clsx';
|
|
11
|
+
import styles from './styles.module.css';
|
|
12
|
+
import isInternalUrl from '@docusaurus/isInternalUrl';
|
|
13
|
+
|
|
14
|
+
function CardContainer({href, children}) {
|
|
15
|
+
const className = clsx(
|
|
16
|
+
'card margin-bottom--lg padding--lg',
|
|
17
|
+
styles.cardContainer,
|
|
18
|
+
href && styles.cardContainerLink,
|
|
19
|
+
);
|
|
20
|
+
return href ? (
|
|
21
|
+
<Link href={href} className={className}>
|
|
22
|
+
{children}
|
|
23
|
+
</Link>
|
|
24
|
+
) : (
|
|
25
|
+
<div className={className}>{children}</div>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function CardLayout({href, icon, title, description}) {
|
|
30
|
+
return (
|
|
31
|
+
<CardContainer href={href}>
|
|
32
|
+
<h2 className={clsx('text--truncate', styles.cardTitle)} title={title}>
|
|
33
|
+
{icon} {title}
|
|
34
|
+
</h2>
|
|
35
|
+
<div
|
|
36
|
+
className={clsx('text--truncate', styles.cardDescription)}
|
|
37
|
+
title={description}>
|
|
38
|
+
{description}
|
|
39
|
+
</div>
|
|
40
|
+
</CardContainer>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function CardCategory({item}) {
|
|
45
|
+
const href = findFirstCategoryLink(item);
|
|
46
|
+
return (
|
|
47
|
+
<CardLayout
|
|
48
|
+
href={href}
|
|
49
|
+
icon="🗃️"
|
|
50
|
+
title={item.label}
|
|
51
|
+
description={`${item.items.length} items`}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function CardLink({item}) {
|
|
57
|
+
const icon = isInternalUrl(item.href) ? '📄️' : '🔗';
|
|
58
|
+
const doc = useDocById(item.docId ?? undefined);
|
|
59
|
+
return (
|
|
60
|
+
<CardLayout
|
|
61
|
+
href={item.href}
|
|
62
|
+
icon={icon}
|
|
63
|
+
title={item.label}
|
|
64
|
+
description={doc?.description}
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default function DocCard({item}) {
|
|
70
|
+
switch (item.type) {
|
|
71
|
+
case 'link':
|
|
72
|
+
return <CardLink item={item} />;
|
|
73
|
+
|
|
74
|
+
case 'category':
|
|
75
|
+
return <CardCategory item={item} />;
|
|
76
|
+
|
|
77
|
+
default:
|
|
78
|
+
throw new Error(`unknown item type ${JSON.stringify(item)}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
.cardContainer {
|
|
9
|
+
height: 8rem;
|
|
10
|
+
|
|
11
|
+
color: var(--ifm-color-emphasis-800);
|
|
12
|
+
--ifm-link-color: var(--ifm-color-emphasis-800);
|
|
13
|
+
--ifm-link-hover-color: var(--ifm-color-emphasis-800);
|
|
14
|
+
--ifm-link-hover-decoration: none;
|
|
15
|
+
|
|
16
|
+
/* box-shadow: var(--ifm-global-shadow-lw); */
|
|
17
|
+
box-shadow: 0 1.5px 3px 0 rgba(0, 0, 0, 0.15);
|
|
18
|
+
border: 1px solid var(--ifm-color-emphasis-200);
|
|
19
|
+
transition: box-shadow var(--ifm-transition-fast) ease,
|
|
20
|
+
background-color var(--ifm-transition-fast) ease;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.cardContainer.cardContainerLink:hover {
|
|
24
|
+
/* box-shadow: var(--ifm-global-shadow-md); */
|
|
25
|
+
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
|
|
26
|
+
}
|
|
27
|
+
html[data-theme='dark'] .cardContainer.cardContainerLink:hover {
|
|
28
|
+
--ifm-card-background-color: #2d2d2d; /* original, non-hovered color is #242526 */
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.cardContainer:not(.cardContainerLink) {
|
|
32
|
+
cursor: not-allowed;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.cardTitle {
|
|
36
|
+
font-size: 1.2rem;
|
|
37
|
+
min-height: 1.2rem;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.cardDescription {
|
|
41
|
+
font-size: 0.8rem;
|
|
42
|
+
min-height: 0.8rem;
|
|
43
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import DocCard from '@theme/DocCard';
|
|
9
|
+
export default function DocCardList({items}) {
|
|
10
|
+
return (
|
|
11
|
+
<div className="row">
|
|
12
|
+
{items.map((item, index) => (
|
|
13
|
+
<article key={index} className="col col--6">
|
|
14
|
+
<DocCard item={item} />
|
|
15
|
+
</article>
|
|
16
|
+
))}
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
9
|
+
import DocCardList from '@theme/DocCardList';
|
|
10
|
+
import DocPaginator from '@theme/DocPaginator';
|
|
11
|
+
import Seo from '@theme/Seo';
|
|
12
|
+
import DocVersionBanner from '@theme/DocVersionBanner';
|
|
13
|
+
import DocVersionBadge from '@theme/DocVersionBadge';
|
|
14
|
+
import {MainHeading} from '@theme/Heading';
|
|
15
|
+
import styles from './styles.module.css';
|
|
16
|
+
export default function DocCategoryGeneratedIndexPage({
|
|
17
|
+
categoryGeneratedIndex,
|
|
18
|
+
}) {
|
|
19
|
+
const category = useCurrentSidebarCategory();
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
<Seo
|
|
23
|
+
title={categoryGeneratedIndex.title}
|
|
24
|
+
description={categoryGeneratedIndex.description}
|
|
25
|
+
/>
|
|
26
|
+
<div className={styles.generatedIndexPage}>
|
|
27
|
+
<DocVersionBanner />
|
|
28
|
+
<DocVersionBadge />
|
|
29
|
+
<header>
|
|
30
|
+
<MainHeading className={styles.title}>
|
|
31
|
+
{categoryGeneratedIndex.title}
|
|
32
|
+
</MainHeading>
|
|
33
|
+
{categoryGeneratedIndex.description && (
|
|
34
|
+
<p>{categoryGeneratedIndex.description}</p>
|
|
35
|
+
)}
|
|
36
|
+
</header>
|
|
37
|
+
<main className="margin-top--lg">
|
|
38
|
+
<DocCardList items={category.items} />
|
|
39
|
+
</main>
|
|
40
|
+
<footer className="margin-top--lg">
|
|
41
|
+
<DocPaginator
|
|
42
|
+
previous={categoryGeneratedIndex.navigation.previous}
|
|
43
|
+
next={categoryGeneratedIndex.navigation.next}
|
|
44
|
+
/>
|
|
45
|
+
</footer>
|
|
46
|
+
</div>
|
|
47
|
+
</>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
@media (min-width: 997px) {
|
|
9
|
+
.generatedIndexPage {
|
|
10
|
+
max-width: 75% !important;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Duplicated from .markdown h1 */
|
|
15
|
+
.title {
|
|
16
|
+
--ifm-h1-font-size: 3rem;
|
|
17
|
+
margin-bottom: calc(1.25 * var(--ifm-leading));
|
|
18
|
+
}
|
|
@@ -9,6 +9,7 @@ import clsx from 'clsx';
|
|
|
9
9
|
import useWindowSize from '@theme/hooks/useWindowSize';
|
|
10
10
|
import DocPaginator from '@theme/DocPaginator';
|
|
11
11
|
import DocVersionBanner from '@theme/DocVersionBanner';
|
|
12
|
+
import DocVersionBadge from '@theme/DocVersionBadge';
|
|
12
13
|
import Seo from '@theme/Seo';
|
|
13
14
|
import DocItemFooter from '@theme/DocItemFooter';
|
|
14
15
|
import TOC from '@theme/TOC';
|
|
@@ -17,7 +18,7 @@ import {MainHeading} from '@theme/Heading';
|
|
|
17
18
|
import styles from './styles.module.css';
|
|
18
19
|
import {ThemeClassNames} from '@docusaurus/theme-common';
|
|
19
20
|
export default function DocItem(props) {
|
|
20
|
-
const {content: DocContent
|
|
21
|
+
const {content: DocContent} = props;
|
|
21
22
|
const {metadata, frontMatter} = DocContent;
|
|
22
23
|
const {
|
|
23
24
|
image,
|
|
@@ -54,18 +55,10 @@ export default function DocItem(props) {
|
|
|
54
55
|
className={clsx('col', {
|
|
55
56
|
[styles.docItemCol]: !hideTableOfContents,
|
|
56
57
|
})}>
|
|
57
|
-
<DocVersionBanner
|
|
58
|
+
<DocVersionBanner />
|
|
58
59
|
<div className={styles.docItemContainer}>
|
|
59
60
|
<article>
|
|
60
|
-
|
|
61
|
-
<span
|
|
62
|
-
className={clsx(
|
|
63
|
-
ThemeClassNames.docs.docVersionBadge,
|
|
64
|
-
'badge badge--secondary',
|
|
65
|
-
)}>
|
|
66
|
-
Version: {versionMetadata.label}
|
|
67
|
-
</span>
|
|
68
|
-
)}
|
|
61
|
+
<DocVersionBadge />
|
|
69
62
|
|
|
70
63
|
{canRenderTOC && (
|
|
71
64
|
<TOCCollapsible
|
|
@@ -94,7 +87,7 @@ export default function DocItem(props) {
|
|
|
94
87
|
<DocItemFooter {...props} />
|
|
95
88
|
</article>
|
|
96
89
|
|
|
97
|
-
<DocPaginator metadata={metadata} />
|
|
90
|
+
<DocPaginator previous={metadata.previous} next={metadata.next} />
|
|
98
91
|
</div>
|
|
99
92
|
</div>
|
|
100
93
|
{renderTocDesktop && (
|
|
@@ -17,15 +17,23 @@ import {matchPath} from '@docusaurus/router';
|
|
|
17
17
|
import {translate} from '@docusaurus/Translate';
|
|
18
18
|
import clsx from 'clsx';
|
|
19
19
|
import styles from './styles.module.css';
|
|
20
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
ThemeClassNames,
|
|
22
|
+
docVersionSearchTag,
|
|
23
|
+
DocsSidebarProvider,
|
|
24
|
+
useDocsSidebar,
|
|
25
|
+
DocsVersionProvider,
|
|
26
|
+
} from '@docusaurus/theme-common';
|
|
21
27
|
import Head from '@docusaurus/Head';
|
|
22
28
|
|
|
23
|
-
function DocPageContent({
|
|
29
|
+
function DocPageContent({
|
|
30
|
+
currentDocRoute,
|
|
31
|
+
versionMetadata,
|
|
32
|
+
children,
|
|
33
|
+
sidebarName,
|
|
34
|
+
}) {
|
|
35
|
+
const sidebar = useDocsSidebar();
|
|
24
36
|
const {pluginId, version} = versionMetadata;
|
|
25
|
-
const sidebarName = currentDocRoute.sidebar;
|
|
26
|
-
const sidebar = sidebarName
|
|
27
|
-
? versionMetadata.docsSidebars[sidebarName]
|
|
28
|
-
: undefined;
|
|
29
37
|
const [hiddenSidebarContainer, setHiddenSidebarContainer] = useState(false);
|
|
30
38
|
const [hiddenSidebar, setHiddenSidebar] = useState(false);
|
|
31
39
|
const toggleSidebar = useCallback(() => {
|
|
@@ -131,21 +139,30 @@ function DocPage(props) {
|
|
|
131
139
|
|
|
132
140
|
if (!currentDocRoute) {
|
|
133
141
|
return <NotFound />;
|
|
134
|
-
}
|
|
142
|
+
} // For now, the sidebarName is added as route config: not ideal!
|
|
135
143
|
|
|
144
|
+
const sidebarName = currentDocRoute.sidebar;
|
|
145
|
+
const sidebar = sidebarName
|
|
146
|
+
? versionMetadata.docsSidebars[sidebarName]
|
|
147
|
+
: null;
|
|
136
148
|
return (
|
|
137
149
|
<>
|
|
138
150
|
<Head>
|
|
139
151
|
{/* TODO we should add a core addRoute({htmlClassName}) generic plugin option */}
|
|
140
152
|
<html className={versionMetadata.className} />
|
|
141
153
|
</Head>
|
|
142
|
-
<
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
154
|
+
<DocsVersionProvider version={versionMetadata}>
|
|
155
|
+
<DocsSidebarProvider sidebar={sidebar}>
|
|
156
|
+
<DocPageContent
|
|
157
|
+
currentDocRoute={currentDocRoute}
|
|
158
|
+
versionMetadata={versionMetadata}
|
|
159
|
+
sidebarName={sidebarName}>
|
|
160
|
+
{renderRoutes(docRoutes, {
|
|
161
|
+
versionMetadata,
|
|
162
|
+
})}
|
|
163
|
+
</DocPageContent>
|
|
164
|
+
</DocsSidebarProvider>
|
|
165
|
+
</DocsVersionProvider>
|
|
149
166
|
</>
|
|
150
167
|
);
|
|
151
168
|
}
|
|
@@ -9,7 +9,7 @@ import Link from '@docusaurus/Link';
|
|
|
9
9
|
import Translate, {translate} from '@docusaurus/Translate';
|
|
10
10
|
|
|
11
11
|
function DocPaginator(props) {
|
|
12
|
-
const {
|
|
12
|
+
const {previous, next} = props;
|
|
13
13
|
return (
|
|
14
14
|
<nav
|
|
15
15
|
className="pagination-nav docusaurus-mt-lg"
|
|
@@ -19,10 +19,8 @@ function DocPaginator(props) {
|
|
|
19
19
|
description: 'The ARIA label for the docs pagination',
|
|
20
20
|
})}>
|
|
21
21
|
<div className="pagination-nav__item">
|
|
22
|
-
{
|
|
23
|
-
<Link
|
|
24
|
-
className="pagination-nav__link"
|
|
25
|
-
to={metadata.previous.permalink}>
|
|
22
|
+
{previous && (
|
|
23
|
+
<Link className="pagination-nav__link" to={previous.permalink}>
|
|
26
24
|
<div className="pagination-nav__sublabel">
|
|
27
25
|
<Translate
|
|
28
26
|
id="theme.docs.paginator.previous"
|
|
@@ -31,14 +29,14 @@ function DocPaginator(props) {
|
|
|
31
29
|
</Translate>
|
|
32
30
|
</div>
|
|
33
31
|
<div className="pagination-nav__label">
|
|
34
|
-
« {
|
|
32
|
+
« {previous.title}
|
|
35
33
|
</div>
|
|
36
34
|
</Link>
|
|
37
35
|
)}
|
|
38
36
|
</div>
|
|
39
37
|
<div className="pagination-nav__item pagination-nav__item--next">
|
|
40
|
-
{
|
|
41
|
-
<Link className="pagination-nav__link" to={
|
|
38
|
+
{next && (
|
|
39
|
+
<Link className="pagination-nav__link" to={next.permalink}>
|
|
42
40
|
<div className="pagination-nav__sublabel">
|
|
43
41
|
<Translate
|
|
44
42
|
id="theme.docs.paginator.next"
|
|
@@ -46,9 +44,7 @@ function DocPaginator(props) {
|
|
|
46
44
|
Next
|
|
47
45
|
</Translate>
|
|
48
46
|
</div>
|
|
49
|
-
<div className="pagination-nav__label">
|
|
50
|
-
{metadata.next.title} »
|
|
51
|
-
</div>
|
|
47
|
+
<div className="pagination-nav__label">{next.title} »</div>
|
|
52
48
|
</Link>
|
|
53
49
|
)}
|
|
54
50
|
</div>
|
|
@@ -89,7 +89,16 @@ const DocSidebarMobileSecondaryMenu = ({toggleSidebar, sidebar, path}) => (
|
|
|
89
89
|
<DocSidebarItems
|
|
90
90
|
items={sidebar}
|
|
91
91
|
activePath={path}
|
|
92
|
-
onItemClick={() =>
|
|
92
|
+
onItemClick={(item) => {
|
|
93
|
+
// Mobile sidebar should only be closed if the category has a link
|
|
94
|
+
if (item.type === 'category' && item.href) {
|
|
95
|
+
toggleSidebar();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (item.type === 'link') {
|
|
99
|
+
toggleSidebar();
|
|
100
|
+
}
|
|
101
|
+
}}
|
|
93
102
|
level={1}
|
|
94
103
|
/>
|
|
95
104
|
</ul>
|
|
@@ -4,33 +4,22 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import React, {useEffect, memo} from 'react';
|
|
7
|
+
import React, {useEffect, memo, useMemo} from 'react';
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
import {
|
|
10
|
-
|
|
10
|
+
isActiveSidebarItem,
|
|
11
11
|
usePrevious,
|
|
12
12
|
Collapsible,
|
|
13
13
|
useCollapsible,
|
|
14
|
+
findFirstCategoryLink,
|
|
14
15
|
ThemeClassNames,
|
|
15
16
|
} from '@docusaurus/theme-common';
|
|
16
17
|
import Link from '@docusaurus/Link';
|
|
17
18
|
import isInternalUrl from '@docusaurus/isInternalUrl';
|
|
19
|
+
import {translate} from '@docusaurus/Translate';
|
|
18
20
|
import IconExternalLink from '@theme/IconExternalLink';
|
|
19
21
|
import styles from './styles.module.css';
|
|
20
|
-
|
|
21
|
-
const isActiveSidebarItem = (item, activePath) => {
|
|
22
|
-
if (item.type === 'link') {
|
|
23
|
-
return isSamePath(item.href, activePath);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (item.type === 'category') {
|
|
27
|
-
return item.items.some((subItem) =>
|
|
28
|
-
isActiveSidebarItem(subItem, activePath),
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return false;
|
|
33
|
-
}; // Optimize sidebar at each "level"
|
|
22
|
+
import useIsBrowser from '@docusaurus/useIsBrowser'; // Optimize sidebar at each "level"
|
|
34
23
|
// TODO this item should probably not receive the "activePath" props
|
|
35
24
|
// TODO this triggers whole sidebar re-renders on navigation
|
|
36
25
|
|
|
@@ -69,6 +58,26 @@ function useAutoExpandActiveCategory({isActive, collapsed, setCollapsed}) {
|
|
|
69
58
|
setCollapsed(false);
|
|
70
59
|
}
|
|
71
60
|
}, [isActive, wasActive, collapsed, setCollapsed]);
|
|
61
|
+
} // When a collapsible category has no link, we still link it to its first child during SSR as a temporary fallback
|
|
62
|
+
// This allows to be able to navigate inside the category even when JS fails to load, is delayed or simply disabled
|
|
63
|
+
// React hydration becomes an optional progressive enhancement
|
|
64
|
+
// see https://github.com/facebookincubator/infima/issues/36#issuecomment-772543188
|
|
65
|
+
// see https://github.com/facebook/docusaurus/issues/3030
|
|
66
|
+
|
|
67
|
+
function useCategoryHrefWithSSRFallback(item) {
|
|
68
|
+
const isBrowser = useIsBrowser();
|
|
69
|
+
return useMemo(() => {
|
|
70
|
+
if (item.href) {
|
|
71
|
+
return item.href;
|
|
72
|
+
} // In these cases, it's not necessary to render a fallback
|
|
73
|
+
// We skip the "findFirstCategoryLink" computation
|
|
74
|
+
|
|
75
|
+
if (isBrowser || !item.collapsible) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return findFirstCategoryLink(item);
|
|
80
|
+
}, [item, isBrowser]);
|
|
72
81
|
}
|
|
73
82
|
|
|
74
83
|
function DocSidebarItemCategory({
|
|
@@ -78,7 +87,8 @@ function DocSidebarItemCategory({
|
|
|
78
87
|
level,
|
|
79
88
|
...props
|
|
80
89
|
}) {
|
|
81
|
-
const {items, label, collapsible, className} = item;
|
|
90
|
+
const {items, label, collapsible, className, href} = item;
|
|
91
|
+
const hrefWithSSRFallback = useCategoryHrefWithSSRFallback(item);
|
|
82
92
|
const isActive = isActiveSidebarItem(item, activePath);
|
|
83
93
|
const {collapsed, setCollapsed, toggleCollapsed} = useCollapsible({
|
|
84
94
|
// active categories are always initialized as expanded
|
|
@@ -107,25 +117,56 @@ function DocSidebarItemCategory({
|
|
|
107
117
|
},
|
|
108
118
|
className,
|
|
109
119
|
)}>
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
120
|
+
<div className="menu__list-item-collapsible">
|
|
121
|
+
<Link
|
|
122
|
+
className={clsx('menu__link', {
|
|
123
|
+
'menu__link--sublist': collapsible && !href,
|
|
124
|
+
'menu__link--active': isActive,
|
|
125
|
+
[styles.menuLinkText]: !collapsible,
|
|
126
|
+
[styles.hasHref]: !!hrefWithSSRFallback,
|
|
127
|
+
})}
|
|
128
|
+
onClick={
|
|
129
|
+
collapsible
|
|
130
|
+
? (e) => {
|
|
131
|
+
onItemClick?.(item);
|
|
132
|
+
|
|
133
|
+
if (href) {
|
|
134
|
+
setCollapsed(false);
|
|
135
|
+
} else {
|
|
136
|
+
e.preventDefault();
|
|
137
|
+
toggleCollapsed();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
: () => {
|
|
141
|
+
onItemClick?.(item);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
href={collapsible ? hrefWithSSRFallback ?? '#' : hrefWithSSRFallback}
|
|
145
|
+
{...props}>
|
|
146
|
+
{label}
|
|
147
|
+
</Link>
|
|
148
|
+
{href && collapsible && (
|
|
149
|
+
<button
|
|
150
|
+
aria-label={translate(
|
|
151
|
+
{
|
|
152
|
+
id: 'theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel',
|
|
153
|
+
message: "Toggle the collapsible sidebar category '{label}'",
|
|
154
|
+
description:
|
|
155
|
+
'The ARIA label to toggle the collapsible sidebar category',
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
label,
|
|
159
|
+
},
|
|
160
|
+
)}
|
|
161
|
+
type="button"
|
|
162
|
+
className="clean-btn menu__caret"
|
|
163
|
+
onClick={(e) => {
|
|
164
|
+
e.preventDefault();
|
|
165
|
+
toggleCollapsed();
|
|
166
|
+
}}
|
|
167
|
+
/>
|
|
168
|
+
)}
|
|
169
|
+
</div>
|
|
129
170
|
|
|
130
171
|
<Collapsible lazy as="ul" className="menu__list" collapsed={collapsed}>
|
|
131
172
|
<DocSidebarItems
|
|
@@ -159,7 +200,7 @@ function DocSidebarItemLink({item, onItemClick, activePath, level, ...props}) {
|
|
|
159
200
|
aria-current={isActive ? 'page' : undefined}
|
|
160
201
|
to={href}
|
|
161
202
|
{...(isInternalUrl(href) && {
|
|
162
|
-
onClick: onItemClick,
|
|
203
|
+
onClick: onItemClick ? () => onItemClick(item) : undefined,
|
|
163
204
|
})}
|
|
164
205
|
{...props}>
|
|
165
206
|
{isInternalUrl(href) ? (
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import {ThemeClassNames, useDocsVersion} from '@docusaurus/theme-common';
|
|
9
|
+
import clsx from 'clsx';
|
|
10
|
+
export default function DocVersionBadge({className}) {
|
|
11
|
+
const versionMetadata = useDocsVersion();
|
|
12
|
+
|
|
13
|
+
if (versionMetadata.badge) {
|
|
14
|
+
return (
|
|
15
|
+
<span
|
|
16
|
+
className={clsx(
|
|
17
|
+
className,
|
|
18
|
+
ThemeClassNames.docs.docVersionBadge,
|
|
19
|
+
'badge badge--secondary',
|
|
20
|
+
)}>
|
|
21
|
+
Version: {versionMetadata.label}
|
|
22
|
+
</span>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
@@ -12,6 +12,7 @@ import {useActivePlugin, useDocVersionSuggestions} from '@theme/hooks/useDocs';
|
|
|
12
12
|
import {
|
|
13
13
|
ThemeClassNames,
|
|
14
14
|
useDocsPreferredVersion,
|
|
15
|
+
useDocsVersion,
|
|
15
16
|
} from '@docusaurus/theme-common';
|
|
16
17
|
import clsx from 'clsx';
|
|
17
18
|
|
|
@@ -84,7 +85,7 @@ function LatestVersionSuggestionLabel({versionLabel, to, onClick}) {
|
|
|
84
85
|
);
|
|
85
86
|
}
|
|
86
87
|
|
|
87
|
-
function DocVersionBannerEnabled({versionMetadata}) {
|
|
88
|
+
function DocVersionBannerEnabled({className, versionMetadata}) {
|
|
88
89
|
const {
|
|
89
90
|
siteConfig: {title: siteTitle},
|
|
90
91
|
} = useDocusaurusContext();
|
|
@@ -105,6 +106,7 @@ function DocVersionBannerEnabled({versionMetadata}) {
|
|
|
105
106
|
return (
|
|
106
107
|
<div
|
|
107
108
|
className={clsx(
|
|
109
|
+
className,
|
|
108
110
|
ThemeClassNames.docs.docVersionBanner,
|
|
109
111
|
'alert alert--warning margin-bottom--md',
|
|
110
112
|
)}
|
|
@@ -123,12 +125,17 @@ function DocVersionBannerEnabled({versionMetadata}) {
|
|
|
123
125
|
);
|
|
124
126
|
}
|
|
125
127
|
|
|
126
|
-
function DocVersionBanner({
|
|
128
|
+
export default function DocVersionBanner({className}) {
|
|
129
|
+
const versionMetadata = useDocsVersion();
|
|
130
|
+
|
|
127
131
|
if (versionMetadata.banner) {
|
|
128
|
-
return
|
|
132
|
+
return (
|
|
133
|
+
<DocVersionBannerEnabled
|
|
134
|
+
className={className}
|
|
135
|
+
versionMetadata={versionMetadata}
|
|
136
|
+
/>
|
|
137
|
+
);
|
|
129
138
|
}
|
|
130
139
|
|
|
131
140
|
return null;
|
|
132
141
|
}
|
|
133
|
-
|
|
134
|
-
export default DocVersionBanner;
|
|
@@ -107,11 +107,12 @@ declare module '@theme/CodeBlock' {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
declare module '@theme/DocPaginator' {
|
|
110
|
+
import type {PropNavigation} from '@docusaurus/plugin-content-docs';
|
|
111
|
+
|
|
110
112
|
type PageInfo = {readonly permalink: string; readonly title: string};
|
|
111
113
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
114
|
+
// May be simpler to provide a {navigation: PropNavigation} prop?
|
|
115
|
+
export interface Props extends PropNavigation {}
|
|
115
116
|
|
|
116
117
|
const DocPaginator: (props: Props) => JSX.Element;
|
|
117
118
|
export default DocPaginator;
|
|
@@ -138,7 +139,7 @@ declare module '@theme/DocSidebarItem' {
|
|
|
138
139
|
|
|
139
140
|
type DocSidebarPropsBase = {
|
|
140
141
|
readonly activePath: string;
|
|
141
|
-
readonly onItemClick?: () => void;
|
|
142
|
+
readonly onItemClick?: (item: PropSidebarItem) => void;
|
|
142
143
|
readonly level: number;
|
|
143
144
|
readonly tabIndex?: number;
|
|
144
145
|
};
|