@docusaurus/theme-classic 0.0.0-6010 → 0.0.0-6014

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 (30) hide show
  1. package/lib/getSwizzleConfig.js +21 -0
  2. package/lib/theme/{BlogPostItem/Header → Blog/Components}/Author/Socials/index.d.ts +3 -4
  3. package/lib/theme/{BlogPostItem/Header → Blog/Components}/Author/Socials/index.js +3 -2
  4. package/lib/theme/{BlogPostItem/Header → Blog/Components}/Author/Socials/styles.module.css +7 -2
  5. package/lib/theme/{BlogPostItem/Header → Blog/Components}/Author/index.d.ts +2 -2
  6. package/lib/theme/Blog/Components/Author/index.js +86 -0
  7. package/lib/theme/Blog/Components/Author/styles.module.css +74 -0
  8. package/lib/theme/Blog/Pages/BlogAuthorsListPage/index.d.ts +9 -0
  9. package/lib/theme/Blog/Pages/BlogAuthorsListPage/index.js +54 -0
  10. package/lib/theme/Blog/Pages/BlogAuthorsListPage/styles.module.css +11 -0
  11. package/lib/theme/Blog/Pages/BlogAuthorsPostsPage/index.d.ts +8 -0
  12. package/lib/theme/Blog/Pages/BlogAuthorsPostsPage/index.js +67 -0
  13. package/lib/theme/BlogPostItem/Header/Authors/index.js +2 -3
  14. package/lib/theme/BlogTagsPostsPage/index.js +2 -30
  15. package/package.json +14 -14
  16. package/src/getSwizzleConfig.ts +21 -0
  17. package/src/theme/{BlogPostItem/Header → Blog/Components}/Author/Socials/index.tsx +8 -3
  18. package/src/theme/{BlogPostItem/Header → Blog/Components}/Author/Socials/styles.module.css +7 -2
  19. package/src/theme/Blog/Components/Author/index.tsx +99 -0
  20. package/src/theme/Blog/Components/Author/styles.module.css +74 -0
  21. package/src/theme/Blog/Pages/BlogAuthorsListPage/index.tsx +62 -0
  22. package/src/theme/Blog/Pages/BlogAuthorsListPage/styles.module.css +11 -0
  23. package/src/theme/Blog/Pages/BlogAuthorsPostsPage/index.tsx +73 -0
  24. package/src/theme/BlogPostItem/Header/Authors/index.tsx +2 -3
  25. package/src/theme/BlogTagsPostsPage/index.tsx +2 -32
  26. package/src/theme-classic.d.ts +24 -25
  27. package/lib/theme/BlogPostItem/Header/Author/index.js +0 -54
  28. package/lib/theme/BlogPostItem/Header/Author/styles.module.css +0 -21
  29. package/src/theme/BlogPostItem/Header/Author/index.tsx +0 -62
  30. package/src/theme/BlogPostItem/Header/Author/styles.module.css +0 -21
@@ -117,6 +117,27 @@ function getSwizzleConfig() {
117
117
  },
118
118
  description: 'The object mapping admonition type to a React component.\nUse it to add custom admonition type components, or replace existing ones.\nCan be ejected or wrapped (only manually, see our documentation).',
119
119
  },
