@docusaurus/theme-classic 0.0.0-5179 → 0.0.0-5184

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 (53) hide show
  1. package/lib/theme/BlogListPage/index.js +2 -11
  2. package/lib/theme/BlogPostItem/Container/index.d.ts +9 -0
  3. package/lib/theme/BlogPostItem/Container/index.js +26 -0
  4. package/lib/theme/BlogPostItem/Content/index.d.ts +9 -0
  5. package/lib/theme/BlogPostItem/Content/index.js +23 -0
  6. package/lib/theme/BlogPostItem/Footer/ReadMoreLink/index.d.ts +9 -0
  7. package/lib/theme/BlogPostItem/Footer/ReadMoreLink/index.js +38 -0
  8. package/lib/theme/{BlogPostAuthor → BlogPostItem/Footer}/index.d.ts +1 -2
  9. package/lib/theme/BlogPostItem/Footer/index.js +52 -0
  10. package/lib/theme/BlogPostItem/Footer/styles.module.css +10 -0
  11. package/lib/theme/BlogPostItem/Header/Author/index.d.ts +9 -0
  12. package/lib/theme/{BlogPostAuthor → BlogPostItem/Header/Author}/index.js +3 -2
  13. package/lib/theme/BlogPostItem/Header/Authors/index.d.ts +9 -0
  14. package/{src/theme/BlogPostAuthors/index.tsx → lib/theme/BlogPostItem/Header/Authors/index.js} +9 -10
  15. package/lib/theme/{BlogPostAuthors → BlogPostItem/Header/Authors}/styles.module.css +0 -0
  16. package/lib/theme/BlogPostItem/Header/Info/index.d.ts +9 -0
  17. package/lib/theme/BlogPostItem/Header/Info/index.js +60 -0
  18. package/lib/theme/BlogPostItem/Header/Info/styles.module.css +10 -0
  19. package/lib/theme/BlogPostItem/Header/Title/index.d.ts +9 -0
  20. package/lib/theme/BlogPostItem/Header/Title/index.js +27 -0
  21. package/{src/theme/BlogPostItem → lib/theme/BlogPostItem/Header/Title}/styles.module.css +2 -10
  22. package/lib/theme/{BlogPostAuthors → BlogPostItem/Header}/index.d.ts +1 -2
  23. package/lib/theme/BlogPostItem/Header/index.js +19 -0
  24. package/lib/theme/BlogPostItem/index.d.ts +1 -1
  25. package/lib/theme/BlogPostItem/index.js +16 -142
  26. package/lib/theme/BlogPostItems/index.d.ts +9 -0
  27. package/lib/theme/BlogPostItems/index.js +27 -0
  28. package/lib/theme/BlogPostPage/Metadata/index.d.ts +8 -0
  29. package/lib/theme/BlogPostPage/Metadata/index.js +41 -0
  30. package/lib/theme/BlogPostPage/index.js +21 -58
  31. package/lib/theme/BlogTagsPostsPage/index.d.ts +1 -1
  32. package/lib/theme/BlogTagsPostsPage/index.js +36 -30
  33. package/package.json +14 -14
  34. package/src/theme/BlogListPage/index.tsx +2 -11
  35. package/src/theme/BlogPostItem/Container/index.tsx +32 -0
  36. package/src/theme/BlogPostItem/Content/index.tsx +29 -0
  37. package/src/theme/BlogPostItem/Footer/ReadMoreLink/index.tsx +44 -0
  38. package/src/theme/BlogPostItem/Footer/index.tsx +60 -0
  39. package/src/theme/BlogPostItem/Footer/styles.module.css +10 -0
  40. package/src/theme/{BlogPostAuthor → BlogPostItem/Header/Author}/index.tsx +8 -3
  41. package/{lib/theme/BlogPostAuthors/index.js → src/theme/BlogPostItem/Header/Authors/index.tsx} +14 -3
  42. package/src/theme/{BlogPostAuthors → BlogPostItem/Header/Authors}/styles.module.css +0 -0
  43. package/src/theme/BlogPostItem/Header/Info/index.tsx +71 -0
  44. package/src/theme/BlogPostItem/Header/Info/styles.module.css +10 -0
  45. package/src/theme/BlogPostItem/Header/Title/index.tsx +33 -0
  46. package/{lib/theme/BlogPostItem → src/theme/BlogPostItem/Header/Title}/styles.module.css +2 -10
  47. package/src/theme/BlogPostItem/Header/index.tsx +21 -0
  48. package/src/theme/BlogPostItem/index.tsx +19 -145
  49. package/src/theme/BlogPostItems/index.tsx +30 -0
  50. package/src/theme/BlogPostPage/Metadata/index.tsx +44 -0
  51. package/src/theme/BlogPostPage/index.tsx +29 -60
  52. package/src/theme/BlogTagsPostsPage/index.tsx +42 -35
  53. package/src/theme-classic.d.ts +80 -18
