@docusaurus/theme-classic 2.0.0-beta.17 → 2.0.0-beta.18
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/getSwizzleConfig.js +113 -2
- package/lib/index.js +7 -12
- package/lib/theme-classic.d.ts +286 -60
- package/lib/translations.js +12 -2
- package/lib/validateThemeConfig.js +1 -1
- package/lib-next/theme/BackToTopButton/index.js +1 -3
- package/lib-next/theme/BlogArchivePage/index.js +14 -10
- package/lib-next/theme/BlogListPage/index.js +34 -13
- package/lib-next/theme/BlogPostItem/index.js +6 -6
- package/lib-next/theme/BlogPostPage/index.js +56 -45
- package/lib-next/theme/BlogTagsListPage/index.js +16 -12
- package/lib-next/theme/BlogTagsPostsPage/index.js +40 -33
- package/lib-next/theme/CodeBlock/CopyButton/index.js +60 -0
- package/lib-next/theme/CodeBlock/CopyButton/styles.module.css +66 -0
- package/lib-next/theme/CodeBlock/index.js +4 -36
- package/lib-next/theme/CodeBlock/styles.module.css +2 -22
- package/lib-next/theme/ColorModeToggle/index.js +36 -57
- package/lib-next/theme/ColorModeToggle/styles.module.css +8 -24
- package/lib-next/theme/DocBreadcrumbs/index.js +28 -11
- package/lib-next/theme/DocBreadcrumbs/styles.module.css +2 -17
- package/lib-next/theme/DocCard/index.js +17 -15
- package/lib-next/theme/DocCard/styles.module.css +8 -17
- package/lib-next/theme/DocCardList/index.js +15 -3
- package/lib-next/theme/DocCategoryGeneratedIndexPage/index.js +27 -6
- package/lib-next/theme/DocItem/index.js +84 -66
- package/lib-next/theme/DocPage/index.js +88 -89
- package/lib-next/theme/DocPage/styles.module.css +0 -4
- package/lib-next/theme/DocSidebar/Desktop/CollapseButton/index.js +34 -0
- package/lib-next/theme/DocSidebar/Desktop/CollapseButton/styles.module.css +44 -0
- package/lib-next/theme/DocSidebar/Desktop/Content/index.js +46 -0
- package/lib-next/theme/DocSidebar/Desktop/Content/styles.module.css +17 -0
- package/lib-next/theme/DocSidebar/Desktop/index.js +34 -0
- package/lib-next/theme/DocSidebar/Desktop/styles.module.css +50 -0
- package/lib-next/theme/DocSidebar/Mobile/index.js +49 -0
- package/lib-next/theme/DocSidebar/index.js +6 -113
- package/lib-next/theme/DocSidebarItem/index.js +14 -13
- package/lib-next/theme/DocSidebarItem/styles.module.css +4 -0
- package/lib-next/theme/DocTagDocListPage/index.js +38 -31
- package/lib-next/theme/DocTagsListPage/index.js +21 -16
- package/lib-next/theme/Footer/Copyright/index.js +18 -0
- package/lib-next/theme/Footer/Layout/index.js +26 -0
- package/lib-next/theme/Footer/LinkItem/index.js +33 -0
- package/lib-next/theme/Footer/Links/MultiColumn/index.js +47 -0
- package/lib-next/theme/Footer/Links/Simple/index.js +41 -0
- package/lib-next/theme/Footer/Links/index.js +17 -0
- package/lib-next/theme/Footer/Logo/index.js +38 -0
- package/lib-next/theme/Footer/{styles.module.css → Logo/styles.module.css} +0 -0
- package/lib-next/theme/Footer/index.js +11 -163
- package/lib-next/theme/Heading/index.js +6 -4
- package/lib-next/theme/IconExternalLink/styles.module.css +0 -2
- package/lib-next/theme/Layout/index.js +15 -10
- package/lib-next/theme/LayoutProviders/index.js +5 -4
- package/lib-next/theme/MDXComponents/A.js +11 -0
- package/lib-next/theme/MDXComponents/Code.js +28 -0
- package/lib-next/theme/MDXComponents/Details.js +20 -0
- package/lib-next/theme/MDXComponents/Head.js +26 -0
- package/lib-next/theme/MDXComponents/Heading.js +11 -0
- package/lib-next/theme/MDXComponents/Img.js +24 -0
- package/lib-next/theme/MDXComponents/Img.module.css +10 -0
- package/lib-next/theme/MDXComponents/Pre.js +18 -0
- package/lib-next/theme/MDXComponents/Ul.js +23 -0
- package/{src/theme/MDXComponents/styles.css → lib-next/theme/MDXComponents/Ul.module.css} +1 -5
- package/lib-next/theme/MDXComponents/index.js +22 -71
- package/lib-next/theme/MDXContent/index.js +12 -0
- package/lib-next/theme/MDXPage/index.js +33 -28
- package/lib-next/theme/Navbar/ColorModeToggle/index.js +25 -0
- package/lib-next/theme/Navbar/Content/index.js +70 -0
- package/lib-next/theme/Navbar/Content/styles.module.css +15 -0
- package/lib-next/theme/Navbar/Layout/index.js +54 -0
- package/{src/theme/Navbar → lib-next/theme/Navbar/Layout}/styles.module.css +0 -13
- package/lib-next/theme/Navbar/Logo/index.js +17 -0
- package/lib-next/theme/Navbar/MobileSidebar/Header/index.js +33 -0
- package/lib-next/theme/Navbar/MobileSidebar/Layout/index.js +28 -0
- package/lib-next/theme/Navbar/MobileSidebar/PrimaryMenu/index.js +33 -0
- package/lib-next/theme/Navbar/MobileSidebar/SecondaryMenu/index.js +36 -0
- package/lib-next/theme/Navbar/MobileSidebar/Toggle/index.js +23 -0
- package/lib-next/theme/Navbar/MobileSidebar/index.js +31 -0
- package/lib-next/theme/Navbar/index.js +6 -271
- package/lib-next/theme/NavbarItem/DefaultNavbarItem.js +2 -6
- package/lib-next/theme/NavbarItem/DropdownNavbarItem.js +10 -2
- package/lib-next/theme/NavbarItem/NavbarNavLink.js +8 -12
- package/lib-next/theme/NotFound.js +38 -33
- package/lib-next/theme/{LayoutHead → SiteMetadata}/index.js +11 -26
- package/lib-next/theme/TOCCollapsible/index.js +1 -3
- package/lib-next/theme/Tabs/__tests__/index.test.js +5 -5
- package/lib-next/theme/Tabs/index.js +2 -2
- package/lib-next/theme/Tag/index.js +4 -4
- package/lib-next/theme/ThemedImage/index.js +3 -3
- package/package.json +17 -17
- package/src/getSwizzleConfig.ts +122 -1
- package/src/index.ts +10 -12
- package/src/theme/BackToTopButton/index.tsx +1 -3
- package/src/theme/BlogArchivePage/index.tsx +18 -17
- package/src/theme/BlogLayout/index.tsx +1 -1
- package/src/theme/BlogListPage/index.tsx +32 -13
- package/src/theme/BlogPostItem/index.tsx +6 -6
- package/src/theme/BlogPostPage/index.tsx +55 -48
- package/src/theme/BlogTagsListPage/index.tsx +16 -12
- package/src/theme/BlogTagsPostsPage/index.tsx +39 -32
- package/src/theme/CodeBlock/CopyButton/index.tsx +66 -0
- package/src/theme/CodeBlock/CopyButton/styles.module.css +66 -0
- package/src/theme/CodeBlock/index.tsx +6 -38
- package/src/theme/CodeBlock/styles.module.css +2 -22
- package/src/theme/ColorModeToggle/index.tsx +36 -61
- package/src/theme/ColorModeToggle/styles.module.css +8 -24
- package/src/theme/DocBreadcrumbs/index.tsx +29 -10
- package/src/theme/DocBreadcrumbs/styles.module.css +2 -17
- package/src/theme/DocCard/index.tsx +24 -17
- package/src/theme/DocCard/styles.module.css +8 -17
- package/src/theme/DocCardList/index.tsx +14 -3
- package/src/theme/DocCategoryGeneratedIndexPage/index.tsx +31 -4
- package/src/theme/DocItem/index.tsx +71 -55
- package/src/theme/DocPage/index.tsx +89 -90
- package/src/theme/DocPage/styles.module.css +0 -4
- package/src/theme/DocSidebar/Desktop/CollapseButton/index.tsx +38 -0
- package/src/theme/DocSidebar/Desktop/CollapseButton/styles.module.css +44 -0
- package/src/theme/DocSidebar/Desktop/Content/index.tsx +55 -0
- package/src/theme/DocSidebar/Desktop/Content/styles.module.css +17 -0
- package/src/theme/DocSidebar/Desktop/index.tsx +38 -0
- package/src/theme/DocSidebar/Desktop/styles.module.css +50 -0
- package/src/theme/DocSidebar/Mobile/index.tsx +54 -0
- package/src/theme/DocSidebar/index.tsx +6 -121
- package/src/theme/DocSidebarItem/index.tsx +15 -16
- package/src/theme/DocSidebarItem/styles.module.css +4 -0
- package/src/theme/DocTagDocListPage/index.tsx +38 -30
- package/src/theme/DocTagsListPage/index.tsx +21 -16
- package/src/theme/DocVersionBanner/index.tsx +3 -4
- package/src/theme/Footer/Copyright/index.tsx +20 -0
- package/src/theme/Footer/Layout/index.tsx +34 -0
- package/src/theme/Footer/LinkItem/index.tsx +36 -0
- package/src/theme/Footer/Links/MultiColumn/index.tsx +51 -0
- package/src/theme/Footer/Links/Simple/index.tsx +42 -0
- package/src/theme/Footer/Links/index.tsx +21 -0
- package/src/theme/Footer/Logo/index.tsx +41 -0
- package/src/theme/Footer/{styles.module.css → Logo/styles.module.css} +0 -0
- package/src/theme/Footer/index.tsx +12 -186
- package/src/theme/Heading/index.tsx +6 -4
- package/src/theme/IconExternalLink/styles.module.css +0 -2
- package/src/theme/Layout/index.tsx +15 -10
- package/src/theme/LayoutProviders/index.tsx +5 -4
- package/src/theme/MDXComponents/A.tsx +14 -0
- package/src/theme/MDXComponents/Code.tsx +37 -0
- package/src/theme/MDXComponents/Details.tsx +26 -0
- package/src/theme/MDXComponents/Head.tsx +29 -0
- package/src/theme/MDXComponents/Heading.tsx +14 -0
- package/src/theme/MDXComponents/Img.module.css +10 -0
- package/src/theme/MDXComponents/Img.tsx +26 -0
- package/src/theme/MDXComponents/Pre.tsx +22 -0
- package/{lib-next/theme/MDXComponents/styles.css → src/theme/MDXComponents/Ul.module.css} +1 -5
- package/src/theme/MDXComponents/Ul.tsx +28 -0
- package/src/theme/MDXComponents/index.tsx +23 -80
- package/src/theme/MDXContent/index.tsx +15 -0
- package/src/theme/MDXPage/index.tsx +33 -28
- package/src/theme/Navbar/ColorModeToggle/index.tsx +30 -0
- package/src/theme/Navbar/Content/index.tsx +81 -0
- package/src/theme/Navbar/Content/styles.module.css +15 -0
- package/src/theme/Navbar/Layout/index.tsx +57 -0
- package/{lib-next/theme/Navbar → src/theme/Navbar/Layout}/styles.module.css +0 -13
- package/src/theme/Navbar/Logo/index.tsx +19 -0
- package/src/theme/Navbar/MobileSidebar/Header/index.tsx +34 -0
- package/src/theme/Navbar/MobileSidebar/Layout/index.tsx +31 -0
- package/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx +38 -0
- package/src/theme/Navbar/MobileSidebar/SecondaryMenu/index.tsx +38 -0
- package/src/theme/Navbar/MobileSidebar/Toggle/index.tsx +25 -0
- package/src/theme/Navbar/MobileSidebar/index.tsx +33 -0
- package/src/theme/Navbar/index.tsx +6 -286
- package/src/theme/NavbarItem/DefaultNavbarItem.tsx +2 -2
- package/src/theme/NavbarItem/DropdownNavbarItem.tsx +11 -2
- package/src/theme/NavbarItem/LocaleDropdownNavbarItem/index.tsx +1 -1
- package/src/theme/NavbarItem/NavbarNavLink.tsx +3 -7
- package/src/theme/NavbarItem/index.tsx +3 -4
- package/src/theme/NotFound.tsx +38 -33
- package/src/theme/{LayoutHead → SiteMetadata}/index.tsx +11 -25
- package/src/theme/TOCCollapsible/index.tsx +1 -3
- package/src/theme/Tabs/index.tsx +5 -6
- package/src/theme/Tag/index.tsx +4 -4
- package/src/theme/ThemedImage/index.tsx +4 -3
- package/src/theme-classic.d.ts +286 -60
- package/src/translations.ts +12 -6
- package/src/validateThemeConfig.ts +6 -6
- package/lib-next/theme/DocSidebar/styles.module.css +0 -107
- package/lib-next/theme/Seo/index.js +0 -40
- package/src/theme/DocSidebar/styles.module.css +0 -107
- package/src/theme/Seo/index.tsx +0 -49
|
@@ -6,40 +6,63 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import React from 'react';
|
|
9
|
-
import Seo from '@theme/Seo';
|
|
10
9
|
import BlogLayout from '@theme/BlogLayout';
|
|
11
10
|
import BlogPostItem from '@theme/BlogPostItem';
|
|
12
11
|
import BlogPostPaginator from '@theme/BlogPostPaginator';
|
|
13
12
|
import type {Props} from '@theme/BlogPostPage';
|
|
14
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
PageMetadata,
|
|
15
|
+
HtmlClassNameProvider,
|
|
16
|
+
ThemeClassNames,
|
|
17
|
+
} from '@docusaurus/theme-common';
|
|
15
18
|
import TOC from '@theme/TOC';
|
|
19
|
+
import clsx from 'clsx';
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
function BlogPostPageMetadata(props: Props): JSX.Element {
|
|
22
|
+
const {content: BlogPostContents} = props;
|
|
23
|
+
const {assets, metadata} = BlogPostContents;
|
|
24
|
+
const {title, description, date, tags, authors, frontMatter} = metadata;
|
|
25
|
+
const {keywords} = frontMatter;
|
|
26
|
+
const image = assets.image ?? frontMatter.image;
|
|
27
|
+
return (
|
|
28
|
+
<PageMetadata
|
|
29
|
+
title={title}
|
|
30
|
+
description={description}
|
|
31
|
+
keywords={keywords}
|
|
32
|
+
image={image}>
|
|
33
|
+
<meta property="og:type" content="article" />
|
|
34
|
+
<meta property="article:published_time" content={date} />
|
|
35
|
+
{/* TODO double check those article meta array syntaxes, see https://ogp.me/#array */}
|
|
36
|
+
{authors.some((author) => author.url) && (
|
|
37
|
+
<meta
|
|
38
|
+
property="article:author"
|
|
39
|
+
content={authors
|
|
40
|
+
.map((author) => author.url)
|
|
41
|
+
.filter(Boolean)
|
|
42
|
+
.join(',')}
|
|
43
|
+
/>
|
|
44
|
+
)}
|
|
45
|
+
{tags.length > 0 && (
|
|
46
|
+
<meta
|
|
47
|
+
property="article:tag"
|
|
48
|
+
content={tags.map((tag) => tag.label).join(',')}
|
|
49
|
+
/>
|
|
50
|
+
)}
|
|
51
|
+
</PageMetadata>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function BlogPostPageContent(props: Props): JSX.Element {
|
|
18
56
|
const {content: BlogPostContents, sidebar} = props;
|
|
19
57
|
const {assets, metadata} = BlogPostContents;
|
|
20
|
-
const {
|
|
21
|
-
title,
|
|
22
|
-
description,
|
|
23
|
-
nextItem,
|
|
24
|
-
prevItem,
|
|
25
|
-
date,
|
|
26
|
-
tags,
|
|
27
|
-
authors,
|
|
28
|
-
frontMatter,
|
|
29
|
-
} = metadata;
|
|
58
|
+
const {nextItem, prevItem, frontMatter} = metadata;
|
|
30
59
|
const {
|
|
31
60
|
hide_table_of_contents: hideTableOfContents,
|
|
32
|
-
keywords,
|
|
33
61
|
toc_min_heading_level: tocMinHeadingLevel,
|
|
34
62
|
toc_max_heading_level: tocMaxHeadingLevel,
|
|
35
63
|
} = frontMatter;
|
|
36
|
-
|
|
37
|
-
const image = assets.image ?? frontMatter.image;
|
|
38
|
-
|
|
39
64
|
return (
|
|
40
65
|
<BlogLayout
|
|
41
|
-
wrapperClassName={ThemeClassNames.wrapper.blogPages}
|
|
42
|
-
pageClassName={ThemeClassNames.page.blogPostPage}
|
|
43
66
|
sidebar={sidebar}
|
|
44
67
|
toc={
|
|
45
68
|
!hideTableOfContents &&
|
|
@@ -52,35 +75,6 @@ export default function BlogPostPage(props: Props): JSX.Element {
|
|
|
52
75
|
/>
|
|
53
76
|
) : undefined
|
|
54
77
|
}>
|
|
55
|
-
<Seo
|
|
56
|
-
// TODO refactor needed: it's a bit annoying but Seo MUST be inside
|
|
57
|
-
// BlogLayout, otherwise default image (set by BlogLayout) would shadow
|
|
58
|
-
// the custom blog post image
|
|
59
|
-
title={title}
|
|
60
|
-
description={description}
|
|
61
|
-
keywords={keywords}
|
|
62
|
-
image={image}>
|
|
63
|
-
<meta property="og:type" content="article" />
|
|
64
|
-
<meta property="article:published_time" content={date} />
|
|
65
|
-
|
|
66
|
-
{/* TODO double check those article meta array syntaxes, see https://ogp.me/#array */}
|
|
67
|
-
{authors.some((author) => author.url) && (
|
|
68
|
-
<meta
|
|
69
|
-
property="article:author"
|
|
70
|
-
content={authors
|
|
71
|
-
.map((author) => author.url)
|
|
72
|
-
.filter(Boolean)
|
|
73
|
-
.join(',')}
|
|
74
|
-
/>
|
|
75
|
-
)}
|
|
76
|
-
{tags.length > 0 && (
|
|
77
|
-
<meta
|
|
78
|
-
property="article:tag"
|
|
79
|
-
content={tags.map((tag) => tag.label).join(',')}
|
|
80
|
-
/>
|
|
81
|
-
)}
|
|
82
|
-
</Seo>
|
|
83
|
-
|
|
84
78
|
<BlogPostItem
|
|
85
79
|
frontMatter={frontMatter}
|
|
86
80
|
assets={assets}
|
|
@@ -95,3 +89,16 @@ export default function BlogPostPage(props: Props): JSX.Element {
|
|
|
95
89
|
</BlogLayout>
|
|
96
90
|
);
|
|
97
91
|
}
|
|
92
|
+
|
|
93
|
+
export default function BlogPostPage(props: Props): JSX.Element {
|
|
94
|
+
return (
|
|
95
|
+
<HtmlClassNameProvider
|
|
96
|
+
className={clsx(
|
|
97
|
+
ThemeClassNames.wrapper.blogPages,
|
|
98
|
+
ThemeClassNames.page.blogPostPage,
|
|
99
|
+
)}>
|
|
100
|
+
<BlogPostPageMetadata {...props} />
|
|
101
|
+
<BlogPostPageContent {...props} />
|
|
102
|
+
</HtmlClassNameProvider>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
@@ -11,25 +11,29 @@ import BlogLayout from '@theme/BlogLayout';
|
|
|
11
11
|
import TagsListByLetter from '@theme/TagsListByLetter';
|
|
12
12
|
import type {Props} from '@theme/BlogTagsListPage';
|
|
13
13
|
import {
|
|
14
|
+
PageMetadata,
|
|
15
|
+
HtmlClassNameProvider,
|
|
14
16
|
ThemeClassNames,
|
|
15
17
|
translateTagsPageTitle,
|
|
16
18
|
} from '@docusaurus/theme-common';
|
|
19
|
+
import SearchMetadata from '../SearchMetadata';
|
|
20
|
+
import clsx from 'clsx';
|
|
17
21
|
|
|
18
22
|
export default function BlogTagsListPage(props: Props): JSX.Element {
|
|
19
23
|
const {tags, sidebar} = props;
|
|
20
24
|
const title = translateTagsPageTitle();
|
|
21
25
|
return (
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
</
|
|
26
|
+
<HtmlClassNameProvider
|
|
27
|
+
className={clsx(
|
|
28
|
+
ThemeClassNames.wrapper.blogPages,
|
|
29
|
+
ThemeClassNames.page.blogTagsListPage,
|
|
30
|
+
)}>
|
|
31
|
+
<PageMetadata title={title} />
|
|
32
|
+
<SearchMetadata tag="blog_tags_list" />
|
|
33
|
+
<BlogLayout sidebar={sidebar}>
|
|
34
|
+
<h1>{title}</h1>
|
|
35
|
+
<TagsListByLetter tags={Object.values(tags)} />
|
|
36
|
+
</BlogLayout>
|
|
37
|
+
</HtmlClassNameProvider>
|
|
34
38
|
);
|
|
35
39
|
}
|
|
@@ -12,8 +12,15 @@ import BlogLayout from '@theme/BlogLayout';
|
|
|
12
12
|
import BlogPostItem from '@theme/BlogPostItem';
|
|
13
13
|
import type {Props} from '@theme/BlogTagsPostsPage';
|
|
14
14
|
import Translate, {translate} from '@docusaurus/Translate';
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
PageMetadata,
|
|
17
|
+
HtmlClassNameProvider,
|
|
18
|
+
ThemeClassNames,
|
|
19
|
+
usePluralForm,
|
|
20
|
+
} from '@docusaurus/theme-common';
|
|
16
21
|
import BlogListPaginator from '@theme/BlogListPaginator';
|
|
22
|
+
import SearchMetadata from '@theme/SearchMetadata';
|
|
23
|
+
import clsx from 'clsx';
|
|
17
24
|
|
|
18
25
|
// Very simple pluralization: probably good enough for now
|
|
19
26
|
function useBlogPostsPlural() {
|
|
@@ -47,38 +54,38 @@ export default function BlogTagsPostsPage(props: Props): JSX.Element {
|
|
|
47
54
|
);
|
|
48
55
|
|
|
49
56
|
return (
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
<h1>{title}</h1>
|
|
57
|
+
<HtmlClassNameProvider
|
|
58
|
+
className={clsx(
|
|
59
|
+
ThemeClassNames.wrapper.blogPages,
|
|
60
|
+
ThemeClassNames.page.blogTagPostListPage,
|
|
61
|
+
)}>
|
|
62
|
+
<PageMetadata title={title} />
|
|
63
|
+
<SearchMetadata tag="blog_tags_posts" />
|
|
64
|
+
<BlogLayout sidebar={sidebar}>
|
|
65
|
+
<header className="margin-bottom--xl">
|
|
66
|
+
<h1>{title}</h1>
|
|
61
67
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
<Link href={allTagsPath}>
|
|
69
|
+
<Translate
|
|
70
|
+
id="theme.tags.tagsPageLink"
|
|
71
|
+
description="The label of the link targeting the tag list page">
|
|
72
|
+
View All Tags
|
|
73
|
+
</Translate>
|
|
74
|
+
</Link>
|
|
75
|
+
</header>
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
{items.map(({content: BlogPostContent}) => (
|
|
78
|
+
<BlogPostItem
|
|
79
|
+
key={BlogPostContent.metadata.permalink}
|
|
80
|
+
frontMatter={BlogPostContent.frontMatter}
|
|
81
|
+
assets={BlogPostContent.assets}
|
|
82
|
+
metadata={BlogPostContent.metadata}
|
|
83
|
+
truncated>
|
|
84
|
+
<BlogPostContent />
|
|
85
|
+
</BlogPostItem>
|
|
86
|
+
))}
|
|
87
|
+
<BlogListPaginator metadata={listMetadata} />
|
|
88
|
+
</BlogLayout>
|
|
89
|
+
</HtmlClassNameProvider>
|
|
83
90
|
);
|
|
84
91
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
+
import React, {useCallback, useState, useRef, useEffect} from 'react';
|
|
9
|
+
import clsx from 'clsx';
|
|
10
|
+
import copy from 'copy-text-to-clipboard';
|
|
11
|
+
import {translate} from '@docusaurus/Translate';
|
|
12
|
+
import type {Props} from '@theme/CodeBlock/CopyButton';
|
|
13
|
+
|
|
14
|
+
import styles from './styles.module.css';
|
|
15
|
+
|
|
16
|
+
export default function CopyButton({code}: Props): JSX.Element {
|
|
17
|
+
const [isCopied, setIsCopied] = useState(false);
|
|
18
|
+
const copyTimeout = useRef<number | undefined>(undefined);
|
|
19
|
+
const handleCopyCode = useCallback(() => {
|
|
20
|
+
copy(code);
|
|
21
|
+
setIsCopied(true);
|
|
22
|
+
copyTimeout.current = window.setTimeout(() => {
|
|
23
|
+
setIsCopied(false);
|
|
24
|
+
}, 1000);
|
|
25
|
+
}, [code]);
|
|
26
|
+
|
|
27
|
+
useEffect(() => () => window.clearTimeout(copyTimeout.current), []);
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<button
|
|
31
|
+
type="button"
|
|
32
|
+
aria-label={
|
|
33
|
+
isCopied
|
|
34
|
+
? translate({
|
|
35
|
+
id: 'theme.CodeBlock.copied',
|
|
36
|
+
message: 'Copied',
|
|
37
|
+
description: 'The copied button label on code blocks',
|
|
38
|
+
})
|
|
39
|
+
: translate({
|
|
40
|
+
id: 'theme.CodeBlock.copyButtonAriaLabel',
|
|
41
|
+
message: 'Copy code to clipboard',
|
|
42
|
+
description: 'The ARIA label for copy code blocks button',
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
title={translate({
|
|
46
|
+
id: 'theme.CodeBlock.copy',
|
|
47
|
+
message: 'Copy',
|
|
48
|
+
description: 'The copy button label on code blocks',
|
|
49
|
+
})}
|
|
50
|
+
className={clsx(
|
|
51
|
+
styles.copyButton,
|
|
52
|
+
'clean-btn',
|
|
53
|
+
isCopied && styles.copyButtonCopied,
|
|
54
|
+
)}
|
|
55
|
+
onClick={handleCopyCode}>
|
|
56
|
+
<span className={styles.copyButtonIcons} aria-hidden="true">
|
|
57
|
+
<svg className={styles.copyButtonIcon} viewBox="0 0 24 24">
|
|
58
|
+
<path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z" />
|
|
59
|
+
</svg>
|
|
60
|
+
<svg className={styles.copyButtonSuccessIcon} viewBox="0 0 24 24">
|
|
61
|
+
<path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" />
|
|
62
|
+
</svg>
|
|
63
|
+
</span>
|
|
64
|
+
</button>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
+
.copyButton {
|
|
9
|
+
display: flex;
|
|
10
|
+
background: inherit;
|
|
11
|
+
border: 1px solid var(--ifm-color-emphasis-300);
|
|
12
|
+
border-radius: var(--ifm-global-radius);
|
|
13
|
+
padding: 0.4rem;
|
|
14
|
+
position: absolute;
|
|
15
|
+
right: calc(var(--ifm-pre-padding) / 2);
|
|
16
|
+
top: calc(var(--ifm-pre-padding) / 2);
|
|
17
|
+
transition: opacity 200ms ease-in-out;
|
|
18
|
+
opacity: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.copyButton:focus-visible,
|
|
22
|
+
.copyButton:hover,
|
|
23
|
+
:global(.theme-code-block:hover) .copyButtonCopied {
|
|
24
|
+
opacity: 1 !important;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
:global(.theme-code-block:hover) .copyButton:not(.copyButtonCopied) {
|
|
28
|
+
opacity: 0.4;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.copyButtonIcons {
|
|
32
|
+
position: relative;
|
|
33
|
+
width: 1.125rem;
|
|
34
|
+
height: 1.125rem;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.copyButtonIcon,
|
|
38
|
+
.copyButtonSuccessIcon {
|
|
39
|
+
position: absolute;
|
|
40
|
+
top: 0;
|
|
41
|
+
left: 0;
|
|
42
|
+
fill: currentColor;
|
|
43
|
+
opacity: inherit;
|
|
44
|
+
width: inherit;
|
|
45
|
+
height: inherit;
|
|
46
|
+
transition: all 0.15s ease;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.copyButtonSuccessIcon {
|
|
50
|
+
top: 50%;
|
|
51
|
+
left: 50%;
|
|
52
|
+
transform: translate(-50%, -50%) scale(0.33);
|
|
53
|
+
opacity: 0;
|
|
54
|
+
color: #00d600;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.copyButtonCopied .copyButtonIcon {
|
|
58
|
+
transform: scale(0.33);
|
|
59
|
+
opacity: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.copyButtonCopied .copyButtonSuccessIcon {
|
|
63
|
+
transform: translate(-50%, -50%) scale(1);
|
|
64
|
+
opacity: 1;
|
|
65
|
+
transition-delay: 0.075s;
|
|
66
|
+
}
|
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
import React, {isValidElement, useEffect, useState} from 'react';
|
|
9
9
|
import clsx from 'clsx';
|
|
10
10
|
import Highlight, {defaultProps, type Language} from 'prism-react-renderer';
|
|
11
|
-
import copy from 'copy-text-to-clipboard';
|
|
12
|
-
import Translate, {translate} from '@docusaurus/Translate';
|
|
13
11
|
import {
|
|
14
12
|
useThemeConfig,
|
|
15
13
|
parseCodeBlockTitle,
|
|
@@ -18,6 +16,7 @@ import {
|
|
|
18
16
|
ThemeClassNames,
|
|
19
17
|
usePrismTheme,
|
|
20
18
|
} from '@docusaurus/theme-common';
|
|
19
|
+
import CopyButton from '@theme/CodeBlock/CopyButton';
|
|
21
20
|
import type {Props} from '@theme/CodeBlock';
|
|
22
21
|
|
|
23
22
|
import styles from './styles.module.css';
|
|
@@ -31,7 +30,6 @@ export default function CodeBlock({
|
|
|
31
30
|
}: Props): JSX.Element {
|
|
32
31
|
const {prism} = useThemeConfig();
|
|
33
32
|
|
|
34
|
-
const [showCopied, setShowCopied] = useState(false);
|
|
35
33
|
const [mounted, setMounted] = useState(false);
|
|
36
34
|
// The Prism theme on SSR is always the default theme but the site theme
|
|
37
35
|
// can be in a different mode. React hydration doesn't update DOM styles
|
|
@@ -90,13 +88,6 @@ export default function CodeBlock({
|
|
|
90
88
|
languageProp ?? parseLanguage(blockClassName) ?? prism.defaultLanguage;
|
|
91
89
|
const {highlightLines, code} = parseLines(content, metastring, language);
|
|
92
90
|
|
|
93
|
-
const handleCopyCode = () => {
|
|
94
|
-
copy(code);
|
|
95
|
-
setShowCopied(true);
|
|
96
|
-
|
|
97
|
-
setTimeout(() => setShowCopied(false), 2000);
|
|
98
|
-
};
|
|
99
|
-
|
|
100
91
|
return (
|
|
101
92
|
<Highlight
|
|
102
93
|
{...defaultProps}
|
|
@@ -120,16 +111,15 @@ export default function CodeBlock({
|
|
|
120
111
|
{codeBlockTitle}
|
|
121
112
|
</div>
|
|
122
113
|
)}
|
|
123
|
-
<div className={
|
|
114
|
+
<div className={styles.codeBlockContent} style={style}>
|
|
124
115
|
<pre
|
|
125
116
|
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
|
|
126
117
|
tabIndex={0}
|
|
127
|
-
className={clsx(className, styles.codeBlock, 'thin-scrollbar')}
|
|
128
|
-
style={style}>
|
|
118
|
+
className={clsx(className, styles.codeBlock, 'thin-scrollbar')}>
|
|
129
119
|
<code className={styles.codeBlockLines}>
|
|
130
120
|
{tokens.map((line, i) => {
|
|
131
|
-
if (line.length === 1 && line[0]
|
|
132
|
-
line[0]
|
|
121
|
+
if (line.length === 1 && line[0]!.content === '\n') {
|
|
122
|
+
line[0]!.content = '';
|
|
133
123
|
}
|
|
134
124
|
|
|
135
125
|
const lineProps = getLineProps({line, key: i});
|
|
@@ -150,29 +140,7 @@ export default function CodeBlock({
|
|
|
150
140
|
</code>
|
|
151
141
|
</pre>
|
|
152
142
|
|
|
153
|
-
<
|
|
154
|
-
type="button"
|
|
155
|
-
aria-label={translate({
|
|
156
|
-
id: 'theme.CodeBlock.copyButtonAriaLabel',
|
|
157
|
-
message: 'Copy code to clipboard',
|
|
158
|
-
description: 'The ARIA label for copy code blocks button',
|
|
159
|
-
})}
|
|
160
|
-
className={clsx(styles.copyButton, 'clean-btn')}
|
|
161
|
-
onClick={handleCopyCode}>
|
|
162
|
-
{showCopied ? (
|
|
163
|
-
<Translate
|
|
164
|
-
id="theme.CodeBlock.copied"
|
|
165
|
-
description="The copied button label on code blocks">
|
|
166
|
-
Copied
|
|
167
|
-
</Translate>
|
|
168
|
-
) : (
|
|
169
|
-
<Translate
|
|
170
|
-
id="theme.CodeBlock.copy"
|
|
171
|
-
description="The copy button label on code blocks">
|
|
172
|
-
Copy
|
|
173
|
-
</Translate>
|
|
174
|
-
)}
|
|
175
|
-
</button>
|
|
143
|
+
<CopyButton code={code} />
|
|
176
144
|
</div>
|
|
177
145
|
</div>
|
|
178
146
|
)}
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
.codeBlockContainer {
|
|
9
9
|
margin-bottom: var(--ifm-leading);
|
|
10
|
-
border-radius: var(--ifm-global-radius);
|
|
11
10
|
box-shadow: var(--ifm-global-shadow-lw);
|
|
12
11
|
}
|
|
13
12
|
|
|
@@ -15,6 +14,7 @@
|
|
|
15
14
|
position: relative;
|
|
16
15
|
/* rtl:ignore */
|
|
17
16
|
direction: ltr;
|
|
17
|
+
border-radius: var(--ifm-global-radius);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
.codeBlockTitle {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
.codeBlock {
|
|
30
30
|
margin: 0;
|
|
31
31
|
padding: 0;
|
|
32
|
-
|
|
32
|
+
background-color: inherit;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
.codeBlockTitle + .codeBlockContent .codeBlock {
|
|
@@ -39,26 +39,6 @@
|
|
|
39
39
|
|
|
40
40
|
.codeBlockStandalone {
|
|
41
41
|
padding: 0;
|
|
42
|
-
border-radius: var(--ifm-global-radius);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.copyButton {
|
|
46
|
-
background: rgb(0 0 0 / 30%);
|
|
47
|
-
border-radius: var(--ifm-global-radius);
|
|
48
|
-
color: var(--ifm-color-white);
|
|
49
|
-
opacity: 0;
|
|
50
|
-
user-select: none;
|
|
51
|
-
padding: 0.4rem 0.5rem;
|
|
52
|
-
position: absolute;
|
|
53
|
-
right: calc(var(--ifm-pre-padding) / 2);
|
|
54
|
-
top: calc(var(--ifm-pre-padding) / 2);
|
|
55
|
-
transition: opacity 200ms ease-in-out;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.copyButton:focus,
|
|
59
|
-
.codeBlockContent:hover > .copyButton,
|
|
60
|
-
.codeBlockTitle:hover + .codeBlockContent .copyButton {
|
|
61
|
-
opacity: 1;
|
|
62
42
|
}
|
|
63
43
|
|
|
64
44
|
.codeBlockLines {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import React
|
|
8
|
+
import React from 'react';
|
|
9
9
|
import type {Props} from '@theme/ColorModeToggle';
|
|
10
10
|
import useIsBrowser from '@docusaurus/useIsBrowser';
|
|
11
11
|
import {translate} from '@docusaurus/Translate';
|
|
@@ -15,76 +15,51 @@ import IconDarkMode from '@theme/IconDarkMode';
|
|
|
15
15
|
import clsx from 'clsx';
|
|
16
16
|
import styles from './styles.module.css';
|
|
17
17
|
|
|
18
|
-
function ColorModeToggle({
|
|
19
|
-
className,
|
|
20
|
-
checked: defaultChecked,
|
|
21
|
-
onChange,
|
|
22
|
-
}: Props): JSX.Element {
|
|
18
|
+
function ColorModeToggle({className, value, onChange}: Props): JSX.Element {
|
|
23
19
|
const isBrowser = useIsBrowser();
|
|
24
|
-
const [checked, setChecked] = useState(defaultChecked);
|
|
25
|
-
const [focused, setFocused] = useState(false);
|
|
26
|
-
const inputRef = useRef<HTMLInputElement>(null);
|
|
27
20
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
const title = translate(
|
|
22
|
+
{
|
|
23
|
+
message: 'Switch between dark and light mode (currently {mode})',
|
|
24
|
+
id: 'theme.colorToggle.ariaLabel',
|
|
25
|
+
description: 'The ARIA label for the navbar color mode toggle',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
mode:
|
|
29
|
+
value === 'dark'
|
|
30
|
+
? translate({
|
|
31
|
+
message: 'dark mode',
|
|
32
|
+
id: 'theme.colorToggle.ariaLabel.mode.dark',
|
|
33
|
+
description: 'The name for the dark color mode',
|
|
34
|
+
})
|
|
35
|
+
: translate({
|
|
36
|
+
message: 'light mode',
|
|
37
|
+
id: 'theme.colorToggle.ariaLabel.mode.light',
|
|
38
|
+
description: 'The name for the light color mode',
|
|
39
|
+
}),
|
|
40
|
+
},
|
|
41
|
+
);
|
|
31
42
|
|
|
32
43
|
return (
|
|
33
|
-
<div
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
<div className={clsx(styles.toggle, className)}>
|
|
45
|
+
<button
|
|
46
|
+
className={clsx(
|
|
47
|
+
'clean-btn',
|
|
48
|
+
styles.toggleButton,
|
|
49
|
+
!isBrowser && styles.toggleButtonDisabled,
|
|
50
|
+
)}
|
|
51
|
+
type="button"
|
|
52
|
+
onClick={() => onChange(value === 'dark' ? 'light' : 'dark')}
|
|
53
|
+
disabled={!isBrowser}
|
|
54
|
+
title={title}
|
|
55
|
+
aria-label={title}>
|
|
45
56
|
<IconLightMode
|
|
46
57
|
className={clsx(styles.toggleIcon, styles.lightToggleIcon)}
|
|
47
58
|
/>
|
|
48
59
|
<IconDarkMode
|
|
49
60
|
className={clsx(styles.toggleIcon, styles.darkToggleIcon)}
|
|
50
61
|
/>
|
|
51
|
-
</
|
|
52
|
-
|
|
53
|
-
<input
|
|
54
|
-
ref={inputRef}
|
|
55
|
-
checked={checked}
|
|
56
|
-
type="checkbox"
|
|
57
|
-
className={styles.toggleScreenReader}
|
|
58
|
-
aria-label={translate(
|
|
59
|
-
{
|
|
60
|
-
message: 'Switch between dark and light mode (currently {mode})',
|
|
61
|
-
id: 'theme.colorToggle.ariaLabel',
|
|
62
|
-
description: 'The ARIA label for the navbar color mode toggle',
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
mode: checked
|
|
66
|
-
? translate({
|
|
67
|
-
message: 'dark mode',
|
|
68
|
-
id: 'theme.colorToggle.ariaLabel.mode.dark',
|
|
69
|
-
description: 'The name for the dark color mode',
|
|
70
|
-
})
|
|
71
|
-
: translate({
|
|
72
|
-
message: 'light mode',
|
|
73
|
-
id: 'theme.colorToggle.ariaLabel.mode.light',
|
|
74
|
-
description: 'The name for the light color mode',
|
|
75
|
-
}),
|
|
76
|
-
},
|
|
77
|
-
)}
|
|
78
|
-
onChange={onChange}
|
|
79
|
-
onClick={() => setChecked(!checked)}
|
|
80
|
-
onFocus={() => setFocused(true)}
|
|
81
|
-
onBlur={() => setFocused(false)}
|
|
82
|
-
onKeyDown={(e) => {
|
|
83
|
-
if (e.key === 'Enter') {
|
|
84
|
-
inputRef.current?.click();
|
|
85
|
-
}
|
|
86
|
-
}}
|
|
87
|
-
/>
|
|
62
|
+
</button>
|
|
88
63
|
</div>
|
|
89
64
|
);
|
|
90
65
|
}
|