@docusaurus/theme-classic 2.0.0-beta.8e9b829d9 → 2.0.0-beta.9

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 (275) hide show
  1. package/README.md +1 -1
  2. package/codeTranslations/ar.json +12 -6
  3. package/codeTranslations/base.json +12 -0
  4. package/codeTranslations/bn.json +6 -0
  5. package/codeTranslations/cs.json +62 -0
  6. package/codeTranslations/da.json +6 -0
  7. package/codeTranslations/de.json +8 -2
  8. package/codeTranslations/es.json +10 -4
  9. package/codeTranslations/fa.json +9 -3
  10. package/codeTranslations/fil.json +6 -0
  11. package/codeTranslations/fr.json +6 -0
  12. package/codeTranslations/he.json +6 -0
  13. package/codeTranslations/hi.json +6 -0
  14. package/codeTranslations/ja.json +6 -0
  15. package/codeTranslations/ko.json +6 -0
  16. package/codeTranslations/pl.json +6 -0
  17. package/codeTranslations/pt-BR.json +8 -2
  18. package/codeTranslations/pt-PT.json +6 -0
  19. package/codeTranslations/ru.json +6 -0
  20. package/codeTranslations/sr.json +62 -0
  21. package/codeTranslations/tr.json +9 -3
  22. package/codeTranslations/vi.json +10 -4
  23. package/codeTranslations/zh-Hans.json +6 -0
  24. package/codeTranslations/zh-Hant.json +6 -0
  25. package/lib/__tests__/validateThemeConfig.test.js +154 -4
  26. package/lib/index.js +2 -3
  27. package/lib/prism-include-languages.js +9 -5
  28. package/lib/theme/AnnouncementBar/index.js +8 -12
  29. package/lib/theme/AnnouncementBar/styles.module.css +23 -32
  30. package/lib/theme/BackToTopButton/index.js +27 -13
  31. package/lib/theme/BackToTopButton/styles.module.css +17 -14
  32. package/lib/theme/BlogArchivePage/index.js +89 -0
  33. package/lib/theme/BlogLayout/index.js +2 -6
  34. package/lib/theme/BlogListPage/index.js +1 -1
  35. package/lib/theme/BlogPostAuthor/index.js +51 -0
  36. package/lib/theme/BlogPostAuthor/styles.module.css +12 -0
  37. package/lib/theme/BlogPostAuthors/index.js +47 -0
  38. package/lib/theme/BlogPostAuthors/styles.module.css +11 -0
  39. package/lib/theme/BlogPostItem/index.js +58 -67
  40. package/lib/theme/BlogPostPage/index.js +33 -4
  41. package/lib/theme/BlogSidebar/styles.module.css +2 -2
  42. package/lib/theme/BlogTagsListPage/index.js +3 -28
  43. package/lib/theme/BlogTagsPostsPage/index.js +5 -8
  44. package/lib/theme/CodeBlock/index.js +44 -37
  45. package/lib/theme/CodeBlock/styles.module.css +1 -2
  46. package/lib/theme/DocItem/index.js +15 -40
  47. package/lib/theme/DocItem/styles.module.css +2 -12
  48. package/lib/theme/DocItemFooter/index.js +79 -0
  49. package/lib/theme/DocItemFooter/styles.module.css +18 -0
  50. package/lib/theme/DocPage/index.js +18 -13
  51. package/lib/theme/DocSidebar/index.js +11 -16
  52. package/lib/theme/DocSidebarItem/index.js +12 -10
  53. package/lib/theme/DocTagDocListPage/index.js +89 -0
  54. package/lib/theme/DocTagsListPage/index.js +44 -0
  55. package/lib/theme/DocVersionBanner/index.js +6 -4
  56. package/lib/theme/EditThisPage/index.js +3 -1
  57. package/lib/theme/Footer/index.js +5 -3
  58. package/lib/theme/Heading/index.js +7 -9
  59. package/lib/theme/Heading/styles.css +4 -6
  60. package/lib/theme/Heading/styles.module.css +9 -5
  61. package/lib/theme/IconClose/index.js +31 -0
  62. package/lib/theme/LastUpdated/index.js +4 -2
  63. package/lib/theme/LayoutHead/index.js +13 -11
  64. package/lib/theme/LayoutProviders/index.js +7 -5
  65. package/lib/theme/Logo/index.js +14 -12
  66. package/lib/theme/MDXComponents/index.js +27 -1
  67. package/lib/theme/MDXComponents/styles.css +11 -0
  68. package/lib/theme/MDXPage/index.js +2 -1
  69. package/lib/theme/Navbar/index.js +20 -3
  70. package/lib/theme/Navbar/styles.module.css +5 -1
  71. package/lib/theme/NavbarItem/DefaultNavbarItem.js +12 -4
  72. package/lib/theme/NavbarItem/DocNavbarItem.js +5 -3
  73. package/lib/theme/NavbarItem/DocsVersionDropdownNavbarItem.js +7 -1
  74. package/lib/theme/NavbarItem/DropdownNavbarItem.js +3 -3
  75. package/lib/theme/NavbarItem/{LocaleDropdownNavbarItem.js → LocaleDropdownNavbarItem/index.js} +3 -4
  76. package/lib/theme/NavbarItem/LocaleDropdownNavbarItem/styles.module.css +11 -0
  77. package/lib/theme/NavbarItem/index.js +5 -0
  78. package/lib/theme/Seo/index.js +10 -7
  79. package/lib/theme/TOC/index.js +9 -30
  80. package/lib/theme/TOC/styles.module.css +1 -1
  81. package/lib/theme/TOCCollapsible/index.js +5 -3
  82. package/lib/theme/TOCInline/index.js +7 -27
  83. package/lib/theme/TOCItems/index.js +78 -0
  84. package/lib/theme/Tabs/__tests__/index.test.js +123 -0
  85. package/lib/theme/Tabs/index.js +73 -50
  86. package/lib/theme/Tabs/styles.module.css +0 -13
  87. package/lib/theme/Tag/index.js +40 -0
  88. package/lib/theme/Tag/styles.module.css +70 -0
  89. package/lib/theme/TagsListByLetter/index.js +48 -0
  90. package/lib/theme/TagsListByLetter/styles.module.css +11 -0
  91. package/lib/theme/TagsListInline/index.js +44 -0
  92. package/lib/theme/TagsListInline/styles.module.css +15 -0
  93. package/lib/theme/ThemedImage/index.js +3 -5
  94. package/lib/theme/Toggle/index.js +23 -18
  95. package/lib/theme/Toggle/styles.module.css +91 -0
  96. package/lib/theme/hooks/useHideableNavbar.js +14 -31
  97. package/lib/theme/hooks/useTheme.js +2 -2
  98. package/lib/theme/hooks/useWindowSize.js +2 -7
  99. package/lib/theme/prism-include-languages.js +4 -3
  100. package/lib/translations.js +4 -4
  101. package/lib/types.d.ts +216 -105
  102. package/lib/validateThemeConfig.js +215 -254
  103. package/lib-next/__tests__/validateThemeConfig.test.js +154 -4
  104. package/lib-next/index.js +1 -2
  105. package/lib-next/prism-include-languages.js +0 -2
  106. package/lib-next/theme/AnnouncementBar/index.js +7 -12
  107. package/lib-next/theme/AnnouncementBar/styles.module.css +23 -32
  108. package/lib-next/theme/BackToTopButton/index.js +37 -17
  109. package/lib-next/theme/BackToTopButton/styles.module.css +17 -14
  110. package/lib-next/theme/BlogArchivePage/index.js +80 -0
  111. package/lib-next/theme/BlogLayout/index.js +4 -7
  112. package/lib-next/theme/BlogListPage/index.js +1 -0
  113. package/lib-next/theme/BlogPostAuthor/index.js +46 -0
  114. package/lib-next/theme/BlogPostAuthor/styles.module.css +12 -0
  115. package/lib-next/theme/BlogPostAuthors/index.js +34 -0
  116. package/lib-next/theme/BlogPostAuthors/styles.module.css +11 -0
  117. package/lib-next/theme/BlogPostItem/index.js +79 -86
  118. package/lib-next/theme/BlogPostPage/index.js +55 -8
  119. package/lib-next/theme/BlogSidebar/styles.module.css +2 -2
  120. package/lib-next/theme/BlogTagsListPage/index.js +7 -39
  121. package/lib-next/theme/BlogTagsPostsPage/index.js +3 -4
  122. package/lib-next/theme/CodeBlock/index.js +53 -49
  123. package/lib-next/theme/CodeBlock/styles.module.css +1 -2
  124. package/lib-next/theme/DocItem/index.js +27 -45
  125. package/lib-next/theme/DocItem/styles.module.css +2 -12
  126. package/lib-next/theme/DocItemFooter/index.js +79 -0
  127. package/lib-next/theme/DocItemFooter/styles.module.css +18 -0
  128. package/lib-next/theme/DocPage/index.js +18 -14
  129. package/lib-next/theme/DocSidebar/index.js +18 -15
  130. package/lib-next/theme/DocSidebarItem/index.js +31 -11
  131. package/lib-next/theme/DocTagDocListPage/index.js +89 -0
  132. package/lib-next/theme/DocTagsListPage/index.js +38 -0
  133. package/lib-next/theme/DocVersionBanner/index.js +16 -9
  134. package/lib-next/theme/EditThisPage/index.js +6 -1
  135. package/lib-next/theme/Footer/index.js +14 -3
  136. package/lib-next/theme/Heading/index.js +10 -13
  137. package/lib-next/theme/Heading/styles.css +4 -6
  138. package/lib-next/theme/Heading/styles.module.css +9 -5
  139. package/lib-next/theme/IconClose/index.js +23 -0
  140. package/lib-next/theme/LastUpdated/index.js +3 -2
  141. package/lib-next/theme/LayoutHead/index.js +9 -15
  142. package/lib-next/theme/LayoutProviders/index.js +8 -5
  143. package/lib-next/theme/Logo/index.js +23 -19
  144. package/lib-next/theme/MDXComponents/index.js +20 -1
  145. package/lib-next/theme/MDXComponents/styles.css +11 -0
  146. package/lib-next/theme/MDXPage/index.js +10 -2
  147. package/lib-next/theme/Navbar/index.js +27 -3
  148. package/lib-next/theme/Navbar/styles.module.css +5 -1
  149. package/lib-next/theme/NavbarItem/DefaultNavbarItem.js +15 -4
  150. package/lib-next/theme/NavbarItem/DocNavbarItem.js +5 -3
  151. package/lib-next/theme/NavbarItem/DocsVersionDropdownNavbarItem.js +12 -4
  152. package/lib-next/theme/NavbarItem/DropdownNavbarItem.js +4 -6
  153. package/lib-next/theme/NavbarItem/{LocaleDropdownNavbarItem.js → LocaleDropdownNavbarItem/index.js} +2 -6
  154. package/lib-next/theme/NavbarItem/LocaleDropdownNavbarItem/styles.module.css +11 -0
  155. package/lib-next/theme/NavbarItem/index.js +2 -0
  156. package/lib-next/theme/Seo/index.js +11 -7
  157. package/lib-next/theme/TOC/index.js +12 -36
  158. package/lib-next/theme/TOC/styles.module.css +1 -1
  159. package/lib-next/theme/TOCCollapsible/index.js +12 -3
  160. package/lib-next/theme/TOCInline/index.js +10 -28
  161. package/lib-next/theme/TOCItems/index.js +85 -0
  162. package/lib-next/theme/Tabs/__tests__/index.test.js +142 -0
  163. package/lib-next/theme/Tabs/index.js +91 -43
  164. package/lib-next/theme/Tabs/styles.module.css +0 -13
  165. package/lib-next/theme/Tag/index.js +27 -0
  166. package/lib-next/theme/Tag/styles.module.css +70 -0
  167. package/lib-next/theme/TagsListByLetter/index.js +42 -0
  168. package/lib-next/theme/TagsListByLetter/styles.module.css +11 -0
  169. package/lib-next/theme/TagsListInline/index.js +31 -0
  170. package/lib-next/theme/TagsListInline/styles.module.css +15 -0
  171. package/lib-next/theme/ThemedImage/index.js +3 -3
  172. package/lib-next/theme/Toggle/index.js +20 -15
  173. package/lib-next/theme/Toggle/styles.module.css +91 -0
  174. package/lib-next/theme/hooks/useHideableNavbar.js +31 -47
  175. package/lib-next/theme/hooks/useTheme.js +2 -2
  176. package/lib-next/theme/hooks/useWindowSize.js +2 -6
  177. package/lib-next/theme/prism-include-languages.js +2 -1
  178. package/lib-next/translations.js +6 -10
  179. package/lib-next/types.d.ts +216 -105
  180. package/lib-next/validateThemeConfig.js +40 -36
  181. package/package.json +23 -19
  182. package/src/__tests__/validateThemeConfig.test.js +154 -4
  183. package/src/index.ts +11 -9
  184. package/src/{prism-include-languages.js → prism-include-languages.ts} +0 -0
  185. package/src/theme/AnnouncementBar/index.tsx +8 -12
  186. package/src/theme/AnnouncementBar/styles.module.css +23 -32
  187. package/src/theme/BackToTopButton/index.tsx +39 -17
  188. package/src/theme/BackToTopButton/styles.module.css +17 -14
  189. package/src/theme/BlogArchivePage/index.tsx +91 -0
  190. package/src/theme/BlogLayout/index.tsx +4 -8
  191. package/src/theme/BlogListPage/index.tsx +1 -0
  192. package/src/theme/BlogPostAuthor/index.tsx +49 -0
  193. package/src/theme/BlogPostAuthor/styles.module.css +12 -0
  194. package/src/theme/BlogPostAuthors/index.tsx +36 -0
  195. package/src/theme/BlogPostAuthors/styles.module.css +11 -0
  196. package/src/theme/BlogPostItem/index.tsx +70 -80
  197. package/src/theme/BlogPostPage/index.tsx +57 -8
  198. package/src/theme/BlogSidebar/styles.module.css +2 -2
  199. package/src/theme/BlogTagsListPage/index.tsx +7 -41
  200. package/src/theme/BlogTagsPostsPage/index.tsx +3 -4
  201. package/src/theme/CodeBlock/index.tsx +63 -47
  202. package/src/theme/CodeBlock/styles.module.css +1 -2
  203. package/src/theme/DocItem/index.tsx +27 -46
  204. package/src/theme/DocItem/styles.module.css +2 -12
  205. package/src/theme/DocItemFooter/index.tsx +91 -0
  206. package/src/theme/DocItemFooter/styles.module.css +18 -0
  207. package/src/theme/DocPage/index.tsx +16 -12
  208. package/src/theme/DocSidebar/index.tsx +20 -16
  209. package/src/theme/DocSidebarItem/index.tsx +29 -10
  210. package/src/theme/DocTagDocListPage/index.tsx +89 -0
  211. package/src/theme/DocTagsListPage/index.tsx +41 -0
  212. package/src/theme/DocVersionBanner/index.tsx +26 -15
  213. package/src/theme/EditThisPage/index.tsx +6 -1
  214. package/src/theme/Footer/index.tsx +16 -3
  215. package/src/theme/Heading/index.tsx +10 -13
  216. package/src/theme/Heading/styles.css +4 -6
  217. package/src/theme/Heading/styles.module.css +9 -5
  218. package/src/theme/IconClose/index.tsx +26 -0
  219. package/src/theme/LastUpdated/index.tsx +3 -2
  220. package/src/theme/LayoutHead/index.tsx +9 -9
  221. package/src/theme/LayoutProviders/index.tsx +8 -5
  222. package/src/theme/Logo/index.tsx +19 -15
  223. package/src/theme/MDXComponents/index.tsx +20 -1
  224. package/src/theme/MDXComponents/styles.css +11 -0
  225. package/src/theme/MDXPage/index.tsx +10 -2
  226. package/src/theme/Navbar/index.tsx +26 -2
  227. package/src/theme/Navbar/styles.module.css +5 -1
  228. package/src/theme/NavbarItem/DefaultNavbarItem.tsx +15 -4
  229. package/src/theme/NavbarItem/DocNavbarItem.tsx +9 -5
  230. package/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx +15 -6
  231. package/src/theme/NavbarItem/DocsVersionNavbarItem.tsx +7 -3
  232. package/src/theme/NavbarItem/DropdownNavbarItem.tsx +4 -6
  233. package/src/theme/NavbarItem/{LocaleDropdownNavbarItem.tsx → LocaleDropdownNavbarItem/index.tsx} +6 -5
  234. package/src/theme/NavbarItem/LocaleDropdownNavbarItem/styles.module.css +11 -0
  235. package/src/theme/NavbarItem/index.tsx +6 -1
  236. package/src/theme/Seo/index.tsx +7 -4
  237. package/src/theme/TOC/index.tsx +13 -38
  238. package/src/theme/TOC/styles.module.css +1 -1
  239. package/src/theme/TOCCollapsible/index.tsx +8 -2
  240. package/src/theme/TOCInline/index.tsx +13 -32
  241. package/src/theme/TOCItems/index.tsx +96 -0
  242. package/src/theme/Tabs/__tests__/index.test.tsx +129 -0
  243. package/src/theme/Tabs/index.tsx +93 -49
  244. package/src/theme/Tabs/styles.module.css +0 -13
  245. package/src/theme/Tag/index.tsx +31 -0
  246. package/src/theme/Tag/styles.module.css +70 -0
  247. package/src/theme/TagsListByLetter/index.tsx +45 -0
  248. package/src/theme/TagsListByLetter/styles.module.css +11 -0
  249. package/src/theme/TagsListInline/index.tsx +35 -0
  250. package/src/theme/TagsListInline/styles.module.css +15 -0
  251. package/src/theme/ThemedImage/index.tsx +3 -3
  252. package/src/theme/Toggle/index.tsx +20 -15
  253. package/src/theme/Toggle/styles.module.css +91 -0
  254. package/src/theme/hooks/useContextualSearchFilters.ts +1 -1
  255. package/src/theme/hooks/useHideableNavbar.ts +32 -47
  256. package/src/theme/hooks/useTabGroupChoice.ts +2 -2
  257. package/src/theme/hooks/useTheme.ts +2 -2
  258. package/src/theme/hooks/useWindowSize.ts +2 -7
  259. package/src/theme/prism-include-languages.ts +3 -2
  260. package/src/translations.ts +6 -10
  261. package/src/types.d.ts +216 -105
  262. package/src/{validateThemeConfig.js → validateThemeConfig.ts} +46 -12
  263. package/tsconfig.json +0 -1
  264. package/update-code-translations.js +5 -4
  265. package/update-code-translations.test.js +1 -1
  266. package/update.js +151 -0
  267. package/lib/theme/Toggle/styles.css +0 -103
  268. package/lib/theme/hooks/useScrollPosition.js +0 -51
  269. package/lib/theme/hooks/useTOCHighlight.js +0 -87
  270. package/lib-next/theme/Toggle/styles.css +0 -103
  271. package/lib-next/theme/hooks/useScrollPosition.js +0 -42
  272. package/lib-next/theme/hooks/useTOCHighlight.js +0 -84
  273. package/src/theme/Toggle/styles.css +0 -103
  274. package/src/theme/hooks/useScrollPosition.ts +0 -52
  275. package/src/theme/hooks/useTOCHighlight.ts +0 -98