@@ -13,9 +13,9 @@ import {
13
13
  ThemeClassNames,
14
14
  } from '@docusaurus/theme-common';
15
15
  import BlogLayout from '@theme/BlogLayout';
16
- import BlogPostItem from '@theme/BlogPostItem';
17
16
  import BlogListPaginator from '@theme/BlogListPaginator';
18
17
  import SearchMetadata from '@theme/SearchMetadata';
18
+ import BlogPostItems from '@theme/BlogPostItems';
19
19
  function BlogListPageMetadata(props) {
20
20
  const {metadata} = props;
21
21
  const {
@@ -35,16 +35,7 @@ function BlogListPageContent(props) {
35
35
  const {metadata, items, sidebar} = props;
36
36
  return (
37
37
  <BlogLayout sidebar={sidebar}>
38
- {items.map(({content: BlogPostContent}) => (
39
- <BlogPostItem
40
- key={BlogPostContent.metadata.permalink}
41
- frontMatter={BlogPostContent.frontMatter}
42
- assets={BlogPostContent.assets}
43
- metadata={BlogPostContent.metadata}
44
- truncated={BlogPostContent.metadata.truncated}>
45
- <BlogPostContent />
46
- </BlogPostItem>
47
- ))}
38
+ <BlogPostItems items={items} />
48
39
  <BlogListPaginator metadata={metadata} />
49
40
  </BlogLayout>
50
41
  );
@@ -0,0 +1,9 @@
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
+ /// <reference types="react" />
8
+ import type { Props } from '@theme/BlogPostItem/Container';
9
+ export default function BlogPostItemContainer({ children, className, }: Props): JSX.Element;
@@ -0,0 +1,26 @@
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 {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
9
+ import {useBlogPost} from '@docusaurus/theme-common/internal';
10
+ export default function BlogPostItemContainer({children, className}) {
11
+ const {frontMatter, assets} = useBlogPost();
12
+ const {withBaseUrl} = useBaseUrlUtils();
13
+ const image = assets.image ?? frontMatter.image;
14
+ return (
15
+ <article
16
+ className={className}
17
+ itemProp="blogPost"
18
+ itemScope
19
+ itemType="http://schema.org/BlogPosting">
20
+ {image && (
21
+ <meta itemProp="image" content={withBaseUrl(image, {absolute: true})} />
22
+ )}
23
+ {children}
24
+ </article>
25
+ );
26
+ }
@@ -0,0 +1,9 @@
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
+ /// <reference types="react" />
8
+ import type { Props } from '@theme/BlogPostItem/Content';
9
+ export default function BlogPostItemContent({ children, className, }: Props): JSX.Element;
@@ -0,0 +1,23 @@
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 {blogPostContainerID} from '@docusaurus/utils-common';
10
+ import {useBlogPost} from '@docusaurus/theme-common/internal';
11
+ import MDXContent from '@theme/MDXContent';
12
+ export default function BlogPostItemContent({children, className}) {
13
+ const {isBlogPostPage} = useBlogPost();
14
+ return (
15
+ <div
16
+ // This ID is used for the feed generation to locate the main content
17
+ id={isBlogPostPage ? blogPostContainerID : undefined}
18
+ className={clsx('markdown', className)}
19
+ itemProp="articleBody">
20
+ <MDXContent>{children}</MDXContent>
21
+ </div>
22
+ );
23
+ }
@@ -0,0 +1,9 @@
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
+ /// <reference types="react" />
8
+ import type { Props } from '@theme/BlogPostItem/Footer/ReadMoreLink';
9
+ export default function BlogPostItemFooterReadMoreLink(props: Props): JSX.Element;
@@ -0,0 +1,38 @@
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 Translate, {translate} from '@docusaurus/Translate';
9
+ import Link from '@docusaurus/Link';
10
+ function ReadMoreLabel() {
11
+ return (
12
+ <b>
13
+ <Translate
14
+ id="theme.blog.post.readMore"
15
+ description="The label used in blog post item excerpts to link to full blog posts">
16
+ Read More
17
+ </Translate>
18
+ </b>
19
+ );
20
+ }
21
+ export default function BlogPostItemFooterReadMoreLink(props) {
22
+ const {blogPostTitle, ...linkProps} = props;
23
+ return (
24
+ <Link
25
+ aria-label={translate(
26
+ {
27
+ message: 'Read more about {title}',
28
+ id: 'theme.blog.post.readMoreLabel',
29
+ description:
30
+ 'The ARIA label for the link to full blog posts from excerpts',
31
+ },
32
+ {title: blogPostTitle},
33
+ )}
34
+ {...linkProps}>
35
+ <ReadMoreLabel />
36
+ </Link>
37
+ );
38
+ }
@@ -5,5 +5,4 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  /// <reference types="react" />
8
- import type { Props } from '@theme/BlogPostAuthor';
9
- export default function BlogPostAuthor({ author }: Props): JSX.Element;
8
+ export default function BlogPostItemFooter(): JSX.Element | null;
@@ -0,0 +1,52 @@
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 {useBlogPost} from '@docusaurus/theme-common/internal';
10
+ import EditThisPage from '@theme/EditThisPage';
11
+ import TagsListInline from '@theme/TagsListInline';
12
+ import ReadMoreLink from '@theme/BlogPostItem/Footer/ReadMoreLink';
13
+ import styles from './styles.module.css';
14
+ export default function BlogPostItemFooter() {
15
+ const {metadata, isBlogPostPage} = useBlogPost();
16
+ const {tags, title, editUrl, hasTruncateMarker} = metadata;
17
+ // A post is truncated if it's in the "list view" and it has a truncate marker
18
+ const truncatedPost = !isBlogPostPage && hasTruncateMarker;
19
+ const tagsExists = tags.length > 0;
20
+ const renderFooter = tagsExists || truncatedPost || editUrl;
21
+ if (!renderFooter) {
22
+ return null;
23
+ }
24
+ return (
25
+ <footer
26
+ className={clsx(
27
+ 'row docusaurus-mt-lg',
28
+ isBlogPostPage && styles.blogPostFooterDetailsFull,
29
+ )}>
30
+ {tagsExists && (
31
+ <div className={clsx('col', {'col--9': truncatedPost})}>
32
+ <TagsListInline tags={tags} />
33
+ </div>
34
+ )}
35
+
36
+ {isBlogPostPage && editUrl && (
37
+ <div className="col margin-top--sm">
38
+ <EditThisPage editUrl={editUrl} />
39
+ </div>
40
+ )}
41
+
42
+ {truncatedPost && (
43
+ <div
44
+ className={clsx('col text--right', {
45
+ 'col--3': tagsExists,
46
+ })}>
47
+ <ReadMoreLink blogPostTitle={title} to={metadata.permalink} />
48
+ </div>
49
+ )}
50
+ </footer>
51
+ );
52
+ }
@@ -0,0 +1,10 @@
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
+ .blogPostFooterDetailsFull {
9
+ flex-direction: column;
10
+ }
@@ -0,0 +1,9 @@
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
+ /// <reference types="react" />
8
+ import type { Props } from '@theme/BlogPostItem/Header/Author';
9
+ export default function BlogPostItemHeaderAuthor({ author, className, }: Props): JSX.Element;
@@ -5,6 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import React from 'react';
8
+ import clsx from 'clsx';
8
9
  import Link from '@docusaurus/Link';
9
10
  function MaybeLink(props) {
10
11
  if (props.href) {
@@ -12,11 +13,11 @@ function MaybeLink(props) {
12
13
  }
13
14
  return <>{props.children}</>;
14
15
  }
15
- export default function BlogPostAuthor({author}) {
16
+ export default function BlogPostItemHeaderAuthor({author, className}) {
16
17
  const {name, title, url, imageURL, email} = author;
17
18
  const link = url || (email && `mailto:${email}`) || undefined;
18
19
  return (
19
- <div className="avatar margin-bottom--sm">
20
+ <div className={clsx('avatar margin-bottom--sm', className)}>
20
21
  {imageURL && (
21
22
  <MaybeLink href={link} className="avatar__photo-link">
22
23
  <img className="avatar__photo" src={imageURL} alt={name} />
@@ -0,0 +1,9 @@
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
+ /// <reference types="react" />
8
+ import type { Props } from '@theme/BlogPostItem/Header/Authors';
9
+ export default function BlogPostItemHeaderAuthors({ className, }: Props): JSX.Element | null;
@@ -4,19 +4,17 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
-
8
7
  import React from 'react';
9
8
  import clsx from 'clsx';
10
- import BlogPostAuthor from '@theme/BlogPostAuthor';
11
- import type {Props} from '@theme/BlogPostAuthors';
12
-
9
+ import {useBlogPost} from '@docusaurus/theme-common/internal';
10
+ import BlogPostItemHeaderAuthor from '@theme/BlogPostItem/Header/Author';
13
11
  import styles from './styles.module.css';
14
-
15
12
  // Component responsible for the authors layout
16
- export default function BlogPostAuthors({
17
- authors,
18
- assets,
19
- }: Props): JSX.Element | null {
13
+ export default function BlogPostItemHeaderAuthors({className}) {
14
+ const {
15
+ metadata: {authors},
16
+ assets,
17
+ } = useBlogPost();
20
18
  const authorsCount = authors.length;
21
19
  if (authorsCount === 0) {
22
20
  return null;
@@ -27,6 +25,7 @@ export default function BlogPostAuthors({
27
25
  className={clsx(
28
26
  'margin-top--md margin-bottom--sm',
29
27
  imageOnly ? styles.imageOnlyAuthorRow : 'row',
28
+ className,
30
29
  )}>
31
30
  {authors.map((author, idx) => (
32
31
  <div
@@ -35,7 +34,7 @@ export default function BlogPostAuthors({
35
34
  imageOnly ? styles.imageOnlyAuthorCol : styles.authorCol,
36
35
  )}
37
36
  key={idx}>
38
- <BlogPostAuthor
37
+ <BlogPostItemHeaderAuthor
39
38
  author={{
40
39
  ...author,
41
40
  // Handle author images using relative paths
@@ -0,0 +1,9 @@
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
+ /// <reference types="react" />
8
+ import type { Props } from '@theme/BlogPostItem/Header/Info';
9
+ export default function BlogPostItemHeaderInfo({ className, }: Props): JSX.Element;
@@ -0,0 +1,60 @@
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 {translate} from '@docusaurus/Translate';
10
+ import {usePluralForm} from '@docusaurus/theme-common';
11
+ import {useBlogPost} from '@docusaurus/theme-common/internal';
12
+ import styles from './styles.module.css';
13
+ // Very simple pluralization: probably good enough for now
14
+ function useReadingTimePlural() {
15
+ const {selectMessage} = usePluralForm();
16
+ return (readingTimeFloat) => {
17
+ const readingTime = Math.ceil(readingTimeFloat);
18
+ return selectMessage(
19
+ readingTime,
20
+ translate(
21
+ {
22
+ id: 'theme.blog.post.readingTime.plurals',
23
+ description:
24
+ 'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',
25
+ message: 'One min read|{readingTime} min read',
26
+ },
27
+ {readingTime},
28
+ ),
29
+ );
30
+ };
31
+ }
32
+ function ReadingTime({readingTime}) {
33
+ const readingTimePlural = useReadingTimePlural();
34
+ return <>{readingTimePlural(readingTime)}</>;
35
+ }
36
+ function Date({date, formattedDate}) {
37
+ return (
38
+ <time dateTime={date} itemProp="datePublished">
39
+ {formattedDate}
40
+ </time>
41
+ );
42
+ }
43
+ function Spacer() {
44
+ return <>{' · '}</>;
45
+ }
46
+ export default function BlogPostItemHeaderInfo({className}) {
47
+ const {metadata} = useBlogPost();
48
+ const {date, formattedDate, readingTime} = metadata;
49
+ return (
50
+ <div className={clsx(styles.container, 'margin-vert--md', className)}>
51
+ <Date date={date} formattedDate={formattedDate} />
52
+ {typeof readingTime !== 'undefined' && (
53
+ <>
54
+ <Spacer />
55
+ <ReadingTime readingTime={readingTime} />
56
+ </>
57
+ )}
58
+ </div>
59
+ );
60
+ }
@@ -0,0 +1,10 @@
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
+ .container {
9
+ font-size: 0.9rem;
10
+ }
@@ -0,0 +1,9 @@
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
+ /// <reference types="react" />
8
+ import type { Props } from '@theme/BlogPostItem/Header/Title';
9
+ export default function BlogPostItemHeaderTitle({ className, }: Props): JSX.Element;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import React from 'react';
8
+ import clsx from 'clsx';
9
+ import Link from '@docusaurus/Link';
10
+ import {useBlogPost} from '@docusaurus/theme-common/internal';
11
+ import styles from './styles.module.css';
12
+ export default function BlogPostItemHeaderTitle({className}) {
13
+ const {metadata, isBlogPostPage} = useBlogPost();
14
+ const {permalink, title} = metadata;
15
+ const TitleHeading = isBlogPostPage ? 'h1' : 'h2';
16
+ return (
17
+ <TitleHeading className={clsx(styles.title, className)} itemProp="headline">
18
+ {isBlogPostPage ? (
19
+ title
20
+ ) : (
21
+ <Link itemProp="url" to={permalink}>
22
+ {title}
23
+ </Link>
24
+ )}
25
+ </TitleHeading>
26
+ );
27
+ }
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- .blogPostTitle {
8
+ .title {
9
9
  font-size: 3rem;
10
10
  }
11
11
 
@@ -13,15 +13,7 @@
13
13
  Blog post title should be smaller on smaller devices
14
14
  **/
15
15
  @media (max-width: 576px) {
16
- .blogPostTitle {
16
+ .title {
17
17
  font-size: 2rem;
18
18
  }
19
19
  }
20
-
21
- .blogPostData {
22
- font-size: 0.9rem;
23
- }
24
-
25
- .blogPostDetailsFull {
26
- flex-direction: column;
27
- }
@@ -5,5 +5,4 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  /// <reference types="react" />
8
- import type { Props } from '@theme/BlogPostAuthors';
9
- export default function BlogPostAuthors({ authors, assets, }: Props): JSX.Element | null;
8
+ export default function BlogPostItemHeader(): JSX.Element;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import React from 'react';
8
+ import BlogPostItemHeaderTitle from '@theme/BlogPostItem/Header/Title';
9
+ import BlogPostItemHeaderInfo from '@theme/BlogPostItem/Header/Info';
10
+ import BlogPostItemHeaderAuthors from '@theme/BlogPostItem/Header/Authors';
11
+ export default function BlogPostItemHeader() {
12
+ return (
13
+ <header>
14
+ <BlogPostItemHeaderTitle />
15
+ <BlogPostItemHeaderInfo />
16
+ <BlogPostItemHeaderAuthors />
17
+ </header>
18
+ );
19
+ }
@@ -6,4 +6,4 @@
6
6
  */
7
7
  /// <reference types="react" />
8
8
  import type { Props } from '@theme/BlogPostItem';
9
- export default function BlogPostItem(props: Props): JSX.Element;
9
+ export default function BlogPostItem({ children, className, }: Props): JSX.Element;
@@ -6,149 +6,23 @@
6
6
  */
7
7
  import React from 'react';
8
8
  import clsx from 'clsx';
9
- import Translate, {translate} from '@docusaurus/Translate';
10
- import Link from '@docusaurus/Link';
11
- import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
12
- import {usePluralForm} from '@docusaurus/theme-common';
13
- import {blogPostContainerID} from '@docusaurus/utils-common';
14
- import MDXContent from '@theme/MDXContent';
15
- import EditThisPage from '@theme/EditThisPage';
16
- import TagsListInline from '@theme/TagsListInline';
17
- import BlogPostAuthors from '@theme/BlogPostAuthors';
18
- import styles from './styles.module.css';
19
- // Very simple pluralization: probably good enough for now
20
- function useReadingTimePlural() {
21
- const {selectMessage} = usePluralForm();
22
- return (readingTimeFloat) => {
23
- const readingTime = Math.ceil(readingTimeFloat);
24
- return selectMessage(
25
- readingTime,
26
- translate(
27
- {
28
- id: 'theme.blog.post.readingTime.plurals',
29
- description:
30
- 'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',
31
- message: 'One min read|{readingTime} min read',
32
- },
33
- {readingTime},
34
- ),
35
- );
36
- };
9
+ import {useBlogPost} from '@docusaurus/theme-common/internal';
10
+ import BlogPostItemContainer from '@theme/BlogPostItem/Container';
11
+ import BlogPostItemHeader from '@theme/BlogPostItem/Header';
12
+ import BlogPostItemContent from '@theme/BlogPostItem/Content';
13
+ import BlogPostItemFooter from '@theme/BlogPostItem/Footer';
14
+ // apply a bottom margin in list view
15
+ function useContainerClassName() {
16
+ const {isBlogPostPage} = useBlogPost();
17
+ return !isBlogPostPage ? 'margin-bottom--xl' : undefined;
37
18
  }
38
- export default function BlogPostItem(props) {
39
- const readingTimePlural = useReadingTimePlural();
40
- const {withBaseUrl} = useBaseUrlUtils();
41
- const {
42
- children,
43
- frontMatter,
44
- assets,
45
- metadata,
46
- truncated,
47
- isBlogPostPage = false,
48
- } = props;
49
- const {
50
- date,
51
- formattedDate,
52
- permalink,
53
- tags,
54
- readingTime,
55
- title,
56
- editUrl,
57
- authors,
58
- } = metadata;
59
- const image = assets.image ?? frontMatter.image;
60
- const truncatedPost = !isBlogPostPage && truncated;
61
- const tagsExists = tags.length > 0;
62
- const TitleHeading = isBlogPostPage ? 'h1' : 'h2';
19
+ export default function BlogPostItem({children, className}) {
20
+ const containerClassName = useContainerClassName();
63
21
  return (
64
- <article
65
- className={!isBlogPostPage ? 'margin-bottom--xl' : undefined}
66
- itemProp="blogPost"
67
- itemScope
68
- itemType="http://schema.org/BlogPosting">
69
- <header>
70
- <TitleHeading className={styles.blogPostTitle} itemProp="headline">
71
- {isBlogPostPage ? (
72
- title
73
- ) : (
74
- <Link itemProp="url" to={permalink}>
75
- {title}
76
- </Link>
77
- )}
78
- </TitleHeading>
79
- <div className={clsx(styles.blogPostData, 'margin-vert--md')}>
80
- <time dateTime={date} itemProp="datePublished">
81
- {formattedDate}
82
- </time>
83
-
84
- {typeof readingTime !== 'undefined' && (
85
- <>
86
- {' · '}
87
- {readingTimePlural(readingTime)}
88
- </>
89
- )}
90
- </div>
91
- <BlogPostAuthors authors={authors} assets={assets} />
92
- </header>
93
-
94
- {image && (
95
- <meta itemProp="image" content={withBaseUrl(image, {absolute: true})} />
96
- )}
97
-
98
- <div
99
- // This ID is used for the feed generation to locate the main content
100
- id={isBlogPostPage ? blogPostContainerID : undefined}
101
- className="markdown"
102
- itemProp="articleBody">
103
- <MDXContent>{children}</MDXContent>
104
- </div>
105
-
106
- {(tagsExists || truncated || editUrl) && (
107
- <footer
108
- className={clsx(
109
- 'row docusaurus-mt-lg',
110
- isBlogPostPage && styles.blogPostDetailsFull,
111
- )}>
112
- {tagsExists && (
113
- <div className={clsx('col', {'col--9': truncatedPost})}>
114
- <TagsListInline tags={tags} />
115
- </div>
116
- )}
117
-
118
- {isBlogPostPage && editUrl && (
119
- <div className="col margin-top--sm">
120
- <EditThisPage editUrl={editUrl} />
121
- </div>
122
- )}
123
-
124
- {truncatedPost && (
125
- <div
126
- className={clsx('col text--right', {
127
- 'col--3': tagsExists,
128
- })}>
129
- <Link
130
- to={metadata.permalink}
131
- aria-label={translate(
132
- {
133
- message: 'Read more about {title}',
134
- id: 'theme.blog.post.readMoreLabel',
135
- description:
136
- 'The ARIA label for the link to full blog posts from excerpts',
137
- },
138
- {title},
139
- )}>
140
- <b>
141
- <Translate
142
- id="theme.blog.post.readMore"
143
- description="The label used in blog post item excerpts to link to full blog posts">
144
- Read More
145
- </Translate>
146
- </b>
147
- </Link>
148
- </div>
149
- )}
150
- </footer>
151
- )}
152
- </article>
22
+ <BlogPostItemContainer className={clsx(containerClassName, className)}>
23
+ <BlogPostItemHeader />
24
+ <BlogPostItemContent>{children}</BlogPostItemContent>
25
+ <BlogPostItemFooter />
26
+ </BlogPostItemContainer>
153
27
  );
154
28
  }