120
+ Blog: {
121
+ actions: {
122
+ // Forbidden because it's a parent folder, makes the CLI crash atm
123
+ eject: 'forbidden',
124
+ wrap: 'forbidden',
125
+ },
126
+ },
127
+ 'Blog/Components': {
128
+ actions: {
129
+ // Forbidden because it's a parent folder, makes the CLI crash atm
130
+ eject: 'forbidden',
131
+ wrap: 'forbidden',
132
+ },
133
+ },
134
+ 'Blog/Pages': {
135
+ actions: {
136
+ // Forbidden because it's a parent folder, makes the CLI crash atm
137
+ eject: 'forbidden',
138
+ wrap: 'forbidden',
139
+ },
140
+ },
120
141
  CodeBlock: {
121
142
  actions: {
122
143
  eject: 'safe',
@@ -4,8 +4,7 @@
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
- import React from 'react';
8
- import type { Props } from '@theme/BlogPostItem/Header/Author/Socials';
9
- export default function AuthorSocials({ author }: {
7
+ import type { Props } from '@theme/Blog/Components/Author/Socials';
8
+ export default function BlogAuthorSocials({ author, }: {
10
9
  author: Props['author'];
11
- }): React.JSX.Element;
10
+ }): JSX.Element;
@@ -37,10 +37,11 @@ function SocialLink({platform, link}) {
37
37
  </Link>
38
38
  );
39
39
  }
40
- export default function AuthorSocials({author}) {
40
+ export default function BlogAuthorSocials({author}) {
41
+ const entries = Object.entries(author.socials ?? {});
41
42
  return (
42
43
  <div className={styles.authorSocials}>
43
- {Object.entries(author.socials ?? {}).map(([platform, linkUrl]) => {
44
+ {entries.map(([platform, linkUrl]) => {
44
45
  return <SocialLink key={platform} platform={platform} link={linkUrl} />;
45
46
  })}
46
47
  </div>
@@ -10,7 +10,12 @@
10
10
  }
11
11
 
12
12
  .authorSocials {
13
- margin-top: 0.2rem;
13
+ /*
14
+ This ensures that container takes height even if there's no social link
15
+ This keeps author names aligned even if only some have socials
16
+ */
17
+ height: var(--docusaurus-blog-social-icon-size);
18
+
14
19
  display: flex;
15
20
  flex-wrap: wrap;
16
21
  align-items: center;
@@ -25,7 +30,7 @@
25
30
  height: var(--docusaurus-blog-social-icon-size);
26
31
  width: var(--docusaurus-blog-social-icon-size);
27
32
  line-height: 0;
28
- margin-right: 0.3rem;
33
+ margin-right: 0.4rem;
29
34
  }
30
35
 
31
36
  .authorSocialIcon {
@@ -4,5 +4,5 @@
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
- import type { Props } from '@theme/BlogPostItem/Header/Author';
8
- export default function BlogPostItemHeaderAuthor({ author, className, }: Props): JSX.Element;
7
+ import type { Props } from '@theme/Blog/Components/Author';
8
+ export default function BlogAuthor({ as, author, className, count, }: Props): JSX.Element;
@@ -0,0 +1,86 @@
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 AuthorSocials from '@theme/Blog/Components/Author/Socials';
11
+ import Heading from '@theme/Heading';
12
+ import styles from './styles.module.css';
13
+ function MaybeLink(props) {
14
+ if (props.href) {
15
+ return <Link {...props} />;
16
+ }
17
+ return <>{props.children}</>;
18
+ }
19
+ function AuthorTitle({title}) {
20
+ return (
21
+ <small className={styles.authorTitle} title={title}>
22
+ {title}
23
+ </small>
24
+ );
25
+ }
26
+ function AuthorName({name, as}) {
27
+ if (!as) {
28
+ return <span className={styles.authorName}>{name}</span>;
29
+ } else {
30
+ return (
31
+ <Heading as={as} className={styles.authorName}>
32
+ {name}
33
+ </Heading>
34
+ );
35
+ }
36
+ }
37
+ function AuthorBlogPostCount({count}) {
38
+ return <span className={clsx(styles.authorBlogPostCount)}>{count}</span>;
39
+ }
40
+ // Note: in the future we might want to have multiple "BlogAuthor" components
41
+ // Creating different display modes with the "as" prop may not be the best idea
42
+ // Explainer: https://kyleshevlin.com/prefer-multiple-compositions/
43
+ // For now, we almost use the same design for all cases, so it's good enough
44
+ export default function BlogAuthor({as, author, className, count}) {
45
+ const {name, title, url, imageURL, email, page} = author;
46
+ const link =
47
+ page?.permalink || url || (email && `mailto:${email}`) || undefined;
48
+ return (
49
+ <div
50
+ className={clsx(
51
+ 'avatar margin-bottom--sm',
52
+ className,
53
+ styles[`author-as-${as}`],
54
+ )}>
55
+ {imageURL && (
56
+ <MaybeLink href={link} className="avatar__photo-link">
57
+ <img
58
+ className={clsx('avatar__photo', styles.authorImage)}
59
+ src={imageURL}
60
+ alt={name}
61
+ />
62
+ </MaybeLink>
63
+ )}
64
+
65
+ {(name || title) && (
66
+ <div className={clsx('avatar__intro', styles.authorDetails)}>
67
+ <div className="avatar__name">
68
+ {name && (
69
+ <MaybeLink href={link}>
70
+ <AuthorName name={name} as={as} />
71
+ </MaybeLink>
72
+ )}
73
+ {count && <AuthorBlogPostCount count={count} />}
74
+ </div>
75
+ {!!title && <AuthorTitle title={title} />}
76
+
77
+ {/*
78
+ We always render AuthorSocials even if there's none
79
+ This keeps other things aligned with flexbox layout
80
+ */}
81
+ <AuthorSocials author={author} />
82
+ </div>
83
+ )}
84
+ </div>
85
+ );
86
+ }
@@ -0,0 +1,74 @@
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
+ .authorImage {
9
+ --ifm-avatar-photo-size: 3.6rem;
10
+ }
11
+
12
+ .author-as-h1 .authorImage {
13
+ --ifm-avatar-photo-size: 7rem;
14
+ }
15
+
16
+ .author-as-h2 .authorImage {
17
+ --ifm-avatar-photo-size: 5.4rem;
18
+ }
19
+
20
+ .authorDetails {
21
+ display: flex;
22
+ flex-direction: column;
23
+ align-items: flex-start;
24
+ justify-content: space-around;
25
+ }
26
+
27
+ .authorName {
28
+ font-size: 1.1rem;
29
+ line-height: 1.1rem;
30
+ display: flex;
31
+ flex-direction: row;
32
+ }
33
+
34
+ .author-as-h1 .authorName {
35
+ font-size: 2.4rem;
36
+ line-height: 2.4rem;
37
+ display: inline;
38
+ }
39
+
40
+ .author-as-h2 .authorName {
41
+ font-size: 1.4rem;
42
+ line-height: 1.4rem;
43
+ display: inline;
44
+ }
45
+
46
+ .authorTitle {
47
+ font-size: 0.8rem;
48
+ line-height: 0.8rem;
49
+ display: -webkit-box;
50
+ overflow: hidden;
51
+ line-clamp: 1;
52
+ -webkit-line-clamp: 1;
53
+ -webkit-box-orient: vertical;
54
+ }
55
+
56
+ .author-as-h1 .authorTitle {
57
+ font-size: 1.2rem;
58
+ line-height: 1.2rem;
59
+ }
60
+
61
+ .author-as-h2 .authorTitle {
62
+ font-size: 1rem;
63
+ line-height: 1rem;
64
+ }
65
+
66
+ .authorBlogPostCount {
67
+ background: var(--ifm-color-secondary);
68
+ color: var(--ifm-color-black);
69
+ font-size: 0.8rem;
70
+ line-height: 1.2;
71
+ border-radius: var(--ifm-global-radius);
72
+ padding: 0.1rem 0.4rem;
73
+ margin-left: 0.3rem;
74
+ }
@@ -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
+ import { type ReactNode } from 'react';
8
+ import type { Props } from '@theme/Blog/Pages/BlogAuthorsListPage';
9
+ export default function BlogAuthorsListPage({ authors, sidebar, }: Props): ReactNode;
@@ -0,0 +1,54 @@
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 {
10
+ PageMetadata,
11
+ HtmlClassNameProvider,
12
+ ThemeClassNames,
13
+ } from '@docusaurus/theme-common';
14
+ import {translateBlogAuthorsListPageTitle} from '@docusaurus/theme-common/internal';
15
+ import BlogLayout from '@theme/BlogLayout';
16
+ import SearchMetadata from '@theme/SearchMetadata';
17
+ import Heading from '@theme/Heading';
18
+ import Author from '@theme/Blog/Components/Author';
19
+ import styles from './styles.module.css';
20
+ function AuthorListItem({author}) {
21
+ return (
22
+ <li className={styles.authorListItem}>
23
+ <Author as="h2" author={author} count={author.count} />
24
+ </li>
25
+ );
26
+ }
27
+ function AuthorsList({authors}) {
28
+ return (
29
+ <section className={clsx('margin-vert--lg', styles.authorsListSection)}>
30
+ <ul>
31
+ {authors.map((author) => (
32
+ <AuthorListItem key={author.key} author={author} />
33
+ ))}
34
+ </ul>
35
+ </section>
36
+ );
37
+ }
38
+ export default function BlogAuthorsListPage({authors, sidebar}) {
39
+ const title = translateBlogAuthorsListPageTitle();
40
+ return (
41
+ <HtmlClassNameProvider
42
+ className={clsx(
43
+ ThemeClassNames.wrapper.blogPages,
44
+ ThemeClassNames.page.blogAuthorsListPage,
45
+ )}>
46
+ <PageMetadata title={title} />
47
+ <SearchMetadata tag="blog_authors_list" />
48
+ <BlogLayout sidebar={sidebar}>
49
+ <Heading as="h1">{title}</Heading>
50
+ <AuthorsList authors={authors} />
51
+ </BlogLayout>
52
+ </HtmlClassNameProvider>
53
+ );
54
+ }
@@ -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
+ .authorListItem {
9
+ list-style-type: none;
10
+ margin-bottom: 2rem;
11
+ }
@@ -0,0 +1,8 @@
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 { Props } from '@theme/Blog/Pages/BlogAuthorsPostsPage';
8
+ export default function BlogAuthorsPostsPage(props: Props): JSX.Element;
@@ -0,0 +1,67 @@
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 {
10
+ PageMetadata,
11
+ HtmlClassNameProvider,
12
+ ThemeClassNames,
13
+ } from '@docusaurus/theme-common';
14
+ import {
15
+ useBlogAuthorPageTitle,
16
+ BlogAuthorsListViewAllLabel,
17
+ } from '@docusaurus/theme-common/internal';
18
+ import Link from '@docusaurus/Link';
19
+ import {useBlogMetadata} from '@docusaurus/plugin-content-blog/client';
20
+ import BlogLayout from '@theme/BlogLayout';
21
+ import BlogListPaginator from '@theme/BlogListPaginator';
22
+ import SearchMetadata from '@theme/SearchMetadata';
23
+ import BlogPostItems from '@theme/BlogPostItems';
24
+ import Author from '@theme/Blog/Components/Author';
25
+ function Metadata({author}) {
26
+ const title = useBlogAuthorPageTitle(author);
27
+ return (
28
+ <>
29
+ <PageMetadata title={title} />
30
+ <SearchMetadata tag="blog_authors_posts" />
31
+ </>
32
+ );
33
+ }
34
+ function ViewAllAuthorsLink() {
35
+ const {authorsListPath} = useBlogMetadata();
36
+ return (
37
+ <Link href={authorsListPath}>
38
+ <BlogAuthorsListViewAllLabel />
39
+ </Link>
40
+ );
41
+ }
42
+ function Content({author, items, sidebar, listMetadata}) {
43
+ return (
44
+ <BlogLayout sidebar={sidebar}>
45
+ <header className="margin-bottom--xl">
46
+ <Author as="h1" author={author} />
47
+ {author.description && <p>{author.description}</p>}
48
+ <ViewAllAuthorsLink />
49
+ </header>
50
+ <hr />
51
+ <BlogPostItems items={items} />
52
+ <BlogListPaginator metadata={listMetadata} />
53
+ </BlogLayout>
54
+ );
55
+ }
56
+ export default function BlogAuthorsPostsPage(props) {
57
+ return (
58
+ <HtmlClassNameProvider
59
+ className={clsx(
60
+ ThemeClassNames.wrapper.blogPages,
61
+ ThemeClassNames.page.blogAuthorsPostsPage,
62
+ )}>
63
+ <Metadata {...props} />
64
+ <Content {...props} />
65
+ </HtmlClassNameProvider>
66
+ );
67
+ }
@@ -7,7 +7,7 @@
7
7
  import React from 'react';
8
8
  import clsx from 'clsx';
9
9
  import {useBlogPost} from '@docusaurus/plugin-content-blog/client';
10
- import BlogPostItemHeaderAuthor from '@theme/BlogPostItem/Header/Author';
10
+ import BlogAuthor from '@theme/Blog/Components/Author';
11
11
  import styles from './styles.module.css';
12
12
  // Component responsible for the authors layout
13
13
  export default function BlogPostItemHeaderAuthors({className}) {
@@ -35,8 +35,7 @@ export default function BlogPostItemHeaderAuthors({className}) {
35
35
  imageOnly ? styles.imageOnlyAuthorCol : styles.authorCol,
36
36
  )}
37
37
  key={idx}>
38
- <BlogPostItemHeaderAuthor
39
- singleAuthor={singleAuthor}
38
+ <BlogAuthor
40
39
  author={{
41
40
  ...author,
42
41
  // Handle author images using relative paths
@@ -6,13 +6,13 @@
6
6
  */
7
7
  import React from 'react';
8
8
  import clsx from 'clsx';
9
- import Translate, {translate} from '@docusaurus/Translate';
9
+ import Translate from '@docusaurus/Translate';
10
10
  import {
11
11
  PageMetadata,
12
12
  HtmlClassNameProvider,
13
13
  ThemeClassNames,
14
- usePluralForm,
15
14
  } from '@docusaurus/theme-common';
15
+ import {useBlogTagsPostsPageTitle} from '@docusaurus/theme-common/internal';
16
16
  import Link from '@docusaurus/Link';
17
17
  import BlogLayout from '@theme/BlogLayout';
18
18
  import BlogListPaginator from '@theme/BlogListPaginator';
@@ -20,34 +20,6 @@ import SearchMetadata from '@theme/SearchMetadata';
20
20
  import BlogPostItems from '@theme/BlogPostItems';
21
21
  import Unlisted from '@theme/Unlisted';
22
22
  import Heading from '@theme/Heading';
23
- // Very simple pluralization: probably good enough for now
24
- function useBlogPostsPlural() {
25
- const {selectMessage} = usePluralForm();
26
- return (count) =>
27
- selectMessage(
28
- count,
29
- translate(
30
- {
31
- id: 'theme.blog.post.plurals',
32
- description:
33
- 'Pluralized label for "{count} posts". 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)',
34
- message: 'One post|{count} posts',
35
- },
36
- {count},
37
- ),
38
- );
39
- }
40
- function useBlogTagsPostsPageTitle(tag) {
41
- const blogPostsPlural = useBlogPostsPlural();
42
- return translate(
43
- {
44
- id: 'theme.blog.tagTitle',
45
- description: 'The title of the page for a blog tag',
46
- message: '{nPosts} tagged with "{tagName}"',
47
- },
48
- {nPosts: blogPostsPlural(tag.count), tagName: tag.label},
49
- );
50
- }
51
23
  function BlogTagsPostsPageMetadata({tag}) {
52
24
  const title = useBlogTagsPostsPageTitle(tag);
53
25
  return (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docusaurus/theme-classic",
3
- "version": "0.0.0-6010",
3
+ "version": "0.0.0-6014",
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": "0.0.0-6010",
24
- "@docusaurus/mdx-loader": "0.0.0-6010",
25
- "@docusaurus/module-type-aliases": "0.0.0-6010",
26
- "@docusaurus/plugin-content-blog": "0.0.0-6010",
27
- "@docusaurus/plugin-content-docs": "0.0.0-6010",
28
- "@docusaurus/plugin-content-pages": "0.0.0-6010",
29
- "@docusaurus/theme-common": "0.0.0-6010",
30
- "@docusaurus/theme-translations": "0.0.0-6010",
31
- "@docusaurus/types": "0.0.0-6010",
32
- "@docusaurus/utils": "0.0.0-6010",
33
- "@docusaurus/utils-common": "0.0.0-6010",
34
- "@docusaurus/utils-validation": "0.0.0-6010",
23
+ "@docusaurus/core": "0.0.0-6014",
24
+ "@docusaurus/mdx-loader": "0.0.0-6014",
25
+ "@docusaurus/module-type-aliases": "0.0.0-6014",
26
+ "@docusaurus/plugin-content-blog": "0.0.0-6014",
27
+ "@docusaurus/plugin-content-docs": "0.0.0-6014",
28
+ "@docusaurus/plugin-content-pages": "0.0.0-6014",
29
+ "@docusaurus/theme-common": "0.0.0-6014",
30
+ "@docusaurus/theme-translations": "0.0.0-6014",
31
+ "@docusaurus/types": "0.0.0-6014",
32
+ "@docusaurus/utils": "0.0.0-6014",
33
+ "@docusaurus/utils-common": "0.0.0-6014",
34
+ "@docusaurus/utils-validation": "0.0.0-6014",
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": "e540dde5a905c3434a5624a94b6c7a7c1a42c4a8"
64
+ "gitHead": "77581424d709d71c35dface5df45925e2851c2c8"
65
65
  }
@@ -127,6 +127,27 @@ export default function getSwizzleConfig(): SwizzleConfig {
127
127
  description:
128
128
  'The object mapping admonition type to a React component.\nUse it to add custom admonition type components, or replace existing ones.\nCan be ejected or wrapped (only manually, see our documentation).',
129
129
  },
130
+ Blog: {
131
+ actions: {
132
+ // Forbidden because it's a parent folder, makes the CLI crash atm
133
+ eject: 'forbidden',
134
+ wrap: 'forbidden',
135
+ },
136
+ },
137
+ 'Blog/Components': {
138
+ actions: {
139
+ // Forbidden because it's a parent folder, makes the CLI crash atm
140
+ eject: 'forbidden',
141
+ wrap: 'forbidden',
142
+ },
143
+ },
144
+ 'Blog/Pages': {
145
+ actions: {
146
+ // Forbidden because it's a parent folder, makes the CLI crash atm
147
+ eject: 'forbidden',
148
+ wrap: 'forbidden',
149
+ },
150
+ },
130
151
  CodeBlock: {
131
152
  actions: {
132
153
  eject: 'safe',
@@ -9,7 +9,7 @@ import type {ComponentType} from 'react';
9
9
  import React from 'react';
10
10
  import clsx from 'clsx';
11
11
  import Link from '@docusaurus/Link';
12
- import type {Props} from '@theme/BlogPostItem/Header/Author/Socials';
12
+ import type {Props} from '@theme/Blog/Components/Author/Socials';
13
13
 
14
14
  import Twitter from '@theme/Icon/Socials/Twitter';
15
15
  import GitHub from '@theme/Icon/Socials/GitHub';
@@ -50,10 +50,15 @@ function SocialLink({platform, link}: {platform: string; link: string}) {
50
50
  );
51
51
  }
52
52
 
53
- export default function AuthorSocials({author}: {author: Props['author']}) {
53
+ export default function BlogAuthorSocials({
54
+ author,
55
+ }: {
56
+ author: Props['author'];
57
+ }): JSX.Element {
58
+ const entries = Object.entries(author.socials ?? {});
54
59
  return (
55
60
  <div className={styles.authorSocials}>
56
- {Object.entries(author.socials ?? {}).map(([platform, linkUrl]) => {
61
+ {entries.map(([platform, linkUrl]) => {
57
62
  return <SocialLink key={platform} platform={platform} link={linkUrl} />;
58
63
  })}
59
64
  </div>
@@ -10,7 +10,12 @@
10
10
  }
11
11
 
12
12
  .authorSocials {
13
- margin-top: 0.2rem;
13
+ /*
14
+ This ensures that container takes height even if there's no social link
15
+ This keeps author names aligned even if only some have socials
16
+ */
17
+ height: var(--docusaurus-blog-social-icon-size);
18
+
14
19
  display: flex;
15
20
  flex-wrap: wrap;
16
21
  align-items: center;
@@ -25,7 +30,7 @@
25
30
  height: var(--docusaurus-blog-social-icon-size);
26
31
  width: var(--docusaurus-blog-social-icon-size);
27
32
  line-height: 0;
28
- margin-right: 0.3rem;
33
+ margin-right: 0.4rem;
29
34
  }
30
35
 
31
36
  .authorSocialIcon {
@@ -0,0 +1,99 @@
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 clsx from 'clsx';
10
+ import Link, {type Props as LinkProps} from '@docusaurus/Link';
11
+ import AuthorSocials from '@theme/Blog/Components/Author/Socials';
12
+ import type {Props} from '@theme/Blog/Components/Author';
13
+ import Heading from '@theme/Heading';
14
+ import styles from './styles.module.css';
15
+
16
+ function MaybeLink(props: LinkProps): JSX.Element {
17
+ if (props.href) {
18
+ return <Link {...props} />;
19
+ }
20
+ return <>{props.children}</>;
21
+ }
22
+
23
+ function AuthorTitle({title}: {title: string}) {
24
+ return (
25
+ <small className={styles.authorTitle} title={title}>
26
+ {title}
27
+ </small>
28
+ );
29
+ }
30
+
31
+ function AuthorName({name, as}: {name: string; as: Props['as']}) {
32
+ if (!as) {
33
+ return <span className={styles.authorName}>{name}</span>;
34
+ } else {
35
+ return (
36
+ <Heading as={as} className={styles.authorName}>
37
+ {name}
38
+ </Heading>
39
+ );
40
+ }
41
+ }
42
+
43
+ function AuthorBlogPostCount({count}: {count: number}) {
44
+ return <span className={clsx(styles.authorBlogPostCount)}>{count}</span>;
45
+ }
46
+
47
+ // Note: in the future we might want to have multiple "BlogAuthor" components
48
+ // Creating different display modes with the "as" prop may not be the best idea
49
+ // Explainer: https://kyleshevlin.com/prefer-multiple-compositions/
50
+ // For now, we almost use the same design for all cases, so it's good enough
51
+ export default function BlogAuthor({
52
+ as,
53
+ author,
54
+ className,
55
+ count,
56
+ }: Props): JSX.Element {
57
+ const {name, title, url, imageURL, email, page} = author;
58
+ const link =
59
+ page?.permalink || url || (email && `mailto:${email}`) || undefined;
60
+
61
+ return (
62
+ <div
63
+ className={clsx(
64
+ 'avatar margin-bottom--sm',
65
+ className,
66
+ styles[`author-as-${as}`],
67
+ )}>
68
+ {imageURL && (
69
+ <MaybeLink href={link} className="avatar__photo-link">
70
+ <img
71
+ className={clsx('avatar__photo', styles.authorImage)}
72
+ src={imageURL}
73
+ alt={name}
74
+ />
75
+ </MaybeLink>
76
+ )}
77
+
78
+ {(name || title) && (
79
+ <div className={clsx('avatar__intro', styles.authorDetails)}>
80
+ <div className="avatar__name">
81
+ {name && (
82
+ <MaybeLink href={link}>
83
+ <AuthorName name={name} as={as} />
84
+ </MaybeLink>
85
+ )}
86
+ {count && <AuthorBlogPostCount count={count} />}
87
+ </div>
88
+ {!!title && <AuthorTitle title={title} />}
89
+
90
+ {/*
91
+ We always render AuthorSocials even if there's none
92
+ This keeps other things aligned with flexbox layout
93
+ */}
94
+ <AuthorSocials author={author} />
95
+ </div>
96
+ )}
97
+ </div>
98
+ );
99
+ }
@@ -0,0 +1,74 @@
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
+ .authorImage {
9
+ --ifm-avatar-photo-size: 3.6rem;
10
+ }
11
+
12
+ .author-as-h1 .authorImage {
13
+ --ifm-avatar-photo-size: 7rem;
14
+ }
15
+
16
+ .author-as-h2 .authorImage {
17
+ --ifm-avatar-photo-size: 5.4rem;
18
+ }
19
+
20
+ .authorDetails {
21
+ display: flex;
22
+ flex-direction: column;
23
+ align-items: flex-start;
24
+ justify-content: space-around;
25
+ }
26
+
27
+ .authorName {
28
+ font-size: 1.1rem;
29
+ line-height: 1.1rem;
30
+ display: flex;
31
+ flex-direction: row;
32
+ }
33
+
34
+ .author-as-h1 .authorName {
35
+ font-size: 2.4rem;
36
+ line-height: 2.4rem;
37
+ display: inline;
38
+ }
39
+
40
+ .author-as-h2 .authorName {
41
+ font-size: 1.4rem;
42
+ line-height: 1.4rem;
43
+ display: inline;
44
+ }
45
+
46
+ .authorTitle {
47
+ font-size: 0.8rem;
48
+ line-height: 0.8rem;
49
+ display: -webkit-box;
50
+ overflow: hidden;
51
+ line-clamp: 1;
52
+ -webkit-line-clamp: 1;
53
+ -webkit-box-orient: vertical;
54
+ }
55
+
56
+ .author-as-h1 .authorTitle {
57
+ font-size: 1.2rem;
58
+ line-height: 1.2rem;
59
+ }
60
+
61
+ .author-as-h2 .authorTitle {
62
+ font-size: 1rem;
63
+ line-height: 1rem;
64
+ }
65
+
66
+ .authorBlogPostCount {
67
+ background: var(--ifm-color-secondary);
68
+ color: var(--ifm-color-black);
69
+ font-size: 0.8rem;
70
+ line-height: 1.2;
71
+ border-radius: var(--ifm-global-radius);
72
+ padding: 0.1rem 0.4rem;
73
+ margin-left: 0.3rem;
74
+ }
@@ -0,0 +1,62 @@
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, {type ReactNode} from 'react';
8
+ import clsx from 'clsx';
9
+ import {
10
+ PageMetadata,
11
+ HtmlClassNameProvider,
12
+ ThemeClassNames,
13
+ } from '@docusaurus/theme-common';
14
+ import {translateBlogAuthorsListPageTitle} from '@docusaurus/theme-common/internal';
15
+ import BlogLayout from '@theme/BlogLayout';
16
+ import type {Props} from '@theme/Blog/Pages/BlogAuthorsListPage';
17
+ import SearchMetadata from '@theme/SearchMetadata';
18
+ import Heading from '@theme/Heading';
19
+ import Author from '@theme/Blog/Components/Author';
20
+ import type {AuthorItemProp} from '@docusaurus/plugin-content-blog';
21
+ import styles from './styles.module.css';
22
+
23
+ function AuthorListItem({author}: {author: AuthorItemProp}) {
24
+ return (
25
+ <li className={styles.authorListItem}>
26
+ <Author as="h2" author={author} count={author.count} />
27
+ </li>
28
+ );
29
+ }
30
+
31
+ function AuthorsList({authors}: {authors: Props['authors']}) {
32
+ return (
33
+ <section className={clsx('margin-vert--lg', styles.authorsListSection)}>
34
+ <ul>
35
+ {authors.map((author) => (
36
+ <AuthorListItem key={author.key} author={author} />
37
+ ))}
38
+ </ul>
39
+ </section>
40
+ );
41
+ }
42
+
43
+ export default function BlogAuthorsListPage({
44
+ authors,
45
+ sidebar,
46
+ }: Props): ReactNode {
47
+ const title: string = translateBlogAuthorsListPageTitle();
48
+ return (
49
+ <HtmlClassNameProvider
50
+ className={clsx(
51
+ ThemeClassNames.wrapper.blogPages,
52
+ ThemeClassNames.page.blogAuthorsListPage,
53
+ )}>
54
+ <PageMetadata title={title} />
55
+ <SearchMetadata tag="blog_authors_list" />
56
+ <BlogLayout sidebar={sidebar}>
57
+ <Heading as="h1">{title}</Heading>
58
+ <AuthorsList authors={authors} />
59
+ </BlogLayout>
60
+ </HtmlClassNameProvider>
61
+ );
62
+ }
@@ -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
+ .authorListItem {
9
+ list-style-type: none;
10
+ margin-bottom: 2rem;
11
+ }
@@ -0,0 +1,73 @@
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 clsx from 'clsx';
10
+ import {
11
+ PageMetadata,
12
+ HtmlClassNameProvider,
13
+ ThemeClassNames,
14
+ } from '@docusaurus/theme-common';
15
+ import {
16
+ useBlogAuthorPageTitle,
17
+ BlogAuthorsListViewAllLabel,
18
+ } from '@docusaurus/theme-common/internal';
19
+ import Link from '@docusaurus/Link';
20
+ import {useBlogMetadata} from '@docusaurus/plugin-content-blog/client';
21
+ import BlogLayout from '@theme/BlogLayout';
22
+ import BlogListPaginator from '@theme/BlogListPaginator';
23
+ import SearchMetadata from '@theme/SearchMetadata';
24
+ import type {Props} from '@theme/Blog/Pages/BlogAuthorsPostsPage';
25
+ import BlogPostItems from '@theme/BlogPostItems';
26
+ import Author from '@theme/Blog/Components/Author';
27
+
28
+ function Metadata({author}: Props): JSX.Element {
29
+ const title = useBlogAuthorPageTitle(author);
30
+ return (
31
+ <>
32
+ <PageMetadata title={title} />
33
+ <SearchMetadata tag="blog_authors_posts" />
34
+ </>
35
+ );
36
+ }
37
+
38
+ function ViewAllAuthorsLink() {
39
+ const {authorsListPath} = useBlogMetadata();
40
+ return (
41
+ <Link href={authorsListPath}>
42
+ <BlogAuthorsListViewAllLabel />
43
+ </Link>
44
+ );
45
+ }
46
+
47
+ function Content({author, items, sidebar, listMetadata}: Props): JSX.Element {
48
+ return (
49
+ <BlogLayout sidebar={sidebar}>
50
+ <header className="margin-bottom--xl">
51
+ <Author as="h1" author={author} />
52
+ {author.description && <p>{author.description}</p>}
53
+ <ViewAllAuthorsLink />
54
+ </header>
55
+ <hr />
56
+ <BlogPostItems items={items} />
57
+ <BlogListPaginator metadata={listMetadata} />
58
+ </BlogLayout>
59
+ );
60
+ }
61
+
62
+ export default function BlogAuthorsPostsPage(props: Props): JSX.Element {
63
+ return (
64
+ <HtmlClassNameProvider
65
+ className={clsx(
66
+ ThemeClassNames.wrapper.blogPages,
67
+ ThemeClassNames.page.blogAuthorsPostsPage,
68
+ )}>
69
+ <Metadata {...props} />
70
+ <Content {...props} />
71
+ </HtmlClassNameProvider>
72
+ );
73
+ }
@@ -8,7 +8,7 @@
8
8
  import React from 'react';
9
9
  import clsx from 'clsx';
10
10
  import {useBlogPost} from '@docusaurus/plugin-content-blog/client';
11
- import BlogPostItemHeaderAuthor from '@theme/BlogPostItem/Header/Author';
11
+ import BlogAuthor from '@theme/Blog/Components/Author';
12
12
  import type {Props} from '@theme/BlogPostItem/Header/Authors';
13
13
  import styles from './styles.module.css';
14
14
 
@@ -40,8 +40,7 @@ export default function BlogPostItemHeaderAuthors({
40
40
  imageOnly ? styles.imageOnlyAuthorCol : styles.authorCol,
41
41
  )}
42
42
  key={idx}>
43
- <BlogPostItemHeaderAuthor
44
- singleAuthor={singleAuthor}
43
+ <BlogAuthor
45
44
  author={{
46
45
  ...author,
47
46
  // Handle author images using relative paths
@@ -7,13 +7,13 @@
7
7
 
8
8
  import React from 'react';
9
9
  import clsx from 'clsx';
10
- import Translate, {translate} from '@docusaurus/Translate';
10
+ import Translate from '@docusaurus/Translate';
11
11
  import {
12
12
  PageMetadata,
13
13
  HtmlClassNameProvider,
14
14
  ThemeClassNames,
15
- usePluralForm,
16
15
  } from '@docusaurus/theme-common';
16
+ import {useBlogTagsPostsPageTitle} from '@docusaurus/theme-common/internal';
17
17
  import Link from '@docusaurus/Link';
18
18
  import BlogLayout from '@theme/BlogLayout';
19
19
  import BlogListPaginator from '@theme/BlogListPaginator';
@@ -23,36 +23,6 @@ import BlogPostItems from '@theme/BlogPostItems';
23
23
  import Unlisted from '@theme/Unlisted';
24
24
  import Heading from '@theme/Heading';
25
25
 
26
- // Very simple pluralization: probably good enough for now
27
- function useBlogPostsPlural() {
28
- const {selectMessage} = usePluralForm();
29
- return (count: number) =>
30
- selectMessage(
31
- count,
32
- translate(
33
- {
34
- id: 'theme.blog.post.plurals',
35
- description:
36
- 'Pluralized label for "{count} posts". 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)',
37
- message: 'One post|{count} posts',
38
- },
39
- {count},
40
- ),
41
- );
42
- }
43
-
44
- function useBlogTagsPostsPageTitle(tag: Props['tag']): string {
45
- const blogPostsPlural = useBlogPostsPlural();
46
- return translate(
47
- {
48
- id: 'theme.blog.tagTitle',
49
- description: 'The title of the page for a blog tag',
50
- message: '{nPosts} tagged with "{tagName}"',
51
- },
52
- {nPosts: blogPostsPlural(tag.count), tagName: tag.label},
53
- );
54
- }
55
-
56
26
  function BlogTagsPostsPageMetadata({tag}: Props): JSX.Element {
57
27
  const title = useBlogTagsPostsPageTitle(tag);
58
28
  return (
@@ -185,6 +185,30 @@ declare module '@theme/BackToTopButton' {
185
185
  export default function BackToTopButton(): JSX.Element;
186
186
  }
187
187
 
188
+ declare module '@theme/Blog/Components/Author' {
189
+ import type {Author} from '@docusaurus/plugin-content-blog';
190
+
191
+ export interface Props {
192
+ readonly as?: 'h1' | 'h2';
193
+ readonly author: Author;
194
+ readonly className?: string;
195
+ readonly count?: number;
196
+ }
197
+
198
+ export default function BlogAuthor(props: Props): JSX.Element;
199
+ }
200
+
201
+ declare module '@theme/Blog/Components/Author/Socials' {
202
+ import type {Author} from '@docusaurus/plugin-content-blog';
203
+
204
+ export interface Props {
205
+ readonly author: Author;
206
+ readonly className?: string;
207
+ }
208
+
209
+ export default function BlogAuthorSocials(props: Props): JSX.Element;
210
+ }
211
+
188
212
  declare module '@theme/BlogListPaginator' {
189
213
  import type {BlogPaginatedMetadata} from '@docusaurus/plugin-content-blog';
190
214
 
@@ -291,31 +315,6 @@ declare module '@theme/BlogPostItem/Header/Info' {
291
315
  export default function BlogPostItemHeaderInfo(): JSX.Element;
292
316
  }
293
317
 
294
- declare module '@theme/BlogPostItem/Header/Author' {
295
- import type {Author} from '@docusaurus/plugin-content-blog';
296
-
297
- export interface Props {
298
- readonly author: Author;
299
- readonly singleAuthor: boolean;
300
- readonly className?: string;
301
- }
302
-
303
- export default function BlogPostItemHeaderAuthor(props: Props): JSX.Element;
304
- }
305
-
306
- declare module '@theme/BlogPostItem/Header/Author/Socials' {
307
- import type {Author} from '@docusaurus/plugin-content-blog';
308
-
309
- export interface Props {
310
- readonly author: Author;
311
- readonly className?: string;
312
- }
313
-
314
- export default function BlogPostItemHeaderAuthorSocials(
315
- props: Props,
316
- ): JSX.Element;
317
- }
318
-
319
318
  declare module '@theme/BlogPostItem/Header/Authors' {
320
319
  export interface Props {
321
320
  readonly className?: string;
@@ -1,54 +0,0 @@
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 AuthorSocials from '@theme/BlogPostItem/Header/Author/Socials';
11
- import styles from './styles.module.css';
12
- function MaybeLink(props) {
13
- if (props.href) {
14
- return <Link {...props} />;
15
- }
16
- return <>{props.children}</>;
17
- }
18
- function AuthorTitle({title}) {
19
- return (
20
- <small className={styles.authorTitle} title={title}>
21
- {title}
22
- </small>
23
- );
24
- }
25
- export default function BlogPostItemHeaderAuthor({
26
- // singleAuthor, // may be useful in the future, or for swizzle users
27
- author,
28
- className,
29
- }) {
30
- const {name, title, url, socials, imageURL, email} = author;
31
- const link = url || (email && `mailto:${email}`) || undefined;
32
- const hasSocials = socials && Object.keys(socials).length > 0;
33
- return (
34
- <div className={clsx('avatar margin-bottom--sm', className)}>
35
- {imageURL && (
36
- <MaybeLink href={link} className="avatar__photo-link">
37
- <img className="avatar__photo" src={imageURL} alt={name} />
38
- </MaybeLink>
39
- )}
40
-
41
- {(name || title) && (
42
- <div className="avatar__intro">
43
- <div className="avatar__name">
44
- <MaybeLink href={link}>
45
- <span className={styles.authorName}>{name}</span>
46
- </MaybeLink>
47
- </div>
48
- {!!title && <AuthorTitle title={title} />}
49
- {hasSocials && <AuthorSocials author={author} />}
50
- </div>
51
- )}
52
- </div>
53
- );
54
- }
@@ -1,21 +0,0 @@
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
- .authorName {
9
- font-size: 1.1rem;
10
- }
11
-
12
- .authorTitle {
13
- margin-top: 0.06rem;
14
- font-size: 0.8rem;
15
- line-height: 0.8rem;
16
- display: -webkit-box;
17
- overflow: hidden;
18
- line-clamp: 1;
19
- -webkit-line-clamp: 1;
20
- -webkit-box-orient: vertical;
21
- }
@@ -1,62 +0,0 @@
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 clsx from 'clsx';
10
- import Link, {type Props as LinkProps} from '@docusaurus/Link';
11
- import AuthorSocials from '@theme/BlogPostItem/Header/Author/Socials';
12
-
13
- import type {Props} from '@theme/BlogPostItem/Header/Author';
14
- import styles from './styles.module.css';
15
-
16
- function MaybeLink(props: LinkProps): JSX.Element {
17
- if (props.href) {
18
- return <Link {...props} />;
19
- }
20
- return <>{props.children}</>;
21
- }
22
-
23
- function AuthorTitle({title}: {title: string}) {
24
- return (
25
- <small className={styles.authorTitle} title={title}>
26
- {title}
27
- </small>
28
- );
29
- }
30
-
31
- export default function BlogPostItemHeaderAuthor({
32
- // singleAuthor, // may be useful in the future, or for swizzle users
33
- author,
34
- className,
35
- }: Props): JSX.Element {
36
- const {name, title, url, socials, imageURL, email} = author;
37
- const link = url || (email && `mailto:${email}`) || undefined;
38
-
39
- const hasSocials = socials && Object.keys(socials).length > 0;
40
-
41
- return (
42
- <div className={clsx('avatar margin-bottom--sm', className)}>
43
- {imageURL && (
44
- <MaybeLink href={link} className="avatar__photo-link">
45
- <img className="avatar__photo" src={imageURL} alt={name} />
46
- </MaybeLink>
47
- )}
48
-
49
- {(name || title) && (
50
- <div className="avatar__intro">
51
- <div className="avatar__name">
52
- <MaybeLink href={link}>
53
- <span className={styles.authorName}>{name}</span>
54
- </MaybeLink>
55
- </div>
56
- {!!title && <AuthorTitle title={title} />}
57
- {hasSocials && <AuthorSocials author={author} />}
58
- </div>
59
- )}
60
- </div>
61
- );
62
- }
@@ -1,21 +0,0 @@
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
- .authorName {
9
- font-size: 1.1rem;
10
- }
11
-
12
- .authorTitle {
13
- margin-top: 0.06rem;
14
- font-size: 0.8rem;
15
- line-height: 0.8rem;
16
- display: -webkit-box;
17
- overflow: hidden;
18
- line-clamp: 1;
19
- -webkit-line-clamp: 1;
20
- -webkit-box-orient: vertical;
21
- }