@@ -0,0 +1,34 @@
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 clsx from 'clsx';
9
+ import BlogPostAuthor from '@theme/BlogPostAuthor';
10
+ import styles from './styles.module.css'; // Component responsible for the authors layout
11
+
12
+ export default function BlogPostAuthors({authors, assets}) {
13
+ const authorsCount = authors.length;
14
+
15
+ if (authorsCount === 0) {
16
+ return <></>;
17
+ }
18
+
19
+ return (
20
+ <div className="row margin-top--md margin-bottom--sm">
21
+ {authors.map((author, idx) => (
22
+ <div className={clsx('col col--6', styles.authorCol)} key={idx}>
23
+ <BlogPostAuthor
24
+ author={{
25
+ ...author,
26
+ // Handle author images using relative paths
27
+ imageURL: assets.authorsImageUrls[idx] ?? author.imageURL,
28
+ }}
29
+ />
30
+ </div>
31
+ ))}
32
+ </div>
33
+ );
34
+ }
@@ -0,0 +1,11 @@
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
+ .authorCol {
9
+ max-width: inherit !important;
10
+ flex-grow: 1 !important;
11
+ }
@@ -9,11 +9,13 @@ import clsx from 'clsx';
9
9
  import {MDXProvider} from '@mdx-js/react';
10
10
  import Translate, {translate} from '@docusaurus/Translate';
11
11
  import Link from '@docusaurus/Link';
12
+ import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
12
13
  import {usePluralForm} from '@docusaurus/theme-common';
13
14
  import MDXComponents from '@theme/MDXComponents';
14
- import Seo from '@theme/Seo';
15
15
  import EditThisPage from '@theme/EditThisPage';
16
- import styles from './styles.module.css'; // Very simple pluralization: probably good enough for now
16
+ import styles from './styles.module.css';
17
+ import TagsListInline from '@theme/TagsListInline';
18
+ import BlogPostAuthors from '@theme/BlogPostAuthors'; // Very simple pluralization: probably good enough for now
17
19
 
18
20
  function useReadingTimePlural() {
19
21
  const {selectMessage} = usePluralForm();
@@ -38,9 +40,11 @@ function useReadingTimePlural() {
38
40
 
39
41
  function BlogPostItem(props) {
40
42
  const readingTimePlural = useReadingTimePlural();
43
+ const {withBaseUrl} = useBaseUrlUtils();
41
44
  const {
42
45
  children,
43
46
  frontMatter,
47
+ assets,
44
48
  metadata,
45
49
  truncated,
46
50
  isBlogPostPage = false,
@@ -53,115 +57,104 @@ function BlogPostItem(props) {
53
57
  readingTime,
54
58
  title,
55
59
  editUrl,
60
+ authors,
56
61
  } = metadata;
57
- const {author, image, keywords} = frontMatter;
58
- const authorURL = frontMatter.author_url || frontMatter.authorURL;
59
- const authorTitle = frontMatter.author_title || frontMatter.authorTitle;
60
- const authorImageURL =
61
- frontMatter.author_image_url || frontMatter.authorImageURL;
62
+ const image = assets.image ?? frontMatter.image;
63
+ const truncatedPost = !isBlogPostPage && truncated;
64
+ const tagsExists = tags.length > 0;
62
65
 
63
66
  const renderPostHeader = () => {
64
67
  const TitleHeading = isBlogPostPage ? 'h1' : 'h2';
65
68
  return (
66
69
  <header>
67
- <TitleHeading className={styles.blogPostTitle}>
68
- {isBlogPostPage ? title : <Link to={permalink}>{title}</Link>}
70
+ <TitleHeading className={styles.blogPostTitle} itemProp="headline">
71
+ {isBlogPostPage ? (
72
+ title
73
+ ) : (
74
+ <Link itemProp="url" to={permalink}>
75
+ {title}
76
+ </Link>
77
+ )}
69
78
  </TitleHeading>
70
79
  <div className={clsx(styles.blogPostData, 'margin-vert--md')}>
71
- <time dateTime={date}>{formattedDate}</time>
80
+ <time dateTime={date} itemProp="datePublished">
81
+ {formattedDate}
82
+ </time>
72
83
 
73
- {readingTime && (
84
+ {typeof readingTime !== 'undefined' && (
74
85
  <>
75
86
  {' · '}
76
87
  {readingTimePlural(readingTime)}
77
88
  </>
78
89
  )}
79
90
  </div>
80
- <div className="avatar margin-vert--md">
81
- {authorImageURL && (
82
- <Link className="avatar__photo-link avatar__photo" href={authorURL}>
83
- <img src={authorImageURL} alt={author} />
84
- </Link>
85
- )}
86
- <div className="avatar__intro">
87
- {author && (
88
- <>
89
- <div className="avatar__name">
90
- <Link href={authorURL}>{author}</Link>
91
- </div>
92
- <small className="avatar__subtitle">{authorTitle}</small>
93
- </>
94
- )}
95
- </div>
96
- </div>
91
+ <BlogPostAuthors authors={authors} assets={assets} />
97
92
  </header>
98
93
  );
99
94
  };
100
95
 
101
96
  return (
102
- <>
103
- <Seo
104
- {...{
105
- keywords,
106
- image,
107
- }}
108
- />
97
+ <article
98
+ className={!isBlogPostPage ? 'margin-bottom--xl' : undefined}
99
+ itemProp="blogPost"
100
+ itemScope
101
+ itemType="http://schema.org/BlogPosting">
102
+ {renderPostHeader()}
109
103
 
110
- <article className={!isBlogPostPage ? 'margin-bottom--xl' : undefined}>
111
- {renderPostHeader()}
112
- <div className="markdown">
113
- <MDXProvider components={MDXComponents}>{children}</MDXProvider>
114
- </div>
115
- {(tags.length > 0 || truncated) && (
116
- <footer
117
- className={clsx('row docusaurus-mt-lg', {
118
- [styles.blogPostDetailsFull]: isBlogPostPage,
119
- })}>
120
- {tags.length > 0 && (
121
- <div className="col">
104
+ {image && (
105
+ <meta
106
+ itemProp="image"
107
+ content={withBaseUrl(image, {
108
+ absolute: true,
109
+ })}
110
+ />
111
+ )}
112
+
113
+ <div className="markdown" itemProp="articleBody">
114
+ <MDXProvider components={MDXComponents}>{children}</MDXProvider>
115
+ </div>
116
+
117
+ {(tagsExists || truncated) && (
118
+ <footer
119
+ className={clsx('row docusaurus-mt-lg', {
120
+ [styles.blogPostDetailsFull]: isBlogPostPage,
121
+ })}>
122
+ {tagsExists && (
123
+ <div
124
+ className={clsx('col', {
125
+ 'col--9': truncatedPost,
126
+ })}>
127
+ <TagsListInline tags={tags} />
128
+ </div>
129
+ )}
130
+
131
+ {isBlogPostPage && editUrl && (
132
+ <div className="col margin-top--sm">
133
+ <EditThisPage editUrl={editUrl} />
134
+ </div>
135
+ )}
136
+
137
+ {truncatedPost && (
138
+ <div
139
+ className={clsx('col text--right', {
140
+ 'col--3': tagsExists,
141
+ })}>
142
+ <Link
143
+ to={metadata.permalink}
144
+ aria-label={`Read more about ${title}`}>
122
145
  <b>
123
146
  <Translate
124
- id="theme.tags.tagsListLabel"
125
- description="The label alongside a tag list">
126
- Tags:
147
+ id="theme.blog.post.readMore"
148
+ description="The label used in blog post item excerpts to link to full blog posts">
149
+ Read More
127
150
  </Translate>
128
151
  </b>
129
- {tags.map(({label, permalink: tagPermalink}) => (
130
- <Link
131
- key={tagPermalink}
132
- className="margin-horiz--sm"
133
- to={tagPermalink}>
134
- {label}
135
- </Link>
136
- ))}
137
- </div>
138
- )}
139
-
140
- {isBlogPostPage && editUrl && (
141
- <div className="col margin-top--sm">
142
- <EditThisPage editUrl={editUrl} />
143
- </div>
144
- )}
145
-
146
- {!isBlogPostPage && truncated && (
147
- <div className="col text--right">
148
- <Link
149
- to={metadata.permalink}
150
- aria-label={`Read more about ${title}`}>
151
- <b>
152
- <Translate
153
- id="theme.blog.post.readMore"
154
- description="The label used in blog post item excerpts to link to full blog posts">
155
- Read More
156
- </Translate>
157
- </b>
158
- </Link>
159
- </div>
160
- )}
161
- </footer>
162
- )}
163
- </article>
164
- </>
152
+ </Link>
153
+ </div>
154
+ )}
155
+ </footer>
156
+ )}
157
+ </article>
165
158
  );
166
159
  }
167
160
 
@@ -5,34 +5,81 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import React from 'react';
8
+ import Seo from '@theme/Seo';
8
9
  import BlogLayout from '@theme/BlogLayout';
9
10
  import BlogPostItem from '@theme/BlogPostItem';
10
11
  import BlogPostPaginator from '@theme/BlogPostPaginator';
11
12
  import {ThemeClassNames} from '@docusaurus/theme-common';
13
+ import TOC from '@theme/TOC';
12
14
 
13
15
  function BlogPostPage(props) {
14
16
  const {content: BlogPostContents, sidebar} = props;
15
- const {frontMatter, metadata} = BlogPostContents;
16
- const {title, description, nextItem, prevItem} = metadata;
17
- const {hide_table_of_contents: hideTableOfContents} = frontMatter;
17
+ const {
18
+ // TODO this frontmatter is not validated/normalized, it's the raw user-provided one. We should expose normalized one too!
19
+ frontMatter,
20
+ assets,
21
+ metadata,
22
+ } = BlogPostContents;
23
+ const {title, description, nextItem, prevItem, date, tags, authors} =
24
+ metadata;
25
+ const {
26
+ hide_table_of_contents: hideTableOfContents,
27
+ keywords,
28
+ toc_min_heading_level: tocMinHeadingLevel,
29
+ toc_max_heading_level: tocMaxHeadingLevel,
30
+ } = frontMatter;
31
+ const image = assets.image ?? frontMatter.image;
18
32
  return (
19
33
  <BlogLayout
20
- title={title}
21
- description={description}
22
34
  wrapperClassName={ThemeClassNames.wrapper.blogPages}
23
35
  pageClassName={ThemeClassNames.page.blogPostPage}
24
36
  sidebar={sidebar}
25
37
  toc={
26
- !hideTableOfContents && BlogPostContents.toc
27
- ? BlogPostContents.toc
28
- : undefined
38
+ !hideTableOfContents &&
39
+ BlogPostContents.toc &&
40
+ BlogPostContents.toc.length > 0 ? (
41
+ <TOC
42
+ toc={BlogPostContents.toc}
43
+ minHeadingLevel={tocMinHeadingLevel}
44
+ maxHeadingLevel={tocMaxHeadingLevel}
45
+ />
46
+ ) : undefined
29
47
  }>
48
+ <Seo // TODO refactor needed: it's a bit annoying but Seo MUST be inside BlogLayout
49
+ // otherwise default image (set by BlogLayout) would shadow the custom blog post image
50
+ title={title}
51
+ description={description}
52
+ keywords={keywords}
53
+ image={image}>
54
+ <meta property="og:type" content="article" />
55
+ <meta property="article:published_time" content={date} />
56
+
57
+ {/* TODO double check those article metas array syntaxes, see https://ogp.me/#array */}
58
+ {authors.some((author) => author.url) && (
59
+ <meta
60
+ property="article:author"
61
+ content={authors
62
+ .map((author) => author.url)
63
+ .filter(Boolean)
64
+ .join(',')}
65
+ />
66
+ )}
67
+ {tags.length > 0 && (
68
+ <meta
69
+ property="article:tag"
70
+ content={tags.map((tag) => tag.label).join(',')}
71
+ />
72
+ )}
73
+ </Seo>
74
+
30
75
  <BlogPostItem
31
76
  frontMatter={frontMatter}
77
+ assets={assets}
32
78
  metadata={metadata}
33
79
  isBlogPostPage>
34
80
  <BlogPostContents />
35
81
  </BlogPostItem>
82
+
36
83
  {(nextItem || prevItem) && (
37
84
  <BlogPostPaginator nextItem={nextItem} prevItem={prevItem} />
38
85
  )}
@@ -34,10 +34,10 @@
34
34
  text-decoration: none;
35
35
  }
36
36
  .sidebarItemLinkActive {
37
- color: var(--ifm-color-primary);
37
+ color: var(--ifm-color-primary) !important;
38
38
  }
39
39
 
40
- @media only screen and (max-width: 996px) {
40
+ @media (max-width: 996px) {
41
41
  .sidebar {
42
42
  display: none;
43
43
  }
@@ -5,48 +5,16 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import React from 'react';
8
- import Link from '@docusaurus/Link';
9
8
  import BlogLayout from '@theme/BlogLayout';
10
- import {translate} from '@docusaurus/Translate';
11
- import {ThemeClassNames} from '@docusaurus/theme-common';
12
-
13
- function getCategoryOfTag(tag) {
14
- // tag's category should be customizable
15
- return tag[0].toUpperCase();
16
- }
9
+ import TagsListByLetter from '@theme/TagsListByLetter';
10
+ import {
11
+ ThemeClassNames,
12
+ translateTagsPageTitle,
13
+ } from '@docusaurus/theme-common';
17
14
 
18
15
  function BlogTagsListPage(props) {
19
16
  const {tags, sidebar} = props;
20
- const title = translate({
21
- id: 'theme.tags.tagsPageTitle',
22
- message: 'Tags',
23
- description: 'The title of the tag list page',
24
- });
25
- const tagCategories = {};
26
- Object.keys(tags).forEach((tag) => {
27
- const category = getCategoryOfTag(tag);
28
- tagCategories[category] = tagCategories[category] || [];
29
- tagCategories[category].push(tag);
30
- });
31
- const tagsList = Object.entries(tagCategories).sort(([a], [b]) =>
32
- a.localeCompare(b),
33
- );
34
- const tagsSection = tagsList
35
- .map(([category, tagsForCategory]) => (
36
- <article key={category}>
37
- <h2>{category}</h2>
38
- {tagsForCategory.map((tag) => (
39
- <Link
40
- className="padding-right--md"
41
- href={tags[tag].permalink}
42
- key={tag}>
43
- {tags[tag].name} ({tags[tag].count})
44
- </Link>
45
- ))}
46
- <hr />
47
- </article>
48
- ))
49
- .filter((item) => item != null);
17
+ const title = translateTagsPageTitle();
50
18
  return (
51
19
  <BlogLayout
52
20
  title={title}
@@ -58,7 +26,7 @@ function BlogTagsListPage(props) {
58
26
  }}
59
27
  sidebar={sidebar}>
60
28
  <h1>{title}</h1>
61
- <section className="margin-vert--lg">{tagsSection}</section>
29
+ <TagsListByLetter tags={Object.values(tags)} />
62
30
  </BlogLayout>
63
31
  );
64
32
  }
@@ -30,7 +30,7 @@ function useBlogPostsPlural() {
30
30
  );
31
31
  }
32
32
 
33
- function BlogTagsPostPage(props) {
33
+ export default function BlogTagsPostsPage(props) {
34
34
  const {metadata, items, sidebar} = props;
35
35
  const {allTagsPath, name: tagName, count} = metadata;
36
36
  const blogPostsPlural = useBlogPostsPlural();
@@ -49,7 +49,7 @@ function BlogTagsPostPage(props) {
49
49
  <BlogLayout
50
50
  title={title}
51
51
  wrapperClassName={ThemeClassNames.wrapper.blogPages}
52
- pageClassName={ThemeClassNames.page.blogTagsPostPage}
52
+ pageClassName={ThemeClassNames.page.blogTagPostListPage}
53
53
  searchMetadatas={{
54
54
  // assign unique search tag to exclude this page from search results!
55
55
  tag: 'blog_tags_posts',
@@ -71,6 +71,7 @@ function BlogTagsPostPage(props) {
71
71
  <BlogPostItem
72
72
  key={BlogPostContent.metadata.permalink}
73
73
  frontMatter={BlogPostContent.frontMatter}
74
+ assets={BlogPostContent.assets}
74
75
  metadata={BlogPostContent.metadata}
75
76
  truncated>
76
77
  <BlogPostContent />
@@ -79,5 +80,3 @@ function BlogTagsPostPage(props) {
79
80
  </BlogLayout>
80
81
  );
81
82
  }
82
-
83
- export default BlogTagsPostPage;
@@ -13,46 +13,45 @@ import usePrismTheme from '@theme/hooks/usePrismTheme';
13
13
  import Translate, {translate} from '@docusaurus/Translate';
14
14
  import styles from './styles.module.css';
15
15
  import {useThemeConfig, parseCodeBlockTitle} from '@docusaurus/theme-common';
16
- const highlightLinesRangeRegex = /{([\d,-]+)}/;
17
-
18
- const getHighlightDirectiveRegex = (
19
- languages = ['js', 'jsBlock', 'jsx', 'python', 'html'],
20
- ) => {
21
- // supported types of comments
22
- const comments = {
23
- js: {
24
- start: '\\/\\/',
25
- end: '',
26
- },
27
- jsBlock: {
28
- start: '\\/\\*',
29
- end: '\\*\\/',
30
- },
31
- jsx: {
32
- start: '\\{\\s*\\/\\*',
33
- end: '\\*\\/\\s*\\}',
34
- },
35
- python: {
36
- start: '#',
37
- end: '',
38
- },
39
- html: {
40
- start: '<!--',
41
- end: '-->',
42
- },
43
- }; // supported directives
44
-
45
- const directives = [
46
- 'highlight-next-line',
47
- 'highlight-start',
48
- 'highlight-end',
49
- ].join('|'); // to be more reliable, the opening and closing comment must match
50
-
16
+ const HighlightLinesRangeRegex = /{([\d,-]+)}/;
17
+ const HighlightLanguages = ['js', 'jsBlock', 'jsx', 'python', 'html'];
18
+ // Supported types of highlight comments
19
+ const HighlightComments = {
20
+ js: {
21
+ start: '\\/\\/',
22
+ end: '',
23
+ },
24
+ jsBlock: {
25
+ start: '\\/\\*',
26
+ end: '\\*\\/',
27
+ },
28
+ jsx: {
29
+ start: '\\{\\s*\\/\\*',
30
+ end: '\\*\\/\\s*\\}',
31
+ },
32
+ python: {
33
+ start: '#',
34
+ end: '',
35
+ },
36
+ html: {
37
+ start: '<!--',
38
+ end: '-->',
39
+ },
40
+ }; // Supported highlight directives
41
+
42
+ const HighlightDirectives = [
43
+ 'highlight-next-line',
44
+ 'highlight-start',
45
+ 'highlight-end',
46
+ ];
47
+
48
+ const getHighlightDirectiveRegex = (languages = HighlightLanguages) => {
49
+ // to be more reliable, the opening and closing comment must match
51
50
  const commentPattern = languages
52
- .map(
53
- (lang) =>
54
- `(?:${comments[lang].start}\\s*(${directives})\\s*${comments[lang].end})`,
55
- )
51
+ .map((lang) => {
52
+ const {start, end} = HighlightComments[lang];
53
+ return `(?:${start}\\s*(${HighlightDirectives.join('|')})\\s*${end})`;
54
+ })
56
55
  .join('|'); // white space is allowed, but otherwise it should be on it's own line
57
56
 
58
57
  return new RegExp(`^\\s*(?:${commentPattern})\\s*$`);
@@ -85,7 +84,7 @@ const highlightDirectiveRegex = (lang) => {
85
84
 
86
85
  export default function CodeBlock({
87
86
  children,
88
- className: languageClassName,
87
+ className: blockClassName,
89
88
  metastring,
90
89
  title,
91
90
  }) {
@@ -112,16 +111,16 @@ export default function CodeBlock({
112
111
 
113
112
  const content = Array.isArray(children) ? children.join('') : children;
114
113
 
115
- if (metastring && highlightLinesRangeRegex.test(metastring)) {
114
+ if (metastring && HighlightLinesRangeRegex.test(metastring)) {
116
115
  // Tested above
117
- const highlightLinesRange = metastring.match(highlightLinesRangeRegex)[1];
116
+ const highlightLinesRange = metastring.match(HighlightLinesRangeRegex)[1];
118
117
  highlightLines = rangeParser(highlightLinesRange).filter((n) => n > 0);
119
118
  }
120
119
 
121
- let language =
122
- languageClassName && // Force Prism's language union type to `any` because it does not contain all available languages
123
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
124
- languageClassName.replace(/language-/, '');
120
+ const languageClassName = blockClassName
121
+ ?.split(' ')
122
+ .find((str) => str.startsWith('language-'));
123
+ let language = languageClassName?.replace(/language-/, '');
125
124
 
126
125
  if (!language && prism.defaultLanguage) {
127
126
  language = prism.defaultLanguage;
@@ -189,7 +188,11 @@ export default function CodeBlock({
189
188
  code={code}
190
189
  language={language}>
191
190
  {({className, style, tokens, getLineProps, getTokenProps}) => (
192
- <div className={styles.codeBlockContainer}>
191
+ <div
192
+ className={clsx(
193
+ styles.codeBlockContainer,
194
+ blockClassName?.replace(/language-[^ ]+/, ''),
195
+ )}>
193
196
  {codeBlockTitle && (
194
197
  <div style={style} className={styles.codeBlockTitle}>
195
198
  {codeBlockTitle}
@@ -203,8 +206,8 @@ export default function CodeBlock({
203
206
  style={style}>
204
207
  <code className={styles.codeBlockLines}>
205
208
  {tokens.map((line, i) => {
206
- if (line.length === 1 && line[0].content === '') {
207
- line[0].content = '\n'; // eslint-disable-line no-param-reassign
209
+ if (line.length === 1 && line[0].content === '\n') {
210
+ line[0].content = '';
208
211
  }
209
212
 
210
213
  const lineProps = getLineProps({
@@ -227,6 +230,7 @@ export default function CodeBlock({
227
230
  })}
228
231
  />
229
232
  ))}
233
+ <br />
230
234
  </span>
231
235
  );
232
236
  })}
@@ -52,11 +52,10 @@
52
52
 
53
53
  .codeBlockLines {
54
54
  font: inherit;
55
+ /*rtl:ignore*/
55
56
  float: left;
56
57
  min-width: 100%;
57
58
  padding: var(--ifm-pre-padding);
58
- display: flex;
59
- flex-direction: column;
60
59
  }
61
60
 
62
61
  @media print {