@docusaurus/theme-classic 3.3.1 → 3.4.0
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.d.ts +0 -1
- package/lib/index.js +6 -87
- package/lib/inlineScripts.d.ts +16 -0
- package/lib/inlineScripts.js +98 -0
- package/lib/theme/BlogTagsPostsPage/index.js +2 -1
- package/lib/theme/DocCard/index.js +1 -1
- package/lib/theme/DocTagDocListPage/index.js +3 -2
- package/lib/theme/Tag/index.d.ts +1 -1
- package/lib/theme/Tag/index.js +2 -1
- package/lib/theme/TagsListInline/index.js +3 -3
- package/package.json +14 -14
- package/src/index.ts +8 -93
- package/src/inlineScripts.ts +114 -0
- package/src/theme/BlogTagsPostsPage/index.tsx +2 -1
- package/src/theme/DocCard/index.tsx +1 -1
- package/src/theme/DocTagDocListPage/index.tsx +3 -1
- package/src/theme/Tag/index.tsx +7 -1
- package/src/theme/TagsListInline/index.tsx +3 -3
package/lib/index.d.ts
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
/// <reference path="../src/theme-classic.d.ts" />
|
|
8
8
|
import type { LoadContext, Plugin } from '@docusaurus/types';
|
|
9
9
|
import type { PluginOptions } from '@docusaurus/theme-classic';
|
|
10
|
-
export declare const AnnouncementBarDismissStorageKey = "docusaurus.announcement.dismiss";
|
|
11
10
|
export default function themeClassic(context: LoadContext, options: PluginOptions): Plugin<undefined>;
|
|
12
11
|
export { default as getSwizzleConfig } from './getSwizzleConfig';
|
|
13
12
|
export { validateThemeConfig, validateOptions } from './options';
|
package/lib/index.js
CHANGED
|
@@ -6,102 +6,21 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.validateOptions = exports.validateThemeConfig = exports.getSwizzleConfig =
|
|
9
|
+
exports.validateOptions = exports.validateThemeConfig = exports.getSwizzleConfig = void 0;
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
11
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
12
12
|
const module_1 = require("module");
|
|
13
13
|
const rtlcss_1 = tslib_1.__importDefault(require("rtlcss"));
|
|
14
14
|
const theme_translations_1 = require("@docusaurus/theme-translations");
|
|
15
15
|
const translations_1 = require("./translations");
|
|
16
|
+
const inlineScripts_1 = require("./inlineScripts");
|
|
16
17
|
const requireFromDocusaurusCore = (0, module_1.createRequire)(require.resolve('@docusaurus/core/package.json'));
|
|
17
18
|
const ContextReplacementPlugin = requireFromDocusaurusCore('webpack/lib/ContextReplacementPlugin');
|
|
18
|
-
// Need to be inlined to prevent dark mode FOUC
|
|
19
|
-
// Make sure the key is the same as the one in `/theme/hooks/useTheme.js`
|
|
20
|
-
const ThemeStorageKey = 'theme';
|
|
21
|
-
// Support for ?docusaurus-theme=dark
|
|
22
|
-
const ThemeQueryStringKey = 'docusaurus-theme';
|
|
23
|
-
// Support for ?docusaurus-data-mode=embed&docusaurus-data-myAttr=42
|
|
24
|
-
const DataQueryStringPrefixKey = 'docusaurus-data-';
|
|
25
|
-
const noFlashColorMode = ({ defaultMode, respectPrefersColorScheme, }) =>
|
|
26
|
-
/* language=js */
|
|
27
|
-
`(function() {
|
|
28
|
-
var defaultMode = '${defaultMode}';
|
|
29
|
-
var respectPrefersColorScheme = ${respectPrefersColorScheme};
|
|
30
|
-
|
|
31
|
-
function setDataThemeAttribute(theme) {
|
|
32
|
-
document.documentElement.setAttribute('data-theme', theme);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function getQueryStringTheme() {
|
|
36
|
-
try {
|
|
37
|
-
return new URLSearchParams(window.location.search).get('${ThemeQueryStringKey}')
|
|
38
|
-
} catch(e) {}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function getStoredTheme() {
|
|
42
|
-
try {
|
|
43
|
-
return localStorage.getItem('${ThemeStorageKey}');
|
|
44
|
-
} catch (err) {}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
var initialTheme = getQueryStringTheme() || getStoredTheme();
|
|
48
|
-
if (initialTheme !== null) {
|
|
49
|
-
setDataThemeAttribute(initialTheme);
|
|
50
|
-
} else {
|
|
51
|
-
if (
|
|
52
|
-
respectPrefersColorScheme &&
|
|
53
|
-
window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
54
|
-
) {
|
|
55
|
-
setDataThemeAttribute('dark');
|
|
56
|
-
} else if (
|
|
57
|
-
respectPrefersColorScheme &&
|
|
58
|
-
window.matchMedia('(prefers-color-scheme: light)').matches
|
|
59
|
-
) {
|
|
60
|
-
setDataThemeAttribute('light');
|
|
61
|
-
} else {
|
|
62
|
-
setDataThemeAttribute(defaultMode === 'dark' ? 'dark' : 'light');
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
})();`;
|
|
66
|
-
/* language=js */
|
|
67
|
-
const DataAttributeQueryStringInlineJavaScript = `
|
|
68
|
-
(function() {
|
|
69
|
-
try {
|
|
70
|
-
const entries = new URLSearchParams(window.location.search).entries();
|
|
71
|
-
for (var [searchKey, value] of entries) {
|
|
72
|
-
if (searchKey.startsWith('${DataQueryStringPrefixKey}')) {
|
|
73
|
-
var key = searchKey.replace('${DataQueryStringPrefixKey}',"data-")
|
|
74
|
-
document.documentElement.setAttribute(key, value);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
} catch(e) {}
|
|
78
|
-
})();
|
|
79
|
-
`;
|
|
80
|
-
// Duplicated constant. Unfortunately we can't import it from theme-common, as
|
|
81
|
-
// we need to support older nodejs versions without ESM support
|
|
82
|
-
// TODO: import from theme-common once we only support Node.js with ESM support
|
|
83
|
-
// + move all those announcementBar stuff there too
|
|
84
|
-
exports.AnnouncementBarDismissStorageKey = 'docusaurus.announcement.dismiss';
|
|
85
|
-
const AnnouncementBarDismissDataAttribute = 'data-announcement-bar-initially-dismissed';
|
|
86
|
-
// We always render the announcement bar html on the server, to prevent layout
|
|
87
|
-
// shifts on React hydration. The theme can use CSS + the data attribute to hide
|
|
88
|
-
// the announcement bar asap (before React hydration)
|
|
89
|
-
/* language=js */
|
|
90
|
-
const AnnouncementBarInlineJavaScript = `
|
|
91
|
-
(function() {
|
|
92
|
-
function isDismissed() {
|
|
93
|
-
try {
|
|
94
|
-
return localStorage.getItem('${exports.AnnouncementBarDismissStorageKey}') === 'true';
|
|
95
|
-
} catch (err) {}
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
document.documentElement.setAttribute('${AnnouncementBarDismissDataAttribute}', isDismissed());
|
|
99
|
-
})();`;
|
|
100
19
|
function getInfimaCSSFile(direction) {
|
|
101
20
|
return `infima/dist/css/default/default${direction === 'rtl' ? '-rtl' : ''}.css`;
|
|
102
21
|
}
|
|
103
22
|
function themeClassic(context, options) {
|
|
104
|
-
const { i18n: { currentLocale, localeConfigs }, } = context;
|
|
23
|
+
const { i18n: { currentLocale, localeConfigs }, siteStorage, } = context;
|
|
105
24
|
const themeConfig = context.siteConfig.themeConfig;
|
|
106
25
|
const { announcementBar, colorMode, prism: { additionalLanguages }, } = themeConfig;
|
|
107
26
|
const { customCss } = options;
|
|
@@ -171,9 +90,9 @@ function themeClassic(context, options) {
|
|
|
171
90
|
{
|
|
172
91
|
tagName: 'script',
|
|
173
92
|
innerHTML: `
|
|
174
|
-
${
|
|
175
|
-
${DataAttributeQueryStringInlineJavaScript}
|
|
176
|
-
${announcementBar ?
|
|
93
|
+
${(0, inlineScripts_1.getThemeInlineScript)({ colorMode, siteStorage })}
|
|
94
|
+
${inlineScripts_1.DataAttributeQueryStringInlineJavaScript}
|
|
95
|
+
${announcementBar ? (0, inlineScripts_1.getAnnouncementBarInlineScript)({ siteStorage }) : ''}
|
|
177
96
|
`,
|
|
178
97
|
},
|
|
179
98
|
],
|
|
@@ -0,0 +1,16 @@
|
|
|
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 type { SiteStorage } from '@docusaurus/types';
|
|
8
|
+
import type { ThemeConfig } from '@docusaurus/theme-common';
|
|
9
|
+
export declare function getThemeInlineScript({ colorMode: { defaultMode, respectPrefersColorScheme }, siteStorage, }: {
|
|
10
|
+
colorMode: ThemeConfig['colorMode'];
|
|
11
|
+
siteStorage: SiteStorage;
|
|
12
|
+
}): string;
|
|
13
|
+
export declare const DataAttributeQueryStringInlineJavaScript = "\n(function() {\n try {\n const entries = new URLSearchParams(window.location.search).entries();\n for (var [searchKey, value] of entries) {\n if (searchKey.startsWith('docusaurus-data-')) {\n var key = searchKey.replace('docusaurus-data-',\"data-\")\n document.documentElement.setAttribute(key, value);\n }\n }\n } catch(e) {}\n})();\n";
|
|
14
|
+
export declare function getAnnouncementBarInlineScript({ siteStorage, }: {
|
|
15
|
+
siteStorage: SiteStorage;
|
|
16
|
+
}): string;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.getAnnouncementBarInlineScript = exports.DataAttributeQueryStringInlineJavaScript = exports.getThemeInlineScript = void 0;
|
|
10
|
+
// Support for ?docusaurus-theme=dark
|
|
11
|
+
const ThemeQueryStringKey = 'docusaurus-theme';
|
|
12
|
+
// Support for ?docusaurus-data-mode=embed&docusaurus-data-myAttr=42
|
|
13
|
+
const DataQueryStringPrefixKey = 'docusaurus-data-';
|
|
14
|
+
function getThemeInlineScript({ colorMode: { defaultMode, respectPrefersColorScheme }, siteStorage, }) {
|
|
15
|
+
// Need to be inlined to prevent dark mode FOUC
|
|
16
|
+
// Make sure the key is the same as the one in the color mode React context
|
|
17
|
+
// Currently defined in: `docusaurus-theme-common/src/contexts/colorMode.tsx`
|
|
18
|
+
const themeStorageKey = `theme${siteStorage.namespace}`;
|
|
19
|
+
/* language=js */
|
|
20
|
+
return `(function() {
|
|
21
|
+
var defaultMode = '${defaultMode}';
|
|
22
|
+
var respectPrefersColorScheme = ${respectPrefersColorScheme};
|
|
23
|
+
|
|
24
|
+
function setDataThemeAttribute(theme) {
|
|
25
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getQueryStringTheme() {
|
|
29
|
+
try {
|
|
30
|
+
return new URLSearchParams(window.location.search).get('${ThemeQueryStringKey}')
|
|
31
|
+
} catch (e) {
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function getStoredTheme() {
|
|
36
|
+
try {
|
|
37
|
+
return window['${siteStorage.type}'].getItem('${themeStorageKey}');
|
|
38
|
+
} catch (err) {
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
var initialTheme = getQueryStringTheme() || getStoredTheme();
|
|
43
|
+
if (initialTheme !== null) {
|
|
44
|
+
setDataThemeAttribute(initialTheme);
|
|
45
|
+
} else {
|
|
46
|
+
if (
|
|
47
|
+
respectPrefersColorScheme &&
|
|
48
|
+
window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
49
|
+
) {
|
|
50
|
+
setDataThemeAttribute('dark');
|
|
51
|
+
} else if (
|
|
52
|
+
respectPrefersColorScheme &&
|
|
53
|
+
window.matchMedia('(prefers-color-scheme: light)').matches
|
|
54
|
+
) {
|
|
55
|
+
setDataThemeAttribute('light');
|
|
56
|
+
} else {
|
|
57
|
+
setDataThemeAttribute(defaultMode === 'dark' ? 'dark' : 'light');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
})();`;
|
|
61
|
+
}
|
|
62
|
+
exports.getThemeInlineScript = getThemeInlineScript;
|
|
63
|
+
/* language=js */
|
|
64
|
+
exports.DataAttributeQueryStringInlineJavaScript = `
|
|
65
|
+
(function() {
|
|
66
|
+
try {
|
|
67
|
+
const entries = new URLSearchParams(window.location.search).entries();
|
|
68
|
+
for (var [searchKey, value] of entries) {
|
|
69
|
+
if (searchKey.startsWith('${DataQueryStringPrefixKey}')) {
|
|
70
|
+
var key = searchKey.replace('${DataQueryStringPrefixKey}',"data-")
|
|
71
|
+
document.documentElement.setAttribute(key, value);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
} catch(e) {}
|
|
75
|
+
})();
|
|
76
|
+
`;
|
|
77
|
+
// We always render the announcement bar html on the server, to prevent layout
|
|
78
|
+
// shifts on React hydration. The theme can use CSS + the data attribute to hide
|
|
79
|
+
// the announcement bar asap (before React hydration)
|
|
80
|
+
function getAnnouncementBarInlineScript({ siteStorage, }) {
|
|
81
|
+
// Duplicated constant. Unfortunately we can't import it from theme-common, as
|
|
82
|
+
// we need to support older nodejs versions without ESM support
|
|
83
|
+
// TODO: import from theme-common once we support Node.js with ESM support
|
|
84
|
+
// + move all those announcementBar stuff there too
|
|
85
|
+
const AnnouncementBarDismissStorageKey = `docusaurus.announcement.dismiss${siteStorage.namespace}`;
|
|
86
|
+
const AnnouncementBarDismissDataAttribute = 'data-announcement-bar-initially-dismissed';
|
|
87
|
+
/* language=js */
|
|
88
|
+
return `(function() {
|
|
89
|
+
function isDismissed() {
|
|
90
|
+
try {
|
|
91
|
+
return localStorage.getItem('${AnnouncementBarDismissStorageKey}') === 'true';
|
|
92
|
+
} catch (err) {}
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
document.documentElement.setAttribute('${AnnouncementBarDismissDataAttribute}', isDismissed());
|
|
96
|
+
})();`;
|
|
97
|
+
}
|
|
98
|
+
exports.getAnnouncementBarInlineScript = getAnnouncementBarInlineScript;
|
|
@@ -52,7 +52,7 @@ function BlogTagsPostsPageMetadata({tag}) {
|
|
|
52
52
|
const title = useBlogTagsPostsPageTitle(tag);
|
|
53
53
|
return (
|
|
54
54
|
<>
|
|
55
|
-
<PageMetadata title={title} />
|
|
55
|
+
<PageMetadata title={title} description={tag.description} />
|
|
56
56
|
<SearchMetadata tag="blog_tags_posts" />
|
|
57
57
|
</>
|
|
58
58
|
);
|
|
@@ -64,6 +64,7 @@ function BlogTagsPostsPageContent({tag, items, sidebar, listMetadata}) {
|
|
|
64
64
|
{tag.unlisted && <Unlisted />}
|
|
65
65
|
<header className="margin-bottom--xl">
|
|
66
66
|
<Heading as="h1">{title}</Heading>
|
|
67
|
+
{tag.description && <p>{tag.description}</p>}
|
|
67
68
|
<Link href={tag.allTagsPath}>
|
|
68
69
|
<Translate
|
|
69
70
|
id="theme.tags.tagsPageLink"
|
|
@@ -23,7 +23,7 @@ function useCategoryItemsPlural() {
|
|
|
23
23
|
count,
|
|
24
24
|
translate(
|
|
25
25
|
{
|
|
26
|
-
message: '{count} items',
|
|
26
|
+
message: '1 item|{count} items',
|
|
27
27
|
id: 'theme.docs.DocCard.categoryDescription.plurals',
|
|
28
28
|
description:
|
|
29
29
|
'The default description for a category card in the generated index about how many items this category includes',
|
|
@@ -55,10 +55,10 @@ function DocItem({doc}) {
|
|
|
55
55
|
</article>
|
|
56
56
|
);
|
|
57
57
|
}
|
|
58
|
-
function DocTagDocListPageMetadata({title}) {
|
|
58
|
+
function DocTagDocListPageMetadata({title, tag}) {
|
|
59
59
|
return (
|
|
60
60
|
<>
|
|
61
|
-
<PageMetadata title={title} />
|
|
61
|
+
<PageMetadata title={title} description={tag.description} />
|
|
62
62
|
<SearchMetadata tag="doc_tag_doc_list" />
|
|
63
63
|
</>
|
|
64
64
|
);
|
|
@@ -73,6 +73,7 @@ function DocTagDocListPageContent({tag, title}) {
|
|
|
73
73
|
{tag.unlisted && <Unlisted />}
|
|
74
74
|
<header className="margin-bottom--xl">
|
|
75
75
|
<Heading as="h1">{title}</Heading>
|
|
76
|
+
{tag.description && <p>{tag.description}</p>}
|
|
76
77
|
<Link href={tag.allTagsPath}>
|
|
77
78
|
<Translate
|
|
78
79
|
id="theme.tags.tagsPageLink"
|
package/lib/theme/Tag/index.d.ts
CHANGED
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
/// <reference path="../../../src/theme-classic.d.ts" />
|
|
8
8
|
/// <reference types="react" />
|
|
9
9
|
import type { Props } from '@theme/Tag';
|
|
10
|
-
export default function Tag({ permalink, label, count }: Props): JSX.Element;
|
|
10
|
+
export default function Tag({ permalink, label, count, description, }: Props): JSX.Element;
|
package/lib/theme/Tag/index.js
CHANGED
|
@@ -8,10 +8,11 @@ import React from 'react';
|
|
|
8
8
|
import clsx from 'clsx';
|
|
9
9
|
import Link from '@docusaurus/Link';
|
|
10
10
|
import styles from './styles.module.css';
|
|
11
|
-
export default function Tag({permalink, label, count}) {
|
|
11
|
+
export default function Tag({permalink, label, count, description}) {
|
|
12
12
|
return (
|
|
13
13
|
<Link
|
|
14
14
|
href={permalink}
|
|
15
|
+
title={description}
|
|
15
16
|
className={clsx(
|
|
16
17
|
styles.tag,
|
|
17
18
|
count ? styles.tagWithCount : styles.tagRegular,
|
|
@@ -20,9 +20,9 @@ export default function TagsListInline({tags}) {
|
|
|
20
20
|
</Translate>
|
|
21
21
|
</b>
|
|
22
22
|
<ul className={clsx(styles.tags, 'padding--none', 'margin-left--sm')}>
|
|
23
|
-
{tags.map((
|
|
24
|
-
<li key={
|
|
25
|
-
<Tag
|
|
23
|
+
{tags.map((tag) => (
|
|
24
|
+
<li key={tag.permalink} className={styles.tag}>
|
|
25
|
+
<Tag {...tag} />
|
|
26
26
|
</li>
|
|
27
27
|
))}
|
|
28
28
|
</ul>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docusaurus/theme-classic",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Classic theme for Docusaurus",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "src/theme-classic.d.ts",
|
|
@@ -20,18 +20,18 @@
|
|
|
20
20
|
"copy:watch": "node ../../admin/scripts/copyUntypedFiles.js --watch"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@docusaurus/core": "3.
|
|
24
|
-
"@docusaurus/mdx-loader": "3.
|
|
25
|
-
"@docusaurus/module-type-aliases": "3.
|
|
26
|
-
"@docusaurus/plugin-content-blog": "3.
|
|
27
|
-
"@docusaurus/plugin-content-docs": "3.
|
|
28
|
-
"@docusaurus/plugin-content-pages": "3.
|
|
29
|
-
"@docusaurus/theme-common": "3.
|
|
30
|
-
"@docusaurus/theme-translations": "3.
|
|
31
|
-
"@docusaurus/types": "3.
|
|
32
|
-
"@docusaurus/utils": "3.
|
|
33
|
-
"@docusaurus/utils-common": "3.
|
|
34
|
-
"@docusaurus/utils-validation": "3.
|
|
23
|
+
"@docusaurus/core": "3.4.0",
|
|
24
|
+
"@docusaurus/mdx-loader": "3.4.0",
|
|
25
|
+
"@docusaurus/module-type-aliases": "3.4.0",
|
|
26
|
+
"@docusaurus/plugin-content-blog": "3.4.0",
|
|
27
|
+
"@docusaurus/plugin-content-docs": "3.4.0",
|
|
28
|
+
"@docusaurus/plugin-content-pages": "3.4.0",
|
|
29
|
+
"@docusaurus/theme-common": "3.4.0",
|
|
30
|
+
"@docusaurus/theme-translations": "3.4.0",
|
|
31
|
+
"@docusaurus/types": "3.4.0",
|
|
32
|
+
"@docusaurus/utils": "3.4.0",
|
|
33
|
+
"@docusaurus/utils-common": "3.4.0",
|
|
34
|
+
"@docusaurus/utils-validation": "3.4.0",
|
|
35
35
|
"@mdx-js/react": "^3.0.0",
|
|
36
36
|
"clsx": "^2.0.0",
|
|
37
37
|
"copy-text-to-clipboard": "^3.2.0",
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
"engines": {
|
|
62
62
|
"node": ">=18.0"
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "49e9a2143274a8dd795659b417b470bc42abbd6e"
|
|
65
65
|
}
|
package/src/index.ts
CHANGED
|
@@ -10,6 +10,11 @@ import {createRequire} from 'module';
|
|
|
10
10
|
import rtlcss from 'rtlcss';
|
|
11
11
|
import {readDefaultCodeTranslationMessages} from '@docusaurus/theme-translations';
|
|
12
12
|
import {getTranslationFiles, translateThemeConfig} from './translations';
|
|
13
|
+
import {
|
|
14
|
+
getThemeInlineScript,
|
|
15
|
+
getAnnouncementBarInlineScript,
|
|
16
|
+
DataAttributeQueryStringInlineJavaScript,
|
|
17
|
+
} from './inlineScripts';
|
|
13
18
|
import type {LoadContext, Plugin} from '@docusaurus/types';
|
|
14
19
|
import type {ThemeConfig} from '@docusaurus/theme-common';
|
|
15
20
|
import type {Plugin as PostCssPlugin} from 'postcss';
|
|
@@ -23,97 +28,6 @@ const ContextReplacementPlugin = requireFromDocusaurusCore(
|
|
|
23
28
|
'webpack/lib/ContextReplacementPlugin',
|
|
24
29
|
) as typeof webpack.ContextReplacementPlugin;
|
|
25
30
|
|
|
26
|
-
// Need to be inlined to prevent dark mode FOUC
|
|
27
|
-
// Make sure the key is the same as the one in `/theme/hooks/useTheme.js`
|
|
28
|
-
const ThemeStorageKey = 'theme';
|
|
29
|
-
// Support for ?docusaurus-theme=dark
|
|
30
|
-
const ThemeQueryStringKey = 'docusaurus-theme';
|
|
31
|
-
// Support for ?docusaurus-data-mode=embed&docusaurus-data-myAttr=42
|
|
32
|
-
const DataQueryStringPrefixKey = 'docusaurus-data-';
|
|
33
|
-
|
|
34
|
-
const noFlashColorMode = ({
|
|
35
|
-
defaultMode,
|
|
36
|
-
respectPrefersColorScheme,
|
|
37
|
-
}: ThemeConfig['colorMode']) =>
|
|
38
|
-
/* language=js */
|
|
39
|
-
`(function() {
|
|
40
|
-
var defaultMode = '${defaultMode}';
|
|
41
|
-
var respectPrefersColorScheme = ${respectPrefersColorScheme};
|
|
42
|
-
|
|
43
|
-
function setDataThemeAttribute(theme) {
|
|
44
|
-
document.documentElement.setAttribute('data-theme', theme);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function getQueryStringTheme() {
|
|
48
|
-
try {
|
|
49
|
-
return new URLSearchParams(window.location.search).get('${ThemeQueryStringKey}')
|
|
50
|
-
} catch(e) {}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function getStoredTheme() {
|
|
54
|
-
try {
|
|
55
|
-
return localStorage.getItem('${ThemeStorageKey}');
|
|
56
|
-
} catch (err) {}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
var initialTheme = getQueryStringTheme() || getStoredTheme();
|
|
60
|
-
if (initialTheme !== null) {
|
|
61
|
-
setDataThemeAttribute(initialTheme);
|
|
62
|
-
} else {
|
|
63
|
-
if (
|
|
64
|
-
respectPrefersColorScheme &&
|
|
65
|
-
window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
66
|
-
) {
|
|
67
|
-
setDataThemeAttribute('dark');
|
|
68
|
-
} else if (
|
|
69
|
-
respectPrefersColorScheme &&
|
|
70
|
-
window.matchMedia('(prefers-color-scheme: light)').matches
|
|
71
|
-
) {
|
|
72
|
-
setDataThemeAttribute('light');
|
|
73
|
-
} else {
|
|
74
|
-
setDataThemeAttribute(defaultMode === 'dark' ? 'dark' : 'light');
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
})();`;
|
|
78
|
-
|
|
79
|
-
/* language=js */
|
|
80
|
-
const DataAttributeQueryStringInlineJavaScript = `
|
|
81
|
-
(function() {
|
|
82
|
-
try {
|
|
83
|
-
const entries = new URLSearchParams(window.location.search).entries();
|
|
84
|
-
for (var [searchKey, value] of entries) {
|
|
85
|
-
if (searchKey.startsWith('${DataQueryStringPrefixKey}')) {
|
|
86
|
-
var key = searchKey.replace('${DataQueryStringPrefixKey}',"data-")
|
|
87
|
-
document.documentElement.setAttribute(key, value);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
} catch(e) {}
|
|
91
|
-
})();
|
|
92
|
-
`;
|
|
93
|
-
|
|
94
|
-
// Duplicated constant. Unfortunately we can't import it from theme-common, as
|
|
95
|
-
// we need to support older nodejs versions without ESM support
|
|
96
|
-
// TODO: import from theme-common once we only support Node.js with ESM support
|
|
97
|
-
// + move all those announcementBar stuff there too
|
|
98
|
-
export const AnnouncementBarDismissStorageKey =
|
|
99
|
-
'docusaurus.announcement.dismiss';
|
|
100
|
-
const AnnouncementBarDismissDataAttribute =
|
|
101
|
-
'data-announcement-bar-initially-dismissed';
|
|
102
|
-
// We always render the announcement bar html on the server, to prevent layout
|
|
103
|
-
// shifts on React hydration. The theme can use CSS + the data attribute to hide
|
|
104
|
-
// the announcement bar asap (before React hydration)
|
|
105
|
-
/* language=js */
|
|
106
|
-
const AnnouncementBarInlineJavaScript = `
|
|
107
|
-
(function() {
|
|
108
|
-
function isDismissed() {
|
|
109
|
-
try {
|
|
110
|
-
return localStorage.getItem('${AnnouncementBarDismissStorageKey}') === 'true';
|
|
111
|
-
} catch (err) {}
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
document.documentElement.setAttribute('${AnnouncementBarDismissDataAttribute}', isDismissed());
|
|
115
|
-
})();`;
|
|
116
|
-
|
|
117
31
|
function getInfimaCSSFile(direction: string) {
|
|
118
32
|
return `infima/dist/css/default/default${
|
|
119
33
|
direction === 'rtl' ? '-rtl' : ''
|
|
@@ -126,6 +40,7 @@ export default function themeClassic(
|
|
|
126
40
|
): Plugin<undefined> {
|
|
127
41
|
const {
|
|
128
42
|
i18n: {currentLocale, localeConfigs},
|
|
43
|
+
siteStorage,
|
|
129
44
|
} = context;
|
|
130
45
|
const themeConfig = context.siteConfig.themeConfig as ThemeConfig;
|
|
131
46
|
const {
|
|
@@ -218,9 +133,9 @@ export default function themeClassic(
|
|
|
218
133
|
{
|
|
219
134
|
tagName: 'script',
|
|
220
135
|
innerHTML: `
|
|
221
|
-
${
|
|
136
|
+
${getThemeInlineScript({colorMode, siteStorage})}
|
|
222
137
|
${DataAttributeQueryStringInlineJavaScript}
|
|
223
|
-
${announcementBar ?
|
|
138
|
+
${announcementBar ? getAnnouncementBarInlineScript({siteStorage}) : ''}
|
|
224
139
|
`,
|
|
225
140
|
},
|
|
226
141
|
],
|
|
@@ -0,0 +1,114 @@
|
|
|
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 type {SiteStorage} from '@docusaurus/types';
|
|
9
|
+
import type {ThemeConfig} from '@docusaurus/theme-common';
|
|
10
|
+
|
|
11
|
+
// Support for ?docusaurus-theme=dark
|
|
12
|
+
const ThemeQueryStringKey = 'docusaurus-theme';
|
|
13
|
+
|
|
14
|
+
// Support for ?docusaurus-data-mode=embed&docusaurus-data-myAttr=42
|
|
15
|
+
const DataQueryStringPrefixKey = 'docusaurus-data-';
|
|
16
|
+
|
|
17
|
+
export function getThemeInlineScript({
|
|
18
|
+
colorMode: {defaultMode, respectPrefersColorScheme},
|
|
19
|
+
siteStorage,
|
|
20
|
+
}: {
|
|
21
|
+
colorMode: ThemeConfig['colorMode'];
|
|
22
|
+
siteStorage: SiteStorage;
|
|
23
|
+
}): string {
|
|
24
|
+
// Need to be inlined to prevent dark mode FOUC
|
|
25
|
+
// Make sure the key is the same as the one in the color mode React context
|
|
26
|
+
// Currently defined in: `docusaurus-theme-common/src/contexts/colorMode.tsx`
|
|
27
|
+
const themeStorageKey = `theme${siteStorage.namespace}`;
|
|
28
|
+
|
|
29
|
+
/* language=js */
|
|
30
|
+
return `(function() {
|
|
31
|
+
var defaultMode = '${defaultMode}';
|
|
32
|
+
var respectPrefersColorScheme = ${respectPrefersColorScheme};
|
|
33
|
+
|
|
34
|
+
function setDataThemeAttribute(theme) {
|
|
35
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getQueryStringTheme() {
|
|
39
|
+
try {
|
|
40
|
+
return new URLSearchParams(window.location.search).get('${ThemeQueryStringKey}')
|
|
41
|
+
} catch (e) {
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getStoredTheme() {
|
|
46
|
+
try {
|
|
47
|
+
return window['${siteStorage.type}'].getItem('${themeStorageKey}');
|
|
48
|
+
} catch (err) {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
var initialTheme = getQueryStringTheme() || getStoredTheme();
|
|
53
|
+
if (initialTheme !== null) {
|
|
54
|
+
setDataThemeAttribute(initialTheme);
|
|
55
|
+
} else {
|
|
56
|
+
if (
|
|
57
|
+
respectPrefersColorScheme &&
|
|
58
|
+
window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
59
|
+
) {
|
|
60
|
+
setDataThemeAttribute('dark');
|
|
61
|
+
} else if (
|
|
62
|
+
respectPrefersColorScheme &&
|
|
63
|
+
window.matchMedia('(prefers-color-scheme: light)').matches
|
|
64
|
+
) {
|
|
65
|
+
setDataThemeAttribute('light');
|
|
66
|
+
} else {
|
|
67
|
+
setDataThemeAttribute(defaultMode === 'dark' ? 'dark' : 'light');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
})();`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* language=js */
|
|
74
|
+
export const DataAttributeQueryStringInlineJavaScript = `
|
|
75
|
+
(function() {
|
|
76
|
+
try {
|
|
77
|
+
const entries = new URLSearchParams(window.location.search).entries();
|
|
78
|
+
for (var [searchKey, value] of entries) {
|
|
79
|
+
if (searchKey.startsWith('${DataQueryStringPrefixKey}')) {
|
|
80
|
+
var key = searchKey.replace('${DataQueryStringPrefixKey}',"data-")
|
|
81
|
+
document.documentElement.setAttribute(key, value);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} catch(e) {}
|
|
85
|
+
})();
|
|
86
|
+
`;
|
|
87
|
+
|
|
88
|
+
// We always render the announcement bar html on the server, to prevent layout
|
|
89
|
+
// shifts on React hydration. The theme can use CSS + the data attribute to hide
|
|
90
|
+
// the announcement bar asap (before React hydration)
|
|
91
|
+
export function getAnnouncementBarInlineScript({
|
|
92
|
+
siteStorage,
|
|
93
|
+
}: {
|
|
94
|
+
siteStorage: SiteStorage;
|
|
95
|
+
}): string {
|
|
96
|
+
// Duplicated constant. Unfortunately we can't import it from theme-common, as
|
|
97
|
+
// we need to support older nodejs versions without ESM support
|
|
98
|
+
// TODO: import from theme-common once we support Node.js with ESM support
|
|
99
|
+
// + move all those announcementBar stuff there too
|
|
100
|
+
const AnnouncementBarDismissStorageKey = `docusaurus.announcement.dismiss${siteStorage.namespace}`;
|
|
101
|
+
const AnnouncementBarDismissDataAttribute =
|
|
102
|
+
'data-announcement-bar-initially-dismissed';
|
|
103
|
+
|
|
104
|
+
/* language=js */
|
|
105
|
+
return `(function() {
|
|
106
|
+
function isDismissed() {
|
|
107
|
+
try {
|
|
108
|
+
return localStorage.getItem('${AnnouncementBarDismissStorageKey}') === 'true';
|
|
109
|
+
} catch (err) {}
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
document.documentElement.setAttribute('${AnnouncementBarDismissDataAttribute}', isDismissed());
|
|
113
|
+
})();`;
|
|
114
|
+
}
|
|
@@ -57,7 +57,7 @@ function BlogTagsPostsPageMetadata({tag}: Props): JSX.Element {
|
|
|
57
57
|
const title = useBlogTagsPostsPageTitle(tag);
|
|
58
58
|
return (
|
|
59
59
|
<>
|
|
60
|
-
<PageMetadata title={title} />
|
|
60
|
+
<PageMetadata title={title} description={tag.description} />
|
|
61
61
|
<SearchMetadata tag="blog_tags_posts" />
|
|
62
62
|
</>
|
|
63
63
|
);
|
|
@@ -75,6 +75,7 @@ function BlogTagsPostsPageContent({
|
|
|
75
75
|
{tag.unlisted && <Unlisted />}
|
|
76
76
|
<header className="margin-bottom--xl">
|
|
77
77
|
<Heading as="h1">{title}</Heading>
|
|
78
|
+
{tag.description && <p>{tag.description}</p>}
|
|
78
79
|
<Link href={tag.allTagsPath}>
|
|
79
80
|
<Translate
|
|
80
81
|
id="theme.tags.tagsPageLink"
|
|
@@ -32,7 +32,7 @@ function useCategoryItemsPlural() {
|
|
|
32
32
|
count,
|
|
33
33
|
translate(
|
|
34
34
|
{
|
|
35
|
-
message: '{count} items',
|
|
35
|
+
message: '1 item|{count} items',
|
|
36
36
|
id: 'theme.docs.DocCard.categoryDescription.plurals',
|
|
37
37
|
description:
|
|
38
38
|
'The default description for a category card in the generated index about how many items this category includes',
|
|
@@ -63,10 +63,11 @@ function DocItem({doc}: {doc: Props['tag']['items'][number]}): JSX.Element {
|
|
|
63
63
|
|
|
64
64
|
function DocTagDocListPageMetadata({
|
|
65
65
|
title,
|
|
66
|
+
tag,
|
|
66
67
|
}: Props & {title: string}): JSX.Element {
|
|
67
68
|
return (
|
|
68
69
|
<>
|
|
69
|
-
<PageMetadata title={title} />
|
|
70
|
+
<PageMetadata title={title} description={tag.description} />
|
|
70
71
|
<SearchMetadata tag="doc_tag_doc_list" />
|
|
71
72
|
</>
|
|
72
73
|
);
|
|
@@ -85,6 +86,7 @@ function DocTagDocListPageContent({
|
|
|
85
86
|
{tag.unlisted && <Unlisted />}
|
|
86
87
|
<header className="margin-bottom--xl">
|
|
87
88
|
<Heading as="h1">{title}</Heading>
|
|
89
|
+
{tag.description && <p>{tag.description}</p>}
|
|
88
90
|
<Link href={tag.allTagsPath}>
|
|
89
91
|
<Translate
|
|
90
92
|
id="theme.tags.tagsPageLink"
|
package/src/theme/Tag/index.tsx
CHANGED
|
@@ -12,10 +12,16 @@ import type {Props} from '@theme/Tag';
|
|
|
12
12
|
|
|
13
13
|
import styles from './styles.module.css';
|
|
14
14
|
|
|
15
|
-
export default function Tag({
|
|
15
|
+
export default function Tag({
|
|
16
|
+
permalink,
|
|
17
|
+
label,
|
|
18
|
+
count,
|
|
19
|
+
description,
|
|
20
|
+
}: Props): JSX.Element {
|
|
16
21
|
return (
|
|
17
22
|
<Link
|
|
18
23
|
href={permalink}
|
|
24
|
+
title={description}
|
|
19
25
|
className={clsx(
|
|
20
26
|
styles.tag,
|
|
21
27
|
count ? styles.tagWithCount : styles.tagRegular,
|
|
@@ -24,9 +24,9 @@ export default function TagsListInline({tags}: Props): JSX.Element {
|
|
|
24
24
|
</Translate>
|
|
25
25
|
</b>
|
|
26
26
|
<ul className={clsx(styles.tags, 'padding--none', 'margin-left--sm')}>
|
|
27
|
-
{tags.map((
|
|
28
|
-
<li key={
|
|
29
|
-
<Tag
|
|
27
|
+
{tags.map((tag) => (
|
|
28
|
+
<li key={tag.permalink} className={styles.tag}>
|
|
29
|
+
<Tag {...tag} />
|
|
30
30
|
</li>
|
|
31
31
|
))}
|
|
32
32
|
</ul>
|