@docusaurus/theme-common 2.4.1 → 3.0.0-alpha.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.
Files changed (114) hide show
  1. package/lib/components/Collapsible/index.d.ts +4 -4
  2. package/lib/components/Collapsible/index.d.ts.map +1 -1
  3. package/lib/components/Collapsible/index.js +4 -3
  4. package/lib/components/Collapsible/index.js.map +1 -1
  5. package/lib/components/Details/index.d.ts +1 -1
  6. package/lib/components/Details/index.d.ts.map +1 -1
  7. package/lib/components/Details/styles.module.css +5 -1
  8. package/lib/components/ThemedComponent/index.d.ts +32 -0
  9. package/lib/components/ThemedComponent/index.d.ts.map +1 -0
  10. package/lib/components/ThemedComponent/index.js +48 -0
  11. package/lib/components/ThemedComponent/index.js.map +1 -0
  12. package/lib/components/ThemedComponent/styles.module.css +18 -0
  13. package/lib/contexts/announcementBar.d.ts +1 -1
  14. package/lib/contexts/announcementBar.d.ts.map +1 -1
  15. package/lib/contexts/blogPost.d.ts +1 -1
  16. package/lib/contexts/blogPost.d.ts.map +1 -1
  17. package/lib/contexts/blogPost.js +3 -3
  18. package/lib/contexts/colorMode.d.ts +2 -2
  19. package/lib/contexts/colorMode.d.ts.map +1 -1
  20. package/lib/contexts/doc.d.ts +1 -1
  21. package/lib/contexts/doc.d.ts.map +1 -1
  22. package/lib/contexts/docSidebarItemsExpandedState.d.ts +1 -1
  23. package/lib/contexts/docSidebarItemsExpandedState.d.ts.map +1 -1
  24. package/lib/contexts/docsSidebar.d.ts +1 -1
  25. package/lib/contexts/docsSidebar.d.ts.map +1 -1
  26. package/lib/contexts/navbarMobileSidebar.d.ts +1 -1
  27. package/lib/contexts/navbarMobileSidebar.d.ts.map +1 -1
  28. package/lib/contexts/navbarSecondaryMenu/content.d.ts +2 -2
  29. package/lib/contexts/navbarSecondaryMenu/content.d.ts.map +1 -1
  30. package/lib/hooks/useMutationObserver.d.ts +1 -1
  31. package/lib/hooks/useMutationObserver.d.ts.map +1 -1
  32. package/lib/hooks/useTOCHighlight.d.ts +1 -1
  33. package/lib/hooks/useTOCHighlight.d.ts.map +1 -1
  34. package/lib/hooks/useWindowSize.d.ts +1 -1
  35. package/lib/hooks/useWindowSize.d.ts.map +1 -1
  36. package/lib/index.d.ts +3 -1
  37. package/lib/index.d.ts.map +1 -1
  38. package/lib/index.js +3 -1
  39. package/lib/index.js.map +1 -1
  40. package/lib/internal.d.ts +3 -2
  41. package/lib/internal.d.ts.map +1 -1
  42. package/lib/internal.js +3 -2
  43. package/lib/internal.js.map +1 -1
  44. package/lib/utils/ThemeClassNames.d.ts +2 -1
  45. package/lib/utils/ThemeClassNames.d.ts.map +1 -1
  46. package/lib/utils/ThemeClassNames.js +4 -0
  47. package/lib/utils/ThemeClassNames.js.map +1 -1
  48. package/lib/utils/admonitionUtils.d.ts.map +1 -1
  49. package/lib/utils/admonitionUtils.js +5 -6
  50. package/lib/utils/admonitionUtils.js.map +1 -1
  51. package/lib/utils/blogUtils.d.ts +13 -0
  52. package/lib/utils/blogUtils.d.ts.map +1 -0
  53. package/lib/utils/blogUtils.js +24 -0
  54. package/lib/utils/blogUtils.js.map +1 -0
  55. package/lib/utils/codeBlockUtils.d.ts +1 -1
  56. package/lib/utils/codeBlockUtils.d.ts.map +1 -1
  57. package/lib/utils/codeBlockUtils.js +15 -2
  58. package/lib/utils/codeBlockUtils.js.map +1 -1
  59. package/lib/utils/docsUtils.d.ts +11 -5
  60. package/lib/utils/docsUtils.d.ts.map +1 -1
  61. package/lib/utils/docsUtils.js +40 -16
  62. package/lib/utils/docsUtils.js.map +1 -1
  63. package/lib/utils/historyUtils.d.ts +1 -1
  64. package/lib/utils/historyUtils.d.ts.map +1 -1
  65. package/lib/utils/metadataUtils.d.ts +1 -1
  66. package/lib/utils/metadataUtils.d.ts.map +1 -1
  67. package/lib/utils/reactUtils.d.ts +2 -11
  68. package/lib/utils/reactUtils.d.ts.map +1 -1
  69. package/lib/utils/reactUtils.js +2 -13
  70. package/lib/utils/reactUtils.js.map +1 -1
  71. package/lib/utils/scrollUtils.d.ts +3 -3
  72. package/lib/utils/scrollUtils.d.ts.map +1 -1
  73. package/lib/utils/scrollUtils.js +3 -2
  74. package/lib/utils/scrollUtils.js.map +1 -1
  75. package/lib/utils/skipToContentUtils.d.ts +1 -1
  76. package/lib/utils/skipToContentUtils.d.ts.map +1 -1
  77. package/lib/utils/skipToContentUtils.js +1 -0
  78. package/lib/utils/skipToContentUtils.js.map +1 -1
  79. package/lib/utils/storageUtils.d.ts +2 -2
  80. package/lib/utils/storageUtils.d.ts.map +1 -1
  81. package/lib/utils/tabsUtils.d.ts +3 -2
  82. package/lib/utils/tabsUtils.d.ts.map +1 -1
  83. package/lib/utils/tabsUtils.js +10 -7
  84. package/lib/utils/tabsUtils.js.map +1 -1
  85. package/lib/utils/tagsUtils.d.ts +1 -1
  86. package/lib/utils/tagsUtils.d.ts.map +1 -1
  87. package/lib/utils/tocUtils.d.ts +1 -1
  88. package/lib/utils/tocUtils.d.ts.map +1 -1
  89. package/lib/utils/unlistedUtils.d.ts +11 -0
  90. package/lib/utils/unlistedUtils.d.ts.map +1 -0
  91. package/lib/utils/unlistedUtils.js +26 -0
  92. package/lib/utils/unlistedUtils.js.map +1 -0
  93. package/lib/utils/useThemeConfig.d.ts +17 -17
  94. package/lib/utils/useThemeConfig.d.ts.map +1 -1
  95. package/package.json +15 -15
  96. package/src/components/Collapsible/index.tsx +3 -3
  97. package/src/components/Details/styles.module.css +5 -1
  98. package/src/components/ThemedComponent/index.tsx +77 -0
  99. package/src/components/ThemedComponent/styles.module.css +18 -0
  100. package/src/contexts/blogPost.tsx +3 -3
  101. package/src/contexts/colorMode.tsx +1 -1
  102. package/src/index.ts +8 -1
  103. package/src/internal.ts +7 -3
  104. package/src/utils/ThemeClassNames.ts +6 -2
  105. package/src/utils/admonitionUtils.tsx +9 -8
  106. package/src/utils/blogUtils.ts +32 -0
  107. package/src/utils/codeBlockUtils.ts +21 -2
  108. package/src/utils/docsUtils.tsx +57 -19
  109. package/src/utils/reactUtils.tsx +1 -15
  110. package/src/utils/scrollUtils.tsx +2 -2
  111. package/src/utils/skipToContentUtils.tsx +1 -0
  112. package/src/utils/storageUtils.ts +1 -1
  113. package/src/utils/tabsUtils.tsx +20 -18
  114. package/src/utils/unlistedUtils.tsx +39 -0
@@ -27,6 +27,9 @@ export const ThemeClassNames = {
27
27
  },
28
28
  wrapper: {
29
29
  main: 'main-wrapper',
30
+ // TODO these wrapper class names are now quite useless
31
+ // TODO do breaking change later in 3.0
32
+ // we already add plugin name/id class on <html>: that's enough
30
33
  blogPages: 'blog-wrapper',
31
34
  docsPages: 'docs-wrapper',
32
35
  mdxPages: 'mdx-wrapper',
@@ -37,8 +40,9 @@ export const ThemeClassNames = {
37
40
  backToTopButton: 'theme-back-to-top-button',
38
41
  codeBlock: 'theme-code-block',
39
42
  admonition: 'theme-admonition',
40
- admonitionType: (type: 'note' | 'tip' | 'danger' | 'info' | 'caution') =>
41
- `theme-admonition-${type}`,
43
+ unlistedBanner: 'theme-unlisted-banner',
44
+
45
+ admonitionType: (type: string) => `theme-admonition-${type}`,
42
46
  },
43
47
  layout: {
44
48
  // TODO add other stable classNames here
@@ -14,16 +14,17 @@ function extractMDXAdmonitionTitle(children: ReactNode): {
14
14
  rest: ReactNode;
15
15
  } {
16
16
  const items = React.Children.toArray(children);
17
- const mdxAdmonitionTitle = items.find(
18
- (item) =>
19
- React.isValidElement(item) &&
20
- (item.props as {mdxType: string} | null)?.mdxType ===
21
- 'mdxAdmonitionTitle',
17
+ const mdxAdmonitionTitleWrapper = items.find(
18
+ (item) => React.isValidElement(item) && item.type === 'mdxAdmonitionTitle',
22
19
  ) as JSX.Element | undefined;
23
- const rest = <>{items.filter((item) => item !== mdxAdmonitionTitle)}</>;
20
+
21
+ const rest = items.filter((item) => item !== mdxAdmonitionTitleWrapper);
22
+
23
+ const mdxAdmonitionTitle = mdxAdmonitionTitleWrapper?.props.children;
24
+
24
25
  return {
25
- mdxAdmonitionTitle: mdxAdmonitionTitle?.props.children,
26
- rest,
26
+ mdxAdmonitionTitle,
27
+ rest: rest.length > 0 ? <>{rest}</> : null,
27
28
  };
28
29
  }
29
30
 
@@ -0,0 +1,32 @@
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 {useMemo} from 'react';
9
+ import {useLocation} from '@docusaurus/router';
10
+ import {isSamePath} from './routesUtils';
11
+ import type {BlogSidebarItem} from '@docusaurus/plugin-content-blog';
12
+
13
+ function isVisible(item: BlogSidebarItem, pathname: string): boolean {
14
+ if (item.unlisted && !isSamePath(item.permalink, pathname)) {
15
+ return false;
16
+ }
17
+ return true;
18
+ }
19
+
20
+ /**
21
+ * Return the visible blog sidebar items to display.
22
+ * Unlisted items are filtered.
23
+ */
24
+ export function useVisibleBlogSidebarItems(
25
+ items: BlogSidebarItem[],
26
+ ): BlogSidebarItem[] {
27
+ const {pathname} = useLocation();
28
+ return useMemo(
29
+ () => items.filter((item) => isVisible(item, pathname)),
30
+ [items, pathname],
31
+ );
32
+ }
@@ -19,6 +19,9 @@ const commentPatterns = {
19
19
  jsx: {start: '\\{\\s*\\/\\*', end: '\\*\\/\\s*\\}'},
20
20
  bash: {start: '#', end: ''},
21
21
  html: {start: '<!--', end: '-->'},
22
+ lua: {start: '--', end: ''},
23
+ wasm: {start: '\\;\\;', end: ''},
24
+ tex: {start: '%', end: ''},
22
25
  };
23
26
 
24
27
  type CommentType = keyof typeof commentPatterns;
@@ -83,10 +86,26 @@ function getAllMagicCommentDirectiveStyles(
83
86
  // Text uses HTML, front matter uses bash
84
87
  return getCommentPattern(['html', 'jsx', 'bash'], magicCommentDirectives);
85
88
 
89
+ case 'tex':
90
+ case 'latex':
91
+ case 'matlab':
92
+ return getCommentPattern(['tex'], magicCommentDirectives);
93
+
94
+ case 'lua':
95
+ case 'haskell':
96
+ case 'sql':
97
+ return getCommentPattern(['lua'], magicCommentDirectives);
98
+
99
+ case 'wasm':
100
+ return getCommentPattern(['wasm'], magicCommentDirectives);
101
+
86
102
  default:
87
- // All comment types
103
+ // All comment types except lua, wasm and matlab
88
104
  return getCommentPattern(
89
- Object.keys(commentPatterns) as CommentType[],
105
+ Object.keys(commentPatterns).filter(
106
+ (pattern) =>
107
+ !['lua', 'wasm', 'tex', 'latex', 'matlab'].includes(pattern),
108
+ ) as CommentType[],
90
109
  magicCommentDirectives,
91
110
  );
92
111
  }
@@ -17,7 +17,7 @@ import {
17
17
  type GlobalSidebar,
18
18
  type GlobalDoc,
19
19
  } from '@docusaurus/plugin-content-docs/client';
20
- import type {Props as DocPageProps} from '@theme/DocPage';
20
+ import type {Props as DocRootProps} from '@theme/DocRoot';
21
21
  import {useDocsPreferredVersion} from '../contexts/docsPreferredVersion';
22
22
  import {useDocsVersion} from '../contexts/docsVersion';
23
23
  import {useDocsSidebar} from '../contexts/docsSidebar';
@@ -79,27 +79,38 @@ export function findSidebarCategory(
79
79
  * Best effort to assign a link to a sidebar category. If the category doesn't
80
80
  * have a link itself, we link to the first sub item with a link.
81
81
  */
82
- export function findFirstCategoryLink(
82
+ export function findFirstSidebarItemCategoryLink(
83
83
  item: PropSidebarItemCategory,
84
84
  ): string | undefined {
85
- if (item.href) {
85
+ if (item.href && !item.linkUnlisted) {
86
86
  return item.href;
87
87
  }
88
88
 
89
89
  for (const subItem of item.items) {
90
- if (subItem.type === 'link') {
91
- return subItem.href;
92
- } else if (subItem.type === 'category') {
93
- const categoryLink = findFirstCategoryLink(subItem);
94
- if (categoryLink) {
95
- return categoryLink;
96
- }
90
+ const link = findFirstSidebarItemLink(subItem);
91
+ if (link) {
92
+ return link;
97
93
  }
98
- // Could be "html" items
99
94
  }
100
95
  return undefined;
101
96
  }
102
97
 
98
+ /**
99
+ * Best effort to assign a link to a sidebar item.
100
+ */
101
+ export function findFirstSidebarItemLink(
102
+ item: PropSidebarItem,
103
+ ): string | undefined {
104
+ if (item.type === 'link' && !item.unlisted) {
105
+ return item.href;
106
+ }
107
+ if (item.type === 'category') {
108
+ return findFirstSidebarItemCategoryLink(item);
109
+ }
110
+ // Other items types, like "html"
111
+ return undefined;
112
+ }
113
+
103
114
  /**
104
115
  * Gets the category associated with the current location. Should only be used
105
116
  * on category index pages.
@@ -152,6 +163,34 @@ export function isActiveSidebarItem(
152
163
  return false;
153
164
  }
154
165
 
166
+ export function isVisibleSidebarItem(
167
+ item: PropSidebarItem,
168
+ activePath: string,
169
+ ): boolean {
170
+ switch (item.type) {
171
+ case 'category':
172
+ return (
173
+ isActiveSidebarItem(item, activePath) ||
174
+ item.items.some((subItem) => isVisibleSidebarItem(subItem, activePath))
175
+ );
176
+ case 'link':
177
+ // An unlisted item remains visible if it is active
178
+ return !item.unlisted || isActiveSidebarItem(item, activePath);
179
+ default:
180
+ return false;
181
+ }
182
+ }
183
+
184
+ export function useVisibleSidebarItems(
185
+ items: readonly PropSidebarItem[],
186
+ activePath: string,
187
+ ): PropSidebarItem[] {
188
+ return useMemo(
189
+ () => items.filter((item) => isVisibleSidebarItem(item, activePath)),
190
+ [items, activePath],
191
+ );
192
+ }
193
+
155
194
  function getSidebarBreadcrumbs(param: {
156
195
  sidebarItems: PropSidebar;
157
196
  pathname: string;
@@ -321,14 +360,11 @@ Available doc ids are:
321
360
  * version metadata, and the subroutes creating individual doc pages. This hook
322
361
  * will match the current location against all known sub-routes.
323
362
  *
324
- * @param props The props received by `@theme/DocPage`
363
+ * @param props The props received by `@theme/DocRoot`
325
364
  * @returns The data of the relevant document at the current location, or `null`
326
365
  * if no document associated with the current location can be found.
327
366
  */
328
- export function useDocRouteMetadata({
329
- route,
330
- versionMetadata,
331
- }: DocPageProps): null | {
367
+ export function useDocRootMetadata({route}: DocRootProps): null | {
332
368
  /** The element that should be rendered at the current location. */
333
369
  docElement: JSX.Element;
334
370
  /**
@@ -340,6 +376,7 @@ export function useDocRouteMetadata({
340
376
  sidebarItems: PropSidebar | undefined;
341
377
  } {
342
378
  const location = useLocation();
379
+ const versionMetadata = useDocsVersion();
343
380
  const docRoutes = route.routes!;
344
381
  const currentDocRoute = docRoutes.find((docRoute) =>
345
382
  matchPath(location.pathname, docRoute),
@@ -365,15 +402,16 @@ export function useDocRouteMetadata({
365
402
  }
366
403
 
367
404
  /**
368
- * Filter categories that don't have a link.
405
+ * Filter items we don't want to display on the doc card list view
369
406
  * @param items
370
407
  */
371
408
  export function filterDocCardListItems(
372
409
  items: PropSidebarItem[],
373
410
  ): PropSidebarItem[] {
374
411
  return items.filter((item) => {
375
- if (item.type === 'category') {
376
- return !!findFirstCategoryLink(item);
412
+ const canHaveLink = item.type === 'category' || item.type === 'link';
413
+ if (canHaveLink) {
414
+ return !!findFirstSidebarItemLink(item);
377
415
  }
378
416
  return true;
379
417
  });
@@ -7,26 +7,12 @@
7
7
 
8
8
  import React, {
9
9
  useCallback,
10
- useEffect,
11
- useLayoutEffect,
12
10
  useMemo,
13
11
  useRef,
14
12
  type ComponentType,
15
13
  type ReactNode,
16
14
  } from 'react';
17
- import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
18
-
19
- /**
20
- * This hook is like `useLayoutEffect`, but without the SSR warning.
21
- * It seems hacky but it's used in many React libs (Redux, Formik...).
22
- * Also mentioned here: https://github.com/facebook/react/issues/16956
23
- *
24
- * It is useful when you need to update a ref as soon as possible after a React
25
- * render (before `useEffect`).
26
- */
27
- export const useIsomorphicLayoutEffect = ExecutionEnvironment.canUseDOM
28
- ? useLayoutEffect
29
- : useEffect;
15
+ import useIsomorphicLayoutEffect from '@docusaurus/useIsomorphicLayoutEffect';
30
16
 
31
17
  /**
32
18
  * Temporary userland implementation until an official hook is implemented
@@ -9,13 +9,13 @@ import React, {
9
9
  useCallback,
10
10
  useContext,
11
11
  useEffect,
12
- useLayoutEffect,
13
12
  useMemo,
14
13
  useRef,
15
14
  type ReactNode,
16
15
  } from 'react';
17
16
  import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
18
17
  import useIsBrowser from '@docusaurus/useIsBrowser';
18
+ import useIsomorphicLayoutEffect from '@docusaurus/useIsomorphicLayoutEffect';
19
19
  import {useEvent, ReactContextError} from './reactUtils';
20
20
 
21
21
  type ScrollController = {
@@ -221,7 +221,7 @@ export function useScrollPositionBlocker(): {
221
221
  [scrollController, scrollPositionSaver],
222
222
  );
223
223
 
224
- useLayoutEffect(() => {
224
+ useIsomorphicLayoutEffect(() => {
225
225
  // Queuing permits to restore scroll position after all useLayoutEffect
226
226
  // have run, and yet preserve the sync nature of the scroll restoration
227
227
  // See https://github.com/facebook/docusaurus/issues/8625
@@ -93,6 +93,7 @@ export function SkipToContentLink(props: SkipToContentLinkProps): JSX.Element {
93
93
  ref={containerRef}
94
94
  role="region"
95
95
  aria-label={DefaultSkipToContentLabel}>
96
+ {/* eslint-disable-next-line @docusaurus/no-html-links */}
96
97
  <a
97
98
  {...props}
98
99
  // Note this is a fallback href in case JS is disabled
@@ -11,7 +11,7 @@ import {useSyncExternalStore} from 'use-sync-external-store/shim';
11
11
 
12
12
  const StorageTypes = ['localStorage', 'sessionStorage', 'none'] as const;
13
13
 
14
- export type StorageType = typeof StorageTypes[number];
14
+ export type StorageType = (typeof StorageTypes)[number];
15
15
 
16
16
  const DefaultStorageType: StorageType = 'localStorage';
17
17
 
@@ -12,9 +12,9 @@ import React, {
12
12
  useMemo,
13
13
  type ReactNode,
14
14
  type ReactElement,
15
- useLayoutEffect,
16
15
  } from 'react';
17
16
  import {useHistory} from '@docusaurus/router';
17
+ import useIsomorphicLayoutEffect from '@docusaurus/useIsomorphicLayoutEffect';
18
18
  import {useQueryStringValue} from '@docusaurus/theme-common/internal';
19
19
  import {duplicates, useStorageSlot} from '../index';
20
20
 
@@ -61,25 +61,27 @@ function isTabItem(
61
61
  return !!props && typeof props === 'object' && 'value' in props;
62
62
  }
63
63
 
64
- function ensureValidChildren(children: TabsProps['children']) {
65
- return (React.Children.map(children, (child) => {
66
- // Pass falsy values through: allow conditionally not rendering a tab
67
- if (!child || (isValidElement(child) && isTabItem(child))) {
68
- return child;
69
- }
70
- // child.type.name will give non-sensical values in prod because of
71
- // minification, but we assume it won't throw in prod.
72
- throw new Error(
73
- `Docusaurus error: Bad <Tabs> child <${
74
- // @ts-expect-error: guarding against unexpected cases
75
- typeof child.type === 'string' ? child.type : child.type.name
76
- }>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`,
77
- );
78
- })?.filter(Boolean) ?? []) as ReactElement<TabItemProps>[];
64
+ export function sanitizeTabsChildren(children: TabsProps['children']) {
65
+ return (React.Children.toArray(children)
66
+ .filter((child) => child !== '\n')
67
+ .map((child) => {
68
+ if (!child || (isValidElement(child) && isTabItem(child))) {
69
+ return child;
70
+ }
71
+ // child.type.name will give non-sensical values in prod because of
72
+ // minification, but we assume it won't throw in prod.
73
+ throw new Error(
74
+ `Docusaurus error: Bad <Tabs> child <${
75
+ // @ts-expect-error: guarding against unexpected cases
76
+ typeof child.type === 'string' ? child.type : child.type.name
77
+ }>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`,
78
+ );
79
+ })
80
+ ?.filter(Boolean) ?? []) as ReactElement<TabItemProps>[];
79
81
  }
80
82
 
81
83
  function extractChildrenTabValues(children: TabsProps['children']): TabValue[] {
82
- return ensureValidChildren(children).map(
84
+ return sanitizeTabsChildren(children).map(
83
85
  ({props: {value, label, attributes, default: isDefault}}) => ({
84
86
  value,
85
87
  label,
@@ -250,7 +252,7 @@ export function useTabs(props: TabsProps): {
250
252
  })();
251
253
  // Sync in a layout/sync effect is important, for useScrollPositionBlocker
252
254
  // See https://github.com/facebook/docusaurus/issues/8625
253
- useLayoutEffect(() => {
255
+ useIsomorphicLayoutEffect(() => {
254
256
  if (valueToSync) {
255
257
  setSelectedValue(valueToSync);
256
258
  }
@@ -0,0 +1,39 @@
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 from 'react';
9
+ import Translate from '@docusaurus/Translate';
10
+ import Head from '@docusaurus/Head';
11
+
12
+ export function UnlistedBannerTitle(): JSX.Element {
13
+ return (
14
+ <Translate
15
+ id="theme.unlistedContent.title"
16
+ description="The unlisted content banner title">
17
+ Unlisted page
18
+ </Translate>
19
+ );
20
+ }
21
+
22
+ export function UnlistedBannerMessage(): JSX.Element {
23
+ return (
24
+ <Translate
25
+ id="theme.unlistedContent.message"
26
+ description="The unlisted content banner message">
27
+ This page is unlisted. Search engines will not index it, and only users
28
+ having a direct link can access it.
29
+ </Translate>
30
+ );
31
+ }
32
+
33
+ export function UnlistedMetadata(): JSX.Element {
34
+ return (
35
+ <Head>
36
+ <meta name="robots" content="noindex, nofollow" />
37
+ </Head>
38
+ );
39
+ }