From 27479a4faae6e8c9e40fd6a1113b9e59dd960ac4 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:05:53 +0200 Subject: [PATCH 01/35] feat(blog): author header social icons --- .../BlogPostItem/Header/Author/index.tsx | 77 ++++++++++++++++++- .../Header/Author/styles.module.css | 17 ++++ website/blog/authors.yml | 1 + 3 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx index 5d9935febb04..4dd49181449c 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx @@ -5,11 +5,70 @@ * LICENSE file in the root directory of this source tree. */ +import type {SVGProps} from 'react'; import React from 'react'; import clsx from 'clsx'; import Link, {type Props as LinkProps} from '@docusaurus/Link'; import type {Props} from '@theme/BlogPostItem/Header/Author'; +import styles from './styles.module.css'; + +type SocialProps = SVGProps & { + user: string; +}; + +function getUrl(user: string, baseUrl: string) { + return user.startsWith('https') ? user : `${baseUrl}${user}`; +} + +function Twitter(props: SocialProps) { + const twitterUrl = getUrl(props.user, 'https://x.com/'); + return ( + // eslint-disable-next-line @docusaurus/no-html-links + + + + + + ); +} + +function Github(props: SocialProps) { + const githubUrl = getUrl(props.user, 'https://github.com/'); + return ( + // eslint-disable-next-line @docusaurus/no-html-links + + + + + + ); +} function MaybeLink(props: LinkProps): JSX.Element { if (props.href) { @@ -22,8 +81,17 @@ export default function BlogPostItemHeaderAuthor({ author, className, }: Props): JSX.Element { - const {name, title, url, imageURL, email} = author; + const {name, title, twitter, github, url, imageURL, email} = author; const link = url || (email && `mailto:${email}`) || undefined; + const renderSocialMedia = () => ( +
+ {(twitter as string) && } + {(github as string) && } +
+ ); + + const hasSocialMedia = twitter || github; + return (
{imageURL && ( @@ -31,7 +99,6 @@ export default function BlogPostItemHeaderAuthor({ {name} )} - {name && (
@@ -39,7 +106,11 @@ export default function BlogPostItemHeaderAuthor({ {name}
- {title && {title}} + {hasSocialMedia ? ( + renderSocialMedia() + ) : ( + {title} + )}
)}
diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css new file mode 100644 index 000000000000..ec21f2c232aa --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css @@ -0,0 +1,17 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.authorSocial { + display: flex; + align-items: center; +} + +.socialIcon { + width: 1.5em; + height: 1.5em; + margin-right: 0.5em; +} diff --git a/website/blog/authors.yml b/website/blog/authors.yml index 5b84346cda7c..073afa0f9e2a 100644 --- a/website/blog/authors.yml +++ b/website/blog/authors.yml @@ -20,6 +20,7 @@ slorber: url: https://thisweekinreact.com image_url: https://github.com/slorber.png twitter: sebastienlorber + github: slorber email: sebastien@thisweekinreact.com yangshun: From c3a8ad50839bc7297c64083353c89dd2cb90441d Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:31:56 +0200 Subject: [PATCH 02/35] update style --- .../src/theme/BlogPostItem/Header/Author/index.tsx | 3 ++- .../src/theme/BlogPostItem/Header/Author/styles.module.css | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx index 4dd49181449c..2ed181df7ee0 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx @@ -84,7 +84,7 @@ export default function BlogPostItemHeaderAuthor({ const {name, title, twitter, github, url, imageURL, email} = author; const link = url || (email && `mailto:${email}`) || undefined; const renderSocialMedia = () => ( -
+
{(twitter as string) && } {(github as string) && }
@@ -99,6 +99,7 @@ export default function BlogPostItemHeaderAuthor({ {name} )} + {name && (
diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css index ec21f2c232aa..8a2ba3c92a48 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css @@ -11,7 +11,7 @@ } .socialIcon { - width: 1.5em; - height: 1.5em; + width: 1.375em; + height: 1.375em; margin-right: 0.5em; } From 51a8e08671d9e13f8b7602dfa6ddb70a1280db39 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 20 Jun 2024 19:31:46 +0200 Subject: [PATCH 03/35] refactor: review --- .../src/authors.ts | 34 +++++++ .../src/plugin-content-blog.d.ts | 7 ++ .../src/theme-classic.d.ts | 32 +++++++ .../BlogPostItem/Header/Author/index.tsx | 89 ++++++------------- .../src/theme/Icon/Socials/Github/index.tsx | 28 ++++++ .../src/theme/Icon/Socials/LinkedIn/index.tsx | 27 ++++++ .../Icon/Socials/StackOverflow/index.tsx | 30 +++++++ .../src/theme/Icon/Socials/Twitter/index.tsx | 27 ++++++ website/blog/authors.yml | 6 +- 9 files changed, 216 insertions(+), 64 deletions(-) create mode 100644 packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx create mode 100644 packages/docusaurus-theme-classic/src/theme/Icon/Socials/LinkedIn/index.tsx create mode 100644 packages/docusaurus-theme-classic/src/theme/Icon/Socials/StackOverflow/index.tsx create mode 100644 packages/docusaurus-theme-classic/src/theme/Icon/Socials/Twitter/index.tsx diff --git a/packages/docusaurus-plugin-content-blog/src/authors.ts b/packages/docusaurus-plugin-content-blog/src/authors.ts index c5fdad61ddfb..69736e338b51 100644 --- a/packages/docusaurus-plugin-content-blog/src/authors.ts +++ b/packages/docusaurus-plugin-content-blog/src/authors.ts @@ -17,6 +17,34 @@ import type { export type AuthorsMap = {[authorKey: string]: Author}; +interface Socials { + twitter: string; + github: string; +} + +const normalizeSocials = (value: Socials) => { + const socialPlatforms = { + twitter: 'https://twitter.com/', + github: 'https://github.com/', + linkedin: 'https://www.linkedin.com/in/', + stackoverflow: 'https://stackoverflow.com/users/', + }; + + (Object.keys(socialPlatforms) as (keyof Socials)[]).forEach((platform) => { + if ( + value[platform] && + !value[platform]!.startsWith(socialPlatforms[platform]) + ) { + value[platform] = normalizeUrl([ + socialPlatforms[platform], + value[platform], + ]); + } + }); + + return value; +}; + const AuthorsMapSchema = Joi.object() .pattern( Joi.string(), @@ -26,6 +54,12 @@ const AuthorsMapSchema = Joi.object() imageURL: URISchema, title: Joi.string(), email: Joi.string(), + socials: Joi.object({ + twitter: Joi.string(), + github: Joi.string(), + linkedin: Joi.string(), + stackoverflow: Joi.string(), + }).custom(normalizeSocials, 'Normalize social media URLs'), }) .rename('image_url', 'imageURL') .or('name', 'imageURL') diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index f4d4f135c061..f338227b50da 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -71,6 +71,13 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the * Unknown keys are allowed, so that we can pass custom fields to authors, * e.g., `twitter`. */ + socials?: { + twitter: string; + linkedin: string; + github: string; + stackoverflow: string; + [key: string]: string; + }; [key: string]: unknown; }; diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 39e7195893b4..4efcf56c96b6 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -1501,6 +1501,38 @@ declare module '@theme/Icon/WordWrap' { export default function IconWordWrap(props: Props): JSX.Element; } +declare module '@theme/Icon/Socials/Twitter' { + import type {ComponentProps} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function Twitter(props: Props): JSX.Element; +} + +declare module '@theme/Icon/Socials/Github' { + import type {ComponentProps} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function Github(props: Props): JSX.Element; +} + +declare module '@theme/Icon/Socials/LinkedIn' { + import type {ComponentProps} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function LinkedIn(props: Props): JSX.Element; +} + +declare module '@theme/Icon/Socials/StackOverflow' { + import type {ComponentProps} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function StackOverflow(props: Props): JSX.Element; +} + declare module '@theme/TagsListByLetter' { import type {TagsListItem} from '@docusaurus/utils'; diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx index 2ed181df7ee0..9b5dfe68d730 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx @@ -5,71 +5,17 @@ * LICENSE file in the root directory of this source tree. */ -import type {SVGProps} from 'react'; import React from 'react'; import clsx from 'clsx'; import Link, {type Props as LinkProps} from '@docusaurus/Link'; import type {Props} from '@theme/BlogPostItem/Header/Author'; +import Twitter from '@theme/Icon/Socials/Twitter'; +import Github from '@theme/Icon/Socials/Github'; +import StackOverflow from '@theme/Icon/Socials/StackOverflow'; +import LinkedIn from '@theme/Icon/Socials/LinkedIn'; import styles from './styles.module.css'; -type SocialProps = SVGProps & { - user: string; -}; - -function getUrl(user: string, baseUrl: string) { - return user.startsWith('https') ? user : `${baseUrl}${user}`; -} - -function Twitter(props: SocialProps) { - const twitterUrl = getUrl(props.user, 'https://x.com/'); - return ( - // eslint-disable-next-line @docusaurus/no-html-links - - - - - - ); -} - -function Github(props: SocialProps) { - const githubUrl = getUrl(props.user, 'https://github.com/'); - return ( - // eslint-disable-next-line @docusaurus/no-html-links - - - - - - ); -} - function MaybeLink(props: LinkProps): JSX.Element { if (props.href) { return ; @@ -81,16 +27,35 @@ export default function BlogPostItemHeaderAuthor({ author, className, }: Props): JSX.Element { - const {name, title, twitter, github, url, imageURL, email} = author; + const {name, title, url, socials, imageURL, email} = author; + const {github, twitter, stackoverflow, linkedin} = socials || {}; const link = url || (email && `mailto:${email}`) || undefined; const renderSocialMedia = () => (
- {(twitter as string) && } - {(github as string) && } + {twitter && ( + + + + )} + {github && ( + + + + )} + {linkedin && ( + + + + )} + {stackoverflow && ( + + + + )}
); - const hasSocialMedia = twitter || github; + const hasSocialMedia = socials && Object.keys(socials).length > 0; return (
diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx new file mode 100644 index 000000000000..2f86f10a2924 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx @@ -0,0 +1,28 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import type {SVGProps} from 'react'; +import {useColorMode} from '@docusaurus/theme-common'; + +// SVG Source: https://svgl.app/ +function Github(props: SVGProps): JSX.Element { + const {colorMode} = useColorMode(); + const fillColor = colorMode === 'dark' ? '#fff' : '#000'; + return ( + + + + ); +} +export default Github; diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/LinkedIn/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/LinkedIn/index.tsx new file mode 100644 index 000000000000..b4b60dd47b5b --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/LinkedIn/index.tsx @@ -0,0 +1,27 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import type {SVGProps} from 'react'; + +// SVG Source: https://svgl.app/ +function LinkedIn(props: SVGProps): JSX.Element { + return ( + + + + ); +} +export default LinkedIn; diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/StackOverflow/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/StackOverflow/index.tsx new file mode 100644 index 000000000000..402bf16260dc --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/StackOverflow/index.tsx @@ -0,0 +1,30 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import type {SVGProps} from 'react'; + +// SVG Source: https://svgl.app/ +function StackOverflow(props: SVGProps): JSX.Element { + return ( + + + + + ); +} +export default StackOverflow; diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Twitter/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Twitter/index.tsx new file mode 100644 index 000000000000..5787de1ae241 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Twitter/index.tsx @@ -0,0 +1,27 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import type {SVGProps} from 'react'; + +// SVG Source: https://svgl.app/ +function Twitter(props: SVGProps): JSX.Element { + return ( + + + + ); +} +export default Twitter; diff --git a/website/blog/authors.yml b/website/blog/authors.yml index 073afa0f9e2a..63d369468196 100644 --- a/website/blog/authors.yml +++ b/website/blog/authors.yml @@ -19,9 +19,11 @@ slorber: title: Docusaurus maintainer, This Week In React editor url: https://thisweekinreact.com image_url: https://github.com/slorber.png - twitter: sebastienlorber - github: slorber email: sebastien@thisweekinreact.com + socials: + github: slorber + twitter: sebastienlorber + stackoverflow: /82609/sebastien-lorber yangshun: name: Yangshun Tay From 7c45cfc64d5ac20baffaa0cf0fd1be02829c2ada Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Thu, 20 Jun 2024 17:36:20 +0000 Subject: [PATCH 04/35] refactor: apply lint autofix --- project-words.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/project-words.txt b/project-words.txt index 0125953ec975..768ec6f5ca01 100644 --- a/project-words.txt +++ b/project-words.txt @@ -109,6 +109,7 @@ froms funboxteam gabrielcsapo Gifs +githubsvg Goss Goyal gtag @@ -166,6 +167,7 @@ linkify Linkify Localizable lockb +lorber Lorber Lorber's lqip @@ -328,6 +330,7 @@ Solana spâce stackblitz stackblitzrc +stackoverflow Stormkit Strikethrough strikethroughs From a93f742233f990abdf7f189d5d87240fb806c60e Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 20 Jun 2024 19:38:09 +0200 Subject: [PATCH 05/35] remove unused class --- .../src/theme/BlogPostItem/Header/Author/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx index 9b5dfe68d730..252a63e36b61 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx @@ -39,7 +39,7 @@ export default function BlogPostItemHeaderAuthor({ )} {github && ( - + )} {linkedin && ( From 685b2febf2419c3668acca7e4cc1602bde096855 Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Thu, 20 Jun 2024 17:43:21 +0000 Subject: [PATCH 06/35] refactor: apply lint autofix --- project-words.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/project-words.txt b/project-words.txt index 768ec6f5ca01..721f38319aa7 100644 --- a/project-words.txt +++ b/project-words.txt @@ -109,7 +109,6 @@ froms funboxteam gabrielcsapo Gifs -githubsvg Goss Goyal gtag From 0ab5afd8355b1b4bc75f62a842ab48c5a1129404 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 2 Jul 2024 15:11:14 +0200 Subject: [PATCH 07/35] add tests and move normalize outside of joi --- .../src/__tests__/authorsSocials.test.ts | 91 +++++++++++++++++++ .../src/authors.ts | 30 +----- .../src/authorsSocials.ts | 35 +++++++ .../src/blogUtils.ts | 8 ++ .../src/plugin-content-blog.d.ts | 17 ++-- 5 files changed, 143 insertions(+), 38 deletions(-) create mode 100644 packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts create mode 100644 packages/docusaurus-plugin-content-blog/src/authorsSocials.ts diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts new file mode 100644 index 000000000000..0348b831b404 --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts @@ -0,0 +1,91 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {normalizeSocials} from '../authorsSocials'; +import type {AuthorSocials} from '@docusaurus/plugin-content-blog'; + +describe('normalizeSocials', () => { + it('only username', () => { + const socials: AuthorSocials = { + twitter: 'ozakione', + linkedin: 'ozakione', + github: 'ozakione', + stackoverflow: 'ozakione', + }; + + expect(normalizeSocials(socials)).toMatchInlineSnapshot(` + { + "github": "https://github.com/ozakione", + "linkedin": "https://www.linkedin.com/ozakione", + "stackoverflow": "https://stackoverflow.com/ozakione", + "twitter": "https://twitter.com/ozakione", + } + `); + }); + + it('only links', () => { + const socials: AuthorSocials = { + twitter: 'https://x.com/ozakione', + linkedin: 'https://linkedin.com/ozakione', + github: 'https://github.com/ozakione', + stackoverflow: 'https://stackoverflow.com/ozakione', + }; + + expect(normalizeSocials(socials)).toEqual(socials); + }); + + it('mixed links', () => { + const socials: AuthorSocials = { + twitter: 'ozakione', + linkedin: 'ozakione', + github: 'https://github.com/ozakione', + stackoverflow: 'https://stackoverflow.com/ozakione', + }; + + expect(normalizeSocials(socials)).toMatchInlineSnapshot(` + { + "github": "https://github.com/ozakione", + "linkedin": "https://www.linkedin.com/ozakione", + "stackoverflow": "https://stackoverflow.com/ozakione", + "twitter": "https://twitter.com/ozakione", + } + `); + }); + + it('one link', () => { + const socials: AuthorSocials = { + twitter: 'ozakione', + }; + + expect(normalizeSocials(socials)).toMatchInlineSnapshot(` + { + "twitter": "https://twitter.com/ozakione", + } + `); + }); + + it('normalize link url', () => { + // stackoverflow doesn't like multiple slashes, as we have trailing slash + // in socialPlatforms, if the user add a prefix slash the url will contain + // multiple slashes causing a 404 + const socials: AuthorSocials = { + twitter: '//ozakione', + github: '/ozakione///', + linkedin: '//ozakione///', + stackoverflow: '///users///82609/sebastien-lorber', + }; + + expect(normalizeSocials(socials)).toMatchInlineSnapshot(` + { + "github": "https://github.com/ozakione/", + "linkedin": "https://www.linkedin.com/ozakione/", + "stackoverflow": "https://stackoverflow.com/users/82609/sebastien-lorber", + "twitter": "https://twitter.com/ozakione", + } + `); + }); +}); diff --git a/packages/docusaurus-plugin-content-blog/src/authors.ts b/packages/docusaurus-plugin-content-blog/src/authors.ts index 69736e338b51..61d1be97d4de 100644 --- a/packages/docusaurus-plugin-content-blog/src/authors.ts +++ b/packages/docusaurus-plugin-content-blog/src/authors.ts @@ -17,34 +17,6 @@ import type { export type AuthorsMap = {[authorKey: string]: Author}; -interface Socials { - twitter: string; - github: string; -} - -const normalizeSocials = (value: Socials) => { - const socialPlatforms = { - twitter: 'https://twitter.com/', - github: 'https://github.com/', - linkedin: 'https://www.linkedin.com/in/', - stackoverflow: 'https://stackoverflow.com/users/', - }; - - (Object.keys(socialPlatforms) as (keyof Socials)[]).forEach((platform) => { - if ( - value[platform] && - !value[platform]!.startsWith(socialPlatforms[platform]) - ) { - value[platform] = normalizeUrl([ - socialPlatforms[platform], - value[platform], - ]); - } - }); - - return value; -}; - const AuthorsMapSchema = Joi.object() .pattern( Joi.string(), @@ -59,7 +31,7 @@ const AuthorsMapSchema = Joi.object() github: Joi.string(), linkedin: Joi.string(), stackoverflow: Joi.string(), - }).custom(normalizeSocials, 'Normalize social media URLs'), + }).unknown(), }) .rename('image_url', 'imageURL') .or('name', 'imageURL') diff --git a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts new file mode 100644 index 000000000000..ec379cd5eb0e --- /dev/null +++ b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts @@ -0,0 +1,35 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {normalizeUrl} from '@docusaurus/utils'; +import type { + AuthorSocials, + SocialPlatform, +} from '@docusaurus/plugin-content-blog'; + +const socialPlatforms: Record = { + twitter: 'https://twitter.com/', + github: 'https://github.com/', + linkedin: 'https://www.linkedin.com/', + stackoverflow: 'https://stackoverflow.com/', +}; + +export const normalizeSocials = (value: AuthorSocials): AuthorSocials => { + (Object.keys(socialPlatforms) as SocialPlatform[]).forEach((platform) => { + if ( + value[platform] && + !value[platform]!.startsWith(socialPlatforms[platform]) + ) { + value[platform] = normalizeUrl([ + socialPlatforms[platform], + value[platform]!, + ]); + } + }); + + return value; +}; diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 68f429cc8c0c..3e3d2994e66f 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -31,6 +31,7 @@ import {getTagsFile} from '@docusaurus/utils-validation'; import {validateBlogPostFrontMatter} from './frontMatter'; import {type AuthorsMap, getAuthorsMap, getBlogPostAuthors} from './authors'; import {reportAuthorsProblems} from './authorsProblems'; +import {normalizeSocials} from './authorsSocials'; import type {TagsFile} from '@docusaurus/utils'; import type {LoadContext, ParseFrontMatter} from '@docusaurus/types'; import type { @@ -383,6 +384,13 @@ export async function generateBlogPosts( authorsMapPath: options.authorsMapPath, }); + if (authorsMap) { + Object.entries(authorsMap).forEach(([, author]) => { + if (author.socials) { + author.socials = normalizeSocials(author.socials); + } + }); + } const tagsFile = await getTagsFile({contentPaths, tags: options.tags}); async function doProcessBlogSourceFile(blogSourceFile: string) { diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index 25266b62f9fe..75437019a569 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -43,6 +43,10 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the authorsImageUrls: (string | undefined)[]; }; + type SocialPlatform = 'twitter' | 'github' | 'linkedin' | 'stackoverflow'; + + export type AuthorSocials = Partial>; + export type Author = { key?: string; // TODO temporary, need refactor @@ -70,17 +74,12 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the */ email?: string; /** - * Unknown keys are allowed, so that we can pass custom fields to authors, - * e.g., `twitter`. + * TODO write a description */ - socials?: { - twitter: string; - linkedin: string; - github: string; - stackoverflow: string; - [key: string]: string; + socials?: Partial> & { + [customAuthorSocialPlatform: string]: string; }; - [key: string]: unknown; + [customAuthorAttribute: string]: unknown; }; /** From be05dc73301edf9bff2823fd3418232a7bd26c12 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 2 Jul 2024 15:16:46 +0200 Subject: [PATCH 08/35] add test --- .../src/__tests__/authorsSocials.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts index 0348b831b404..6b689a2fbee3 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts @@ -88,4 +88,12 @@ describe('normalizeSocials', () => { } `); }); + + it('allow other form of urls', () => { + const socials: AuthorSocials = { + twitter: 'https://bit.ly/sebastienlorber-twitter', + }; + + expect(normalizeSocials(socials)).toEqual(socials); + }); }); From eb4a2fc25b4f41e1a8fb55239b710a746b0a5d4b Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Tue, 2 Jul 2024 15:54:58 +0200 Subject: [PATCH 09/35] wip --- .../src/theme/Icon/Socials/Github/index.tsx | 8 ++++---- .../Icon/Socials/Github/styles.module.css | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/styles.module.css diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx index 2f86f10a2924..a3696b7d2a45 100644 --- a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx @@ -6,12 +6,11 @@ */ import type {SVGProps} from 'react'; -import {useColorMode} from '@docusaurus/theme-common'; + +import styles from './styles.module.css'; // SVG Source: https://svgl.app/ function Github(props: SVGProps): JSX.Element { - const {colorMode} = useColorMode(); - const fillColor = colorMode === 'dark' ? '#fff' : '#000'; return ( ): JSX.Element { height="250" {...props} xmlns="http://www.w3.org/2000/svg" - fill={fillColor} + className={styles.githubSvg} + style={{'--dark': '#fff', '--light': '#000'} as React.CSSProperties} preserveAspectRatio="xMidYMid"> diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/styles.module.css b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/styles.module.css new file mode 100644 index 000000000000..08eb56bb1659 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/styles.module.css @@ -0,0 +1,19 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +.githubSvg { + width: 1.375em; + height: 1.375em; + margin-right: 0.5em; +} + +[data-theme='dark'] .githubSvg { + fill: var(--dark); +} + +[data-theme='light'] .githubSvg { + fill: var(--light); +} From 0c26f22185637b70c51f1849fb84751d58037581 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 3 Jul 2024 14:07:49 +0200 Subject: [PATCH 10/35] add default icon & refactor code --- .../src/theme-classic.d.ts | 8 ++++ .../BlogPostItem/Header/Author/index.tsx | 45 ++++++++++--------- .../src/theme/Icon/Socials/Default/index.tsx | 33 ++++++++++++++ 3 files changed, 65 insertions(+), 21 deletions(-) create mode 100644 packages/docusaurus-theme-classic/src/theme/Icon/Socials/Default/index.tsx diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index fd961909df94..36ff2599cf77 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -1538,6 +1538,14 @@ declare module '@theme/Icon/Socials/LinkedIn' { export default function LinkedIn(props: Props): JSX.Element; } +declare module '@theme/Icon/Socials/Default' { + import type {ComponentProps} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function DefaultSocial(props: Props): JSX.Element; +} + declare module '@theme/Icon/Socials/StackOverflow' { import type {ComponentProps} from 'react'; diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx index 252a63e36b61..9223ff83746e 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import type {ComponentType} from 'react'; import React from 'react'; import clsx from 'clsx'; import Link, {type Props as LinkProps} from '@docusaurus/Link'; @@ -14,6 +15,7 @@ import Twitter from '@theme/Icon/Socials/Twitter'; import Github from '@theme/Icon/Socials/Github'; import StackOverflow from '@theme/Icon/Socials/StackOverflow'; import LinkedIn from '@theme/Icon/Socials/LinkedIn'; +import DefaultSocial from '@theme/Icon/Socials/Default'; import styles from './styles.module.css'; function MaybeLink(props: LinkProps): JSX.Element { @@ -23,35 +25,36 @@ function MaybeLink(props: LinkProps): JSX.Element { return <>{props.children}; } +const PlatformIconsMap: Record> = { + twitter: Twitter, + github: Github, + stackoverflow: StackOverflow, + linkedin: LinkedIn, +}; + +function PlatformLink({platform, link}: {platform: string; link: string}) { + const Icon = PlatformIconsMap[platform] ?? DefaultSocial; + return ( + + + + ); +} + export default function BlogPostItemHeaderAuthor({ author, className, }: Props): JSX.Element { const {name, title, url, socials, imageURL, email} = author; - const {github, twitter, stackoverflow, linkedin} = socials || {}; const link = url || (email && `mailto:${email}`) || undefined; + const renderSocialMedia = () => (
- {twitter && ( - - - - )} - {github && ( - - - - )} - {linkedin && ( - - - - )} - {stackoverflow && ( - - - - )} + {Object.entries(socials ?? {}).map(([platform, linkUrl]) => { + return ( + + ); + })}
); diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Default/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Default/index.tsx new file mode 100644 index 000000000000..c5a15cd67d90 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Default/index.tsx @@ -0,0 +1,33 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import type {SVGProps} from 'react'; + +// SVG Source: https://tabler.io/ +function DefaultSocial(props: SVGProps): JSX.Element { + return ( + + + + + + + + + ); +} +export default DefaultSocial; From e98b0ed112c5e867c2828abad887113d5364a339 Mon Sep 17 00:00:00 2001 From: OzakIOne Date: Wed, 3 Jul 2024 12:32:08 +0000 Subject: [PATCH 11/35] refactor: apply lint autofix --- project-words.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/project-words.txt b/project-words.txt index d28eb98170fc..cc65e25d344e 100644 --- a/project-words.txt +++ b/project-words.txt @@ -236,6 +236,7 @@ outerbounds Outerbounds overrideable ozaki +ozakione pageview palenight Palenight From dec190e8d12450e88a726afb4c82716a6903c1f3 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 3 Jul 2024 14:42:59 +0200 Subject: [PATCH 12/35] fix css --- .../src/theme/Icon/Socials/Github/index.tsx | 5 +++-- .../src/theme/Icon/Socials/Github/styles.module.css | 9 ++------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx index a3696b7d2a45..4551d3bad48b 100644 --- a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx @@ -7,6 +7,7 @@ import type {SVGProps} from 'react'; +import clsx from 'clsx'; import styles from './styles.module.css'; // SVG Source: https://svgl.app/ @@ -17,9 +18,9 @@ function Github(props: SVGProps): JSX.Element { width="256" height="250" {...props} + className={clsx(props.className, styles.githubSvg)} xmlns="http://www.w3.org/2000/svg" - className={styles.githubSvg} - style={{'--dark': '#fff', '--light': '#000'} as React.CSSProperties} + style={{'--dark': '#000', '--light': '#fff'} as React.CSSProperties} preserveAspectRatio="xMidYMid"> diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/styles.module.css b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/styles.module.css index 08eb56bb1659..716c6cc8efc3 100644 --- a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/styles.module.css @@ -4,16 +4,11 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -.githubSvg { - width: 1.375em; - height: 1.375em; - margin-right: 0.5em; -} [data-theme='dark'] .githubSvg { - fill: var(--dark); + fill: var(--light); } [data-theme='light'] .githubSvg { - fill: var(--light); + fill: var(--dark); } From 39d740316c8da92d87c4ee28e48fbb5a6dfe831b Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:42:21 +0200 Subject: [PATCH 13/35] add dogfood ui --- .../Header/Author/styles.module.css | 1 + .../_blog tests/2024-07-03-dual-author.mdx | 26 +++++++ .../2024-07-03-multiple-authors.mdx | 71 +++++++++++++++++++ .../_blog tests/2024-07-03-single-author.mdx | 18 +++++ 4 files changed, 116 insertions(+) create mode 100644 website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx create mode 100644 website/_dogfooding/_blog tests/2024-07-03-multiple-authors.mdx create mode 100644 website/_dogfooding/_blog tests/2024-07-03-single-author.mdx diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css index 8a2ba3c92a48..7a56000247e3 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css @@ -7,6 +7,7 @@ .authorSocial { display: flex; + flex-wrap: wrap; align-items: center; } diff --git a/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx b/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx new file mode 100644 index 000000000000..d00f93b68715 --- /dev/null +++ b/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx @@ -0,0 +1,26 @@ +--- +title: Dual author socials +authors: + - name: slorber + imageURL: https://github.com/slorber.png + socials: + twitter: sebastienlorber + github: slorber + stackoverflow: https://stackoverflow.com/users/82609/sebastien-lorber + linkedin: https://www.linkedin.com/in/sebastienlorber/ + newsletter: https://thisweekinreact.com/newsletter + - name: slorber + imageURL: https://github.com/slorber.png + socials: + twitter: sebastienlorber + github: slorber + stackoverflow: https://stackoverflow.com/users/82609/sebastien-lorber + linkedin: https://www.linkedin.com/in/sebastienlorber/ + newsletter: https://thisweekinreact.com/newsletter +--- + +# Multiple authors + +## Content + +Content about the blog post diff --git a/website/_dogfooding/_blog tests/2024-07-03-multiple-authors.mdx b/website/_dogfooding/_blog tests/2024-07-03-multiple-authors.mdx new file mode 100644 index 000000000000..ff43e0893268 --- /dev/null +++ b/website/_dogfooding/_blog tests/2024-07-03-multiple-authors.mdx @@ -0,0 +1,71 @@ +--- +title: How multiple authors with socials looks +authors: + - name: slorber + imageURL: https://github.com/slorber.png + socials: + twitter: sebastienlorber + github: slorber + stackoverflow: https://stackoverflow.com/users/82609/sebastien-lorber + linkedin: https://www.linkedin.com/in/sebastienlorber/ + newsletter: https://thisweekinreact.com/newsletter + - name: slorber + imageURL: https://github.com/slorber.png + socials: + twitter: sebastienlorber + - name: slorber + imageURL: https://github.com/slorber.png + title: Docusaurus Maintainer and This Week In React editor + - name: slorber + imageURL: https://github.com/slorber.png + title: Docusaurus Maintainer and This Week In React editor editor editor editor editor editor editor editor + - name: slorber + imageURL: https://github.com/slorber.png + title: Docusaurus Maintainer and This Week In React editor + - name: slorber + imageURL: https://github.com/slorber.png + socials: + twitter: sebastienlorber + github: slorber + - name: slorber + imageURL: https://github.com/slorber.png + socials: + twitter: sebastienlorber + github: slorber + - name: slorber + imageURL: https://github.com/slorber.png + socials: + a: sebastienlorber + b: slorber + c: slorber + d: slorber + e: slorber + f: slorber + g: slorber + h: slorber + i: slorber + j: slorber + k: slorber + l: slorber + - name: slorber + imageURL: https://github.com/slorber.png + socials: + a: sebastienlorber + b: slorber + c: slorber + d: slorber + e: slorber + f: slorber + g: slorber + h: slorber + i: slorber + j: slorber + k: slorber + l: slorber +--- + +# Multiple authors + +## Content + +Content about the blog post diff --git a/website/_dogfooding/_blog tests/2024-07-03-single-author.mdx b/website/_dogfooding/_blog tests/2024-07-03-single-author.mdx new file mode 100644 index 000000000000..03813a689f52 --- /dev/null +++ b/website/_dogfooding/_blog tests/2024-07-03-single-author.mdx @@ -0,0 +1,18 @@ +--- +title: Single author socials +authors: + - name: slorber + imageURL: https://github.com/slorber.png + socials: + twitter: sebastienlorber + github: slorber + stackoverflow: https://stackoverflow.com/users/82609/sebastien-lorber + linkedin: https://www.linkedin.com/in/sebastienlorber/ + newsletter: https://thisweekinreact.com/newsletter +--- + +# Multiple authors + +## Content + +Content about the blog post From 0e19baffcae1a654d0d527b5a1738aba2f857567 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Fri, 5 Jul 2024 15:55:57 +0200 Subject: [PATCH 14/35] add tests --- .../src/__tests__/authors.test.ts | 65 +++++++++++++++++++ .../src/authors.ts | 1 + .../src/authorsSocials.ts | 1 + .../src/plugin-content-blog.d.ts | 7 +- .../src/theme-classic.d.ts | 8 +++ .../BlogPostItem/Header/Author/index.tsx | 2 + .../src/theme/Icon/Socials/X/index.tsx | 29 +++++++++ .../theme/Icon/Socials/X/styles.module.css | 14 ++++ 8 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 packages/docusaurus-theme-classic/src/theme/Icon/Socials/X/index.tsx create mode 100644 packages/docusaurus-theme-classic/src/theme/Icon/Socials/X/styles.module.css diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts index bb55d7b4c4ad..9ca49bf739d0 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts @@ -529,3 +529,68 @@ describe('validateAuthorsMap', () => { ); }); }); + +describe('authors socials', () => { + it('valid known author map socials', () => { + const authorsMap: AuthorsMap = { + ozaki: { + name: 'ozaki', + socials: { + twitter: 'ozakione', + github: 'ozakione', + }, + }, + }; + + expect(validateAuthorsMap(authorsMap)).toEqual(authorsMap); + }); + + it('throw socials that are not strings', () => { + const authorsMap: AuthorsMap = { + ozaki: { + name: 'ozaki', + socials: { + // @ts-expect-error: for tests + twitter: 42, + }, + }, + }; + + expect(() => + validateAuthorsMap(authorsMap), + ).toThrowErrorMatchingInlineSnapshot( + `""ozaki.socials.twitter" must be a string"`, + ); + }); + + it('throw socials that are objects', () => { + const authorsMap: AuthorsMap = { + ozaki: { + name: 'ozaki', + socials: { + // @ts-expect-error: for tests + twitter: {link: 'ozakione'}, + }, + }, + }; + + expect(() => + validateAuthorsMap(authorsMap), + ).toThrowErrorMatchingInlineSnapshot( + `""ozaki.socials.twitter" must be a string"`, + ); + }); + + it('valid unknown author map socials', () => { + const authorsMap: AuthorsMap = { + ozaki: { + name: 'ozaki', + socials: { + random: 'ozakione', + }, + }, + }; + + expect(validateAuthorsMap(authorsMap)).toEqual(authorsMap); + }); +}); diff --git a/packages/docusaurus-plugin-content-blog/src/authors.ts b/packages/docusaurus-plugin-content-blog/src/authors.ts index 61d1be97d4de..2873bbf940c6 100644 --- a/packages/docusaurus-plugin-content-blog/src/authors.ts +++ b/packages/docusaurus-plugin-content-blog/src/authors.ts @@ -31,6 +31,7 @@ const AuthorsMapSchema = Joi.object() github: Joi.string(), linkedin: Joi.string(), stackoverflow: Joi.string(), + x: Joi.string(), }).unknown(), }) .rename('image_url', 'imageURL') diff --git a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts index ec379cd5eb0e..fa770a89ae50 100644 --- a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts +++ b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts @@ -16,6 +16,7 @@ const socialPlatforms: Record = { github: 'https://github.com/', linkedin: 'https://www.linkedin.com/', stackoverflow: 'https://stackoverflow.com/', + x: 'https://x.com/', }; export const normalizeSocials = (value: AuthorSocials): AuthorSocials => { diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index 75437019a569..38b4622c4550 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -43,7 +43,12 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the authorsImageUrls: (string | undefined)[]; }; - type SocialPlatform = 'twitter' | 'github' | 'linkedin' | 'stackoverflow'; + type SocialPlatform = + | 'twitter' + | 'github' + | 'linkedin' + | 'stackoverflow' + | 'x'; export type AuthorSocials = Partial>; diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 36ff2599cf77..a3f3756d2617 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -1530,6 +1530,14 @@ declare module '@theme/Icon/Socials/Github' { export default function Github(props: Props): JSX.Element; } +declare module '@theme/Icon/Socials/X' { + import type {ComponentProps} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function X(props: Props): JSX.Element; +} + declare module '@theme/Icon/Socials/LinkedIn' { import type {ComponentProps} from 'react'; diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx index 9223ff83746e..c14ffe69ba3d 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx @@ -13,6 +13,7 @@ import Link, {type Props as LinkProps} from '@docusaurus/Link'; import type {Props} from '@theme/BlogPostItem/Header/Author'; import Twitter from '@theme/Icon/Socials/Twitter'; import Github from '@theme/Icon/Socials/Github'; +import X from '@theme/Icon/Socials/X'; import StackOverflow from '@theme/Icon/Socials/StackOverflow'; import LinkedIn from '@theme/Icon/Socials/LinkedIn'; import DefaultSocial from '@theme/Icon/Socials/Default'; @@ -30,6 +31,7 @@ const PlatformIconsMap: Record> = { github: Github, stackoverflow: StackOverflow, linkedin: LinkedIn, + x: X, }; function PlatformLink({platform, link}: {platform: string; link: string}) { diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/X/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/X/index.tsx new file mode 100644 index 000000000000..7f066fd0d1f0 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/X/index.tsx @@ -0,0 +1,29 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import type {SVGProps} from 'react'; + +import clsx from 'clsx'; +import styles from './styles.module.css'; + +// SVG Source: https://svgl.app/ +function X(props: SVGProps): JSX.Element { + return ( + + + + ); +} +export default X; diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/X/styles.module.css b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/X/styles.module.css new file mode 100644 index 000000000000..261dadc5b553 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/X/styles.module.css @@ -0,0 +1,14 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +[data-theme='dark'] .xSvg { + fill: var(--light); +} + +[data-theme='light'] .xSvg { + fill: var(--dark); +} From f83e860e987d9f059abac03d3d19205d2f243bfb Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Sat, 6 Jul 2024 13:07:37 +0200 Subject: [PATCH 15/35] fix links --- .../src/plugin-content-blog.d.ts | 2 +- .../2024-07-03-multiple-authors.mdx | 62 +++++++++---------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index 38b4622c4550..e8cc4baa268b 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -81,7 +81,7 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the /** * TODO write a description */ - socials?: Partial> & { + socials?: AuthorSocials & { [customAuthorSocialPlatform: string]: string; }; [customAuthorAttribute: string]: unknown; diff --git a/website/_dogfooding/_blog tests/2024-07-03-multiple-authors.mdx b/website/_dogfooding/_blog tests/2024-07-03-multiple-authors.mdx index ff43e0893268..fc4e62501200 100644 --- a/website/_dogfooding/_blog tests/2024-07-03-multiple-authors.mdx +++ b/website/_dogfooding/_blog tests/2024-07-03-multiple-authors.mdx @@ -4,15 +4,15 @@ authors: - name: slorber imageURL: https://github.com/slorber.png socials: - twitter: sebastienlorber - github: slorber + twitter: https://x.com/sebastienlorber + github: https://github.com/slorber stackoverflow: https://stackoverflow.com/users/82609/sebastien-lorber linkedin: https://www.linkedin.com/in/sebastienlorber/ newsletter: https://thisweekinreact.com/newsletter - name: slorber imageURL: https://github.com/slorber.png socials: - twitter: sebastienlorber + twitter: https://x.com/sebastienlorber - name: slorber imageURL: https://github.com/slorber.png title: Docusaurus Maintainer and This Week In React editor @@ -25,43 +25,43 @@ authors: - name: slorber imageURL: https://github.com/slorber.png socials: - twitter: sebastienlorber - github: slorber + twitter: https://x.com/sebastienlorber + github: https://github.com/slorber - name: slorber imageURL: https://github.com/slorber.png socials: - twitter: sebastienlorber - github: slorber + github: https://github.com/slorber + twitter: https://x.com/sebastienlorber - name: slorber imageURL: https://github.com/slorber.png socials: - a: sebastienlorber - b: slorber - c: slorber - d: slorber - e: slorber - f: slorber - g: slorber - h: slorber - i: slorber - j: slorber - k: slorber - l: slorber + a: https://thisweekinreact.com/newsletter + b: https://thisweekinreact.com/newsletter + c: https://thisweekinreact.com/newsletter + d: https://thisweekinreact.com/newsletter + e: https://thisweekinreact.com/newsletter + f: https://thisweekinreact.com/newsletter + g: https://thisweekinreact.com/newsletter + h: https://thisweekinreact.com/newsletter + i: https://thisweekinreact.com/newsletter + j: https://thisweekinreact.com/newsletter + k: https://thisweekinreact.com/newsletter + l: https://thisweekinreact.com/newsletter - name: slorber imageURL: https://github.com/slorber.png socials: - a: sebastienlorber - b: slorber - c: slorber - d: slorber - e: slorber - f: slorber - g: slorber - h: slorber - i: slorber - j: slorber - k: slorber - l: slorber + a: https://thisweekinreact.com/newsletter + b: https://thisweekinreact.com/newsletter + c: https://thisweekinreact.com/newsletter + d: https://thisweekinreact.com/newsletter + e: https://thisweekinreact.com/newsletter + f: https://thisweekinreact.com/newsletter + g: https://thisweekinreact.com/newsletter + h: https://thisweekinreact.com/newsletter + i: https://thisweekinreact.com/newsletter + j: https://thisweekinreact.com/newsletter + k: https://thisweekinreact.com/newsletter + l: https://thisweekinreact.com/newsletter --- # Multiple authors From bb08c728871113c17ce607c5680a2b9bf32350d7 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Sat, 6 Jul 2024 13:32:41 +0200 Subject: [PATCH 16/35] fix links --- .../_dogfooding/_blog tests/2024-07-03-dual-author.mdx | 8 ++++---- .../_dogfooding/_blog tests/2024-07-03-single-author.mdx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx b/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx index d00f93b68715..16e144e86ce3 100644 --- a/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx +++ b/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx @@ -4,16 +4,16 @@ authors: - name: slorber imageURL: https://github.com/slorber.png socials: - twitter: sebastienlorber - github: slorber + twitter: https://x.com/sebastienlorber + github: https://github.com/slorber stackoverflow: https://stackoverflow.com/users/82609/sebastien-lorber linkedin: https://www.linkedin.com/in/sebastienlorber/ newsletter: https://thisweekinreact.com/newsletter - name: slorber imageURL: https://github.com/slorber.png socials: - twitter: sebastienlorber - github: slorber + twitter: https://x.com/sebastienlorber + github: https://github.com/slorber stackoverflow: https://stackoverflow.com/users/82609/sebastien-lorber linkedin: https://www.linkedin.com/in/sebastienlorber/ newsletter: https://thisweekinreact.com/newsletter diff --git a/website/_dogfooding/_blog tests/2024-07-03-single-author.mdx b/website/_dogfooding/_blog tests/2024-07-03-single-author.mdx index 03813a689f52..004f6e89d99a 100644 --- a/website/_dogfooding/_blog tests/2024-07-03-single-author.mdx +++ b/website/_dogfooding/_blog tests/2024-07-03-single-author.mdx @@ -4,8 +4,8 @@ authors: - name: slorber imageURL: https://github.com/slorber.png socials: - twitter: sebastienlorber - github: slorber + twitter: https://x.com/sebastienlorber + github: https://github.com/slorber stackoverflow: https://stackoverflow.com/users/82609/sebastien-lorber linkedin: https://www.linkedin.com/in/sebastienlorber/ newsletter: https://thisweekinreact.com/newsletter From 45e495082fe713dd2892591e30758d969ba5c1b3 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 11 Jul 2024 14:44:58 +0200 Subject: [PATCH 17/35] adjust design of blog author social icons --- .../src/theme-classic.d.ts | 3 +- .../BlogPostItem/Header/Author/index.tsx | 50 ++++++++++--------- .../Header/Author/styles.module.css | 47 +++++++++++++++-- .../BlogPostItem/Header/Authors/index.tsx | 4 +- .../Header/Authors/styles.module.css | 1 - .../src/theme/Icon/Socials/Github/index.tsx | 4 +- .../_blog tests/2024-07-03-dual-author.mdx | 6 +-- .../2024-07-03-multiple-authors.mdx | 44 ++++++++++++---- .../_blog tests/2024-07-03-single-author.mdx | 6 ++- website/_dogfooding/dogfooding.config.ts | 1 + website/blog/authors.yml | 2 +- 11 files changed, 118 insertions(+), 50 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index a3f3756d2617..9dadb2463fda 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -296,6 +296,7 @@ declare module '@theme/BlogPostItem/Header/Author' { export interface Props { readonly author: PropBlogPostContent['metadata']['authors'][number]; + readonly singleAuthor: boolean; readonly className?: string; } @@ -1551,7 +1552,7 @@ declare module '@theme/Icon/Socials/Default' { export interface Props extends ComponentProps<'svg'> {} - export default function DefaultSocial(props: Props): JSX.Element; + export default function DefaultSocialIcon(props: Props): JSX.Element; } declare module '@theme/Icon/Socials/StackOverflow' { diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx index c14ffe69ba3d..ec135ad53d15 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx @@ -16,7 +16,7 @@ import Github from '@theme/Icon/Socials/Github'; import X from '@theme/Icon/Socials/X'; import StackOverflow from '@theme/Icon/Socials/StackOverflow'; import LinkedIn from '@theme/Icon/Socials/LinkedIn'; -import DefaultSocial from '@theme/Icon/Socials/Default'; +import DefaultSocialIcon from '@theme/Icon/Socials/Default'; import styles from './styles.module.css'; function MaybeLink(props: LinkProps): JSX.Element { @@ -34,33 +34,40 @@ const PlatformIconsMap: Record> = { x: X, }; -function PlatformLink({platform, link}: {platform: string; link: string}) { - const Icon = PlatformIconsMap[platform] ?? DefaultSocial; +function SocialLink({platform, link}: {platform: string; link: string}) { + const Icon = PlatformIconsMap[platform] ?? DefaultSocialIcon; return ( - - + + ); } +function AuthorSocials({author}: {author: Props['author']}) { + return
+ {Object.entries(author.socials ?? {}).map(([platform, linkUrl]) => { + return ; + })} +
+} + +function AuthorTitle({title}: {title: string}) { + return ( + + {title} + + ); +} + export default function BlogPostItemHeaderAuthor({ + // singleAuthor, author, className, }: Props): JSX.Element { const {name, title, url, socials, imageURL, email} = author; const link = url || (email && `mailto:${email}`) || undefined; - const renderSocialMedia = () => ( -
- {Object.entries(socials ?? {}).map(([platform, linkUrl]) => { - return ( - - ); - })} -
- ); - - const hasSocialMedia = socials && Object.keys(socials).length > 0; + const hasSocials = socials && Object.keys(socials).length > 0; return (
@@ -70,18 +77,15 @@ export default function BlogPostItemHeaderAuthor({ )} - {name && ( + {(name || title) && (
- {name} + {name}
- {hasSocialMedia ? ( - renderSocialMedia() - ) : ( - {title} - )} + {!!title && } + {hasSocials && }
)}
diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css index 7a56000247e3..044f7e582ad5 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css @@ -5,14 +5,51 @@ * LICENSE file in the root directory of this source tree. */ -.authorSocial { +:root { + --docusaurus-blog-social-icon-size: 1rem; +} + +.authorName { + font-size: 1.1rem; +} + +.singleAuthor .authorName { + font-size: 1.3rem; +} + +.authorSocials { + margin-top: 0.2rem; + display: flex; flex-wrap: wrap; align-items: center; + line-height: 0; + + overflow: hidden; + line-clamp: 1; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; +} + +.authorSocialLink { + height: var(--docusaurus-blog-social-icon-size); + width: var(--docusaurus-blog-social-icon-size); + line-height: 0; + margin-right: 0.2rem; +} + +.authorSocialIcon { + width: var(--docusaurus-blog-social-icon-size); + height: var(--docusaurus-blog-social-icon-size); } -.socialIcon { - width: 1.375em; - height: 1.375em; - margin-right: 0.5em; +.authorTitle { + margin-top: 0.06rem; + font-size: 0.8rem; + line-height: 0.8rem; + display: -webkit-box; + overflow: hidden; + line-clamp: 1; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; } diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Authors/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Authors/index.tsx index d1ed5bb11cdd..9402f493b9e1 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Authors/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Authors/index.tsx @@ -25,6 +25,7 @@ export default function BlogPostItemHeaderAuthors({ return null; } const imageOnly = authors.every(({name}) => !name); + const singleAuthor = authors.length === 1; return (
(
): JSX.Element { return ( Date: Thu, 11 Jul 2024 12:49:36 +0000 Subject: [PATCH 18/35] refactor: apply lint autofix --- .../src/theme/BlogPostItem/Header/Author/index.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx index ec135ad53d15..4d11bdeb0a4d 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx @@ -44,11 +44,13 @@ function SocialLink({platform, link}: {platform: string; link: string}) { } function AuthorSocials({author}: {author: Props['author']}) { - return
- {Object.entries(author.socials ?? {}).map(([platform, linkUrl]) => { - return ; - })} -
+ return ( +
+ {Object.entries(author.socials ?? {}).map(([platform, linkUrl]) => { + return ; + })} +
+ ); } function AuthorTitle({title}: {title: string}) { From eb5522f006cb208dea538709230628ede18aa7d4 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 11 Jul 2024 14:57:20 +0200 Subject: [PATCH 19/35] correct casing for GitHub --- .../src/theme-classic.d.ts | 2 +- .../theme/BlogPostItem/Header/Author/index.tsx | 16 +++++++++------- .../Icon/Socials/{Github => GitHub}/index.tsx | 4 ++-- .../Socials/{Github => GitHub}/styles.module.css | 0 4 files changed, 12 insertions(+), 10 deletions(-) rename packages/docusaurus-theme-classic/src/theme/Icon/Socials/{Github => GitHub}/index.tsx (96%) rename packages/docusaurus-theme-classic/src/theme/Icon/Socials/{Github => GitHub}/styles.module.css (100%) diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 9dadb2463fda..c45442cd31e1 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -1523,7 +1523,7 @@ declare module '@theme/Icon/Socials/Twitter' { export default function Twitter(props: Props): JSX.Element; } -declare module '@theme/Icon/Socials/Github' { +declare module '@theme/Icon/Socials/GitHub' { import type {ComponentProps} from 'react'; export interface Props extends ComponentProps<'svg'> {} diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx index ec135ad53d15..4032244f49b7 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx @@ -12,7 +12,7 @@ import Link, {type Props as LinkProps} from '@docusaurus/Link'; import type {Props} from '@theme/BlogPostItem/Header/Author'; import Twitter from '@theme/Icon/Socials/Twitter'; -import Github from '@theme/Icon/Socials/Github'; +import GitHub from '@theme/Icon/Socials/GitHub'; import X from '@theme/Icon/Socials/X'; import StackOverflow from '@theme/Icon/Socials/StackOverflow'; import LinkedIn from '@theme/Icon/Socials/LinkedIn'; @@ -28,7 +28,7 @@ function MaybeLink(props: LinkProps): JSX.Element { const PlatformIconsMap: Record> = { twitter: Twitter, - github: Github, + github: GitHub, stackoverflow: StackOverflow, linkedin: LinkedIn, x: X, @@ -44,11 +44,13 @@ function SocialLink({platform, link}: {platform: string; link: string}) { } function AuthorSocials({author}: {author: Props['author']}) { - return
- {Object.entries(author.socials ?? {}).map(([platform, linkUrl]) => { - return ; - })} -
+ return ( +
+ {Object.entries(author.socials ?? {}).map(([platform, linkUrl]) => { + return ; + })} +
+ ); } function AuthorTitle({title}: {title: string}) { diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/GitHub/index.tsx similarity index 96% rename from packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx rename to packages/docusaurus-theme-classic/src/theme/Icon/Socials/GitHub/index.tsx index ba8402082f76..b20fd337c529 100644 --- a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/GitHub/index.tsx @@ -11,7 +11,7 @@ import clsx from 'clsx'; import styles from './styles.module.css'; // SVG Source: https://svgl.app/ -function Github(props: SVGProps): JSX.Element { +function GitHub(props: SVGProps): JSX.Element { return ( ): JSX.Element { ); } -export default Github; +export default GitHub; diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/styles.module.css b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/GitHub/styles.module.css similarity index 100% rename from packages/docusaurus-theme-classic/src/theme/Icon/Socials/Github/styles.module.css rename to packages/docusaurus-theme-classic/src/theme/Icon/Socials/GitHub/styles.module.css From 342948143498d65d593a7f66299d7325efb43113 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 11 Jul 2024 18:28:26 +0200 Subject: [PATCH 20/35] Fix Icon/Socials swizzle config --- .../docusaurus-theme-classic/src/getSwizzleConfig.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/docusaurus-theme-classic/src/getSwizzleConfig.ts b/packages/docusaurus-theme-classic/src/getSwizzleConfig.ts index f3761d8857cb..1b0a871197e2 100644 --- a/packages/docusaurus-theme-classic/src/getSwizzleConfig.ts +++ b/packages/docusaurus-theme-classic/src/getSwizzleConfig.ts @@ -289,6 +289,17 @@ export default function getSwizzleConfig(): SwizzleConfig { }, description: 'The menu icon component', }, + 'Icon/Socials': { + actions: { + // Forbidden because it's a parent folder, makes the CLI crash atm + // TODO the CLI should rather support --eject + // Subfolders can be swizzled + eject: 'forbidden', + wrap: 'forbidden', + }, + description: + 'The Icon/Socials folder is not directly swizzle-able, but you can swizzle its sub-components.', + }, MDXComponents: { actions: { eject: 'safe', From 7905a5bafe75c7e7be20f7b7a40bf88289d4dfd0 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 11 Jul 2024 18:43:25 +0200 Subject: [PATCH 21/35] fix blog author socials --- website/blog/authors.yml | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/website/blog/authors.yml b/website/blog/authors.yml index 4bad05575e99..965d9bf94d05 100644 --- a/website/blog/authors.yml +++ b/website/blog/authors.yml @@ -4,22 +4,24 @@ JMarcey: url: https://twitter.com/JoelMarcey image_url: https://github.com/JoelMarcey.png email: jimarcey@gmail.com - twitter: JoelMarcey + socials: + x: joelmarcey + github: JoelMarcey zpao: name: Paul O’Shannessy title: Engineering Manager at Meta - url: https://twitter.com/zpao + url: https://x.com/zpao image_url: https://github.com/zpao.png - email: jimarcey@gmail.com - twitter: zpao + socials: + x: zpao + github: zpao slorber: name: Sébastien Lorber title: Docusaurus maintainer, This Week In React editor url: https://thisweekinreact.com image_url: https://github.com/slorber.png - email: sebastien@thisweekinreact.com socials: x: sebastienlorber github: slorber @@ -30,8 +32,10 @@ yangshun: title: Front End Engineer at Meta url: https://github.com/yangshun image_url: https://github.com/yangshun.png - twitter: yangshunz email: tay.yang.shun@gmail.com + socials: + x: yangshunz + github: yangshun lex111: name: Alexey Pyltsyn @@ -52,17 +56,19 @@ endiliey: title: Maintainer of Docusaurus url: https://github.com/endiliey image_url: https://github.com/endiliey.png - twitter: endiliey abernathyca: name: Christine Abernathy - url: http://twitter.com/abernathyca + url: http://x.com/abernathyca image_url: https://github.com/caabernathy.png - twitter: abernathyca + socials: + x: abernathyca shortcuts: name: Clément Vannicatte title: Software Engineer @ Algolia url: https://github.com/shortcuts image_url: https://github.com/shortcuts.png - twitter: sh0rtcts + socials: + x: sh0rtcts + github: shortcuts From fd2b81a5c9aeca15ef9de1c176784c488028b3e6 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 11 Jul 2024 18:49:38 +0200 Subject: [PATCH 22/35] add test case for normalizeSocials --- .../src/__tests__/authorsSocials.test.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts index 6b689a2fbee3..1888be8df99a 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts @@ -96,4 +96,13 @@ describe('normalizeSocials', () => { expect(normalizeSocials(socials)).toEqual(socials); }); + + it('allow unknown social platforms urls', () => { + const socials: AuthorSocials = { + twitch: 'https://www.twitch.tv/sebastienlorber', + newsletter: 'https://thisweekinreact.com', + }; + + expect(normalizeSocials(socials)).toEqual(socials); + }); }); From 8641befd4bf9d009aa5befdaeac6090c211433fa Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 11 Jul 2024 19:21:14 +0200 Subject: [PATCH 23/35] Ensure author socials normalization is wired properly --- .../__fixtures__/authorsMapFiles/authors.yml | 8 ++- .../2018-12-14-Happy-First-Birthday-Slash.md | 3 + .../__fixtures__/website/blog/authors.yml | 4 ++ .../src/__tests__/authors.test.ts | 67 +++++++++++++++++++ .../src/authors.ts | 28 ++++++-- .../src/blogUtils.ts | 8 --- .../docusaurus-utils/src/dataFileUtils.ts | 1 + .../_blog tests/2024-07-03-dual-author.mdx | 8 +-- 8 files changed, 107 insertions(+), 20 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/authorsMapFiles/authors.yml b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/authorsMapFiles/authors.yml index ac09421385d9..62f84790dade 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/authorsMapFiles/authors.yml +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/authorsMapFiles/authors.yml @@ -4,15 +4,19 @@ JMarcey: title: Technical Lead & Developer Advocate at Facebook url: http://twitter.com/JoelMarcey image_url: https://github.com/JoelMarcey.png - twitter: JoelMarcey + socials: + twitter: https://twitter.com/JoelMarcey + x: https://x.com/JoelMarcey slorber: name: Sébastien Lorber title: Docusaurus maintainer url: https://sebastienlorber.com image_url: https://github.com/slorber.png - twitter: sebastienlorber email: lorber.sebastien@gmail.com + socials: + twitter: sebastienlorber + x: sebastienlorber yangshun: name: Yangshun Tay diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/2018-12-14-Happy-First-Birthday-Slash.md b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/2018-12-14-Happy-First-Birthday-Slash.md index 10ba9373aa47..b8b206e3fb92 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/2018-12-14-Happy-First-Birthday-Slash.md +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/2018-12-14-Happy-First-Birthday-Slash.md @@ -2,6 +2,9 @@ title: Happy 1st Birthday Slash! authors: - name: Yangshun Tay + socials: + x: https://x.com/yangshunz + github: yangshun - slorber tags: [birthday,inlineTag,globalTag] --- diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/authors.yml b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/authors.yml index a704e9e9841b..c44d2ee68da6 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/authors.yml +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/blog/authors.yml @@ -3,3 +3,7 @@ slorber: title: Docusaurus maintainer email: lorber.sebastien@gmail.com url: https://sebastienlorber.com + socials: + twitter: sebastienlorber + x: https://x.com/sebastienlorber + github: slorber diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts index 9ca49bf739d0..51576d635a55 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts @@ -255,6 +255,52 @@ describe('getBlogPostAuthors', () => { ]); }); + it('can normalize inline authors', () => { + expect( + getBlogPostAuthors({ + frontMatter: { + authors: [ + { + name: 'Seb1', + socials: { + x: 'https://x.com/sebastienlorber', + twitter: 'sebastienlorber', + github: 'slorber', + }, + }, + { + name: 'Seb2', + socials: { + x: 'sebastienlorber', + twitter: 'https://twitter.com/sebastienlorber', + github: 'https://github.com/slorber', + }, + }, + ], + }, + authorsMap: {}, + baseUrl: '/', + }), + ).toEqual([ + { + name: 'Seb1', + socials: { + x: 'https://x.com/sebastienlorber', + twitter: 'https://twitter.com/sebastienlorber', + github: 'https://github.com/slorber', + }, + }, + { + name: 'Seb2', + socials: { + x: 'https://x.com/sebastienlorber', + twitter: 'https://twitter.com/sebastienlorber', + github: 'https://github.com/slorber', + }, + }, + ]); + }); + it('throw when using author key with no authorsMap', () => { expect(() => getBlogPostAuthors({ @@ -412,6 +458,27 @@ describe('getAuthorsMap', () => { }), ).resolves.toBeUndefined(); }); + + describe('getAuthorsMap returns normalized', () => { + it('socials', async () => { + const authorsMap = await getAuthorsMap({ + contentPaths, + authorsMapPath: 'authors.yml', + }); + expect(authorsMap.slorber.socials).toMatchInlineSnapshot(` + { + "twitter": "https://twitter.com/sebastienlorber", + "x": "https://x.com/sebastienlorber", + } + `); + expect(authorsMap.JMarcey.socials).toMatchInlineSnapshot(` + { + "twitter": "https://twitter.com/JoelMarcey", + "x": "https://x.com/JoelMarcey", + } + `); + }); + }); }); describe('validateAuthorsMap', () => { diff --git a/packages/docusaurus-plugin-content-blog/src/authors.ts b/packages/docusaurus-plugin-content-blog/src/authors.ts index 2873bbf940c6..557180279a06 100644 --- a/packages/docusaurus-plugin-content-blog/src/authors.ts +++ b/packages/docusaurus-plugin-content-blog/src/authors.ts @@ -5,8 +5,10 @@ * LICENSE file in the root directory of this source tree. */ +import * as _ from 'lodash'; import {getDataFileData, normalizeUrl} from '@docusaurus/utils'; import {Joi, URISchema} from '@docusaurus/utils-validation'; +import {normalizeSocials} from './authorsSocials'; import type {BlogContentPaths} from './types'; import type { Author, @@ -58,18 +60,32 @@ export function validateAuthorsMap(content: unknown): AuthorsMap { return value; } +function normalizeAuthor(author: Author): Author { + return { + ...author, + socials: author.socials ? normalizeSocials(author.socials) : undefined, + }; +} + +function normalizeAuthorsMap(authorsMap: AuthorsMap): AuthorsMap { + return _.mapValues(authorsMap, normalizeAuthor); +} + export async function getAuthorsMap(params: { authorsMapPath: string; contentPaths: BlogContentPaths; }): Promise { - return getDataFileData( + const authorsMap = await getDataFileData( { filePath: params.authorsMapPath, contentPaths: params.contentPaths, fileType: 'authors map', }, + // TODO annoying to test: tightly coupled FS reads + validation... validateAuthorsMap, ); + + return authorsMap ? normalizeAuthorsMap(authorsMap) : undefined; } type AuthorsParam = { @@ -122,7 +138,7 @@ function getFrontMatterAuthorLegacy({ function normalizeFrontMatterAuthors( frontMatterAuthors: BlogPostFrontMatterAuthors = [], ): BlogPostFrontMatterAuthor[] { - function normalizeAuthor( + function normalizeFrontMatterAuthor( authorInput: string | Author, ): BlogPostFrontMatterAuthor { if (typeof authorInput === 'string') { @@ -135,8 +151,8 @@ function normalizeFrontMatterAuthors( } return Array.isArray(frontMatterAuthors) - ? frontMatterAuthors.map(normalizeAuthor) - : [normalizeAuthor(frontMatterAuthors)]; + ? frontMatterAuthors.map(normalizeFrontMatterAuthor) + : [normalizeFrontMatterAuthor(frontMatterAuthors)]; } function getFrontMatterAuthors(params: AuthorsParam): Author[] { @@ -165,11 +181,11 @@ ${Object.keys(authorsMap) } function toAuthor(frontMatterAuthor: BlogPostFrontMatterAuthor): Author { - return { + return normalizeAuthor({ // Author def from authorsMap can be locally overridden by front matter ...getAuthorsMapAuthor(frontMatterAuthor.key), ...frontMatterAuthor, - }; + }); } return frontMatterAuthors.map(toAuthor); diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 3e3d2994e66f..68f429cc8c0c 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -31,7 +31,6 @@ import {getTagsFile} from '@docusaurus/utils-validation'; import {validateBlogPostFrontMatter} from './frontMatter'; import {type AuthorsMap, getAuthorsMap, getBlogPostAuthors} from './authors'; import {reportAuthorsProblems} from './authorsProblems'; -import {normalizeSocials} from './authorsSocials'; import type {TagsFile} from '@docusaurus/utils'; import type {LoadContext, ParseFrontMatter} from '@docusaurus/types'; import type { @@ -384,13 +383,6 @@ export async function generateBlogPosts( authorsMapPath: options.authorsMapPath, }); - if (authorsMap) { - Object.entries(authorsMap).forEach(([, author]) => { - if (author.socials) { - author.socials = normalizeSocials(author.socials); - } - }); - } const tagsFile = await getTagsFile({contentPaths, tags: options.tags}); async function doProcessBlogSourceFile(blogSourceFile: string) { diff --git a/packages/docusaurus-utils/src/dataFileUtils.ts b/packages/docusaurus-utils/src/dataFileUtils.ts index 937d22b9cf2b..ba671d6e8875 100644 --- a/packages/docusaurus-utils/src/dataFileUtils.ts +++ b/packages/docusaurus-utils/src/dataFileUtils.ts @@ -63,6 +63,7 @@ export async function getDataFileData( try { const contentString = await fs.readFile(filePath, {encoding: 'utf8'}); const unsafeContent = Yaml.load(contentString); + // TODO we shouldn't validate here: it makes validation harder to test return validate(unsafeContent); } catch (err) { logger.error`The ${params.fileType} file at path=${filePath} looks invalid.`; diff --git a/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx b/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx index 00c6adc18130..025001460de1 100644 --- a/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx +++ b/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx @@ -4,10 +4,10 @@ authors: - name: Sébastien Lorber imageURL: https://github.com/slorber.png socials: - twitter: https://x.com/sebastienlorber - github: https://github.com/slorber - stackoverflow: https://stackoverflow.com/users/82609/sebastien-lorber - linkedin: https://www.linkedin.com/in/sebastienlorber/ + twitter: sebastienlorber + github: slorber + stackoverflow: /users/82609/sebastien-lorber + linkedin: sebastienlorber newsletter: https://thisweekinreact.com/newsletter - name: Sébastien Lorber imageURL: https://github.com/slorber.png From 9ed1e6a877aad639a7f7d164facd2c82e0a129f1 Mon Sep 17 00:00:00 2001 From: slorber Date: Thu, 11 Jul 2024 17:26:40 +0000 Subject: [PATCH 24/35] refactor: apply lint autofix --- project-words.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/project-words.txt b/project-words.txt index cc65e25d344e..af729e8ade47 100644 --- a/project-words.txt +++ b/project-words.txt @@ -145,6 +145,7 @@ javadoc jiti jmarcey jodyheavener +joelmarcey joshcena jssdk Kaszubowski From ccc6a04d15d4d1f89e36f0e54c0d7f77deb77661 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 11 Jul 2024 19:58:40 +0200 Subject: [PATCH 25/35] Extract AuthorSocials component + fix JS comments + docs --- .../src/authorsSocials.ts | 8 ++- .../src/plugin-content-blog.d.ts | 28 +++++++-- .../src/theme-classic.d.ts | 17 +++++- .../Header/Author/Socials/index.tsx | 61 +++++++++++++++++++ .../Header/Author/Socials/styles.module.css | 34 +++++++++++ .../BlogPostItem/Header/Author/index.tsx | 37 +---------- .../Header/Author/styles.module.css | 34 ----------- .../docs/api/plugins/plugin-content-blog.mdx | 10 +++ website/docs/blog.mdx | 21 +++++++ 9 files changed, 170 insertions(+), 80 deletions(-) create mode 100644 packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/Socials/index.tsx create mode 100644 packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/Socials/styles.module.css diff --git a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts index fa770a89ae50..2ec75b7e3fbb 100644 --- a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts +++ b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts @@ -8,10 +8,10 @@ import {normalizeUrl} from '@docusaurus/utils'; import type { AuthorSocials, - SocialPlatform, + SocialPlatformKey, } from '@docusaurus/plugin-content-blog'; -const socialPlatforms: Record = { +const socialPlatforms: Record = { twitter: 'https://twitter.com/', github: 'https://github.com/', linkedin: 'https://www.linkedin.com/', @@ -19,8 +19,10 @@ const socialPlatforms: Record = { x: 'https://x.com/', }; +const SocialPlatformKeys = Object.keys(socialPlatforms) as SocialPlatformKey[]; + export const normalizeSocials = (value: AuthorSocials): AuthorSocials => { - (Object.keys(socialPlatforms) as SocialPlatform[]).forEach((platform) => { + SocialPlatformKeys.forEach((platform) => { if ( value[platform] && !value[platform]!.startsWith(socialPlatforms[platform]) diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts index e8cc4baa268b..589a5e93b169 100644 --- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts +++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts @@ -43,14 +43,28 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the authorsImageUrls: (string | undefined)[]; }; - type SocialPlatform = + /** + * Note we don't pre-define all possible platforms + * Users can add their own custom platforms if needed + */ + export type SocialPlatformKey = | 'twitter' | 'github' | 'linkedin' | 'stackoverflow' | 'x'; - export type AuthorSocials = Partial>; + /** + * Social platforms of the author. + * The record value is usually the fully qualified link of the social profile. + * For pre-defined platforms, it's possible to pass a handle instead + */ + export type AuthorSocials = Partial> & { + /** + * Unknown keys are allowed: users can pass additional social platforms + */ + [customAuthorSocialPlatform: string]: string; + }; export type Author = { key?: string; // TODO temporary, need refactor @@ -79,11 +93,13 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the */ email?: string; /** - * TODO write a description + * Social platforms of the author + * Usually displayed as a list of social icon links. + */ + socials?: AuthorSocials; + /** + * Unknown keys are allowed, so that we can pass custom fields to authors, */ - socials?: AuthorSocials & { - [customAuthorSocialPlatform: string]: string; - }; [customAuthorAttribute: string]: unknown; }; diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index c45442cd31e1..142a229862f9 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -292,10 +292,10 @@ declare module '@theme/BlogPostItem/Header/Info' { } declare module '@theme/BlogPostItem/Header/Author' { - import type {PropBlogPostContent} from '@docusaurus/plugin-content-blog'; + import type {Author} from '@docusaurus/plugin-content-blog'; export interface Props { - readonly author: PropBlogPostContent['metadata']['authors'][number]; + readonly author: Author; readonly singleAuthor: boolean; readonly className?: string; } @@ -303,6 +303,19 @@ declare module '@theme/BlogPostItem/Header/Author' { export default function BlogPostItemHeaderAuthor(props: Props): JSX.Element; } +declare module '@theme/BlogPostItem/Header/Author/Socials' { + import type {Author} from '@docusaurus/plugin-content-blog'; + + export interface Props { + readonly author: Author; + readonly className?: string; + } + + export default function BlogPostItemHeaderAuthorSocials( + props: Props, + ): JSX.Element; +} + declare module '@theme/BlogPostItem/Header/Authors' { export interface Props { readonly className?: string; diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/Socials/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/Socials/index.tsx new file mode 100644 index 000000000000..55866b14f2c2 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/Socials/index.tsx @@ -0,0 +1,61 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import type {ComponentType} from 'react'; +import React from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import type {Props} from '@theme/BlogPostItem/Header/Author/Socials'; + +import Twitter from '@theme/Icon/Socials/Twitter'; +import GitHub from '@theme/Icon/Socials/GitHub'; +import X from '@theme/Icon/Socials/X'; +import StackOverflow from '@theme/Icon/Socials/StackOverflow'; +import LinkedIn from '@theme/Icon/Socials/LinkedIn'; +import DefaultSocialIcon from '@theme/Icon/Socials/Default'; + +import styles from './styles.module.css'; + +type SocialIcon = ComponentType<{className: string}>; + +type SocialPlatformConfig = {Icon: SocialIcon; label: string}; + +const SocialPlatformConfigs: Record = { + twitter: {Icon: Twitter, label: 'Twitter'}, + github: {Icon: GitHub, label: 'GitHub'}, + stackoverflow: {Icon: StackOverflow, label: 'Stack Overflow'}, + linkedin: {Icon: LinkedIn, label: 'LinkedIn'}, + x: {Icon: X, label: 'X'}, +}; + +function getSocialPlatformConfig(platformKey: string): SocialPlatformConfig { + return ( + SocialPlatformConfigs[platformKey] ?? { + Icon: DefaultSocialIcon, + label: platformKey, + } + ); +} + +function SocialLink({platform, link}: {platform: string; link: string}) { + const {Icon, label} = getSocialPlatformConfig(platform); + return ( + + + + ); +} + +export default function AuthorSocials({author}: {author: Props['author']}) { + return ( +
+ {Object.entries(author.socials ?? {}).map(([platform, linkUrl]) => { + return ; + })} +
+ ); +} diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/Socials/styles.module.css b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/Socials/styles.module.css new file mode 100644 index 000000000000..583f120571ac --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/Socials/styles.module.css @@ -0,0 +1,34 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +:root { + --docusaurus-blog-social-icon-size: 1rem; +} + +.authorSocials { + margin-top: 0.2rem; + display: flex; + flex-wrap: wrap; + align-items: center; + line-height: 0; + overflow: hidden; + line-clamp: 1; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; +} + +.authorSocialLink { + height: var(--docusaurus-blog-social-icon-size); + width: var(--docusaurus-blog-social-icon-size); + line-height: 0; + margin-right: 0.2rem; +} + +.authorSocialIcon { + width: var(--docusaurus-blog-social-icon-size); + height: var(--docusaurus-blog-social-icon-size); +} diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx index 4032244f49b7..0e81c7a42675 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx @@ -5,18 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -import type {ComponentType} from 'react'; import React from 'react'; import clsx from 'clsx'; import Link, {type Props as LinkProps} from '@docusaurus/Link'; +import AuthorSocials from '@theme/BlogPostItem/Header/Author/Socials'; import type {Props} from '@theme/BlogPostItem/Header/Author'; -import Twitter from '@theme/Icon/Socials/Twitter'; -import GitHub from '@theme/Icon/Socials/GitHub'; -import X from '@theme/Icon/Socials/X'; -import StackOverflow from '@theme/Icon/Socials/StackOverflow'; -import LinkedIn from '@theme/Icon/Socials/LinkedIn'; -import DefaultSocialIcon from '@theme/Icon/Socials/Default'; import styles from './styles.module.css'; function MaybeLink(props: LinkProps): JSX.Element { @@ -26,33 +20,6 @@ function MaybeLink(props: LinkProps): JSX.Element { return <>{props.children}; } -const PlatformIconsMap: Record> = { - twitter: Twitter, - github: GitHub, - stackoverflow: StackOverflow, - linkedin: LinkedIn, - x: X, -}; - -function SocialLink({platform, link}: {platform: string; link: string}) { - const Icon = PlatformIconsMap[platform] ?? DefaultSocialIcon; - return ( - - - - ); -} - -function AuthorSocials({author}: {author: Props['author']}) { - return ( -
- {Object.entries(author.socials ?? {}).map(([platform, linkUrl]) => { - return ; - })} -
- ); -} - function AuthorTitle({title}: {title: string}) { return ( @@ -62,7 +29,7 @@ function AuthorTitle({title}: {title: string}) { } export default function BlogPostItemHeaderAuthor({ - // singleAuthor, + // singleAuthor, // may be useful in the future, or for swizzle users author, className, }: Props): JSX.Element { diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css index 044f7e582ad5..21ea5d40dc89 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/styles.module.css @@ -5,44 +5,10 @@ * LICENSE file in the root directory of this source tree. */ -:root { - --docusaurus-blog-social-icon-size: 1rem; -} - .authorName { font-size: 1.1rem; } -.singleAuthor .authorName { - font-size: 1.3rem; -} - -.authorSocials { - margin-top: 0.2rem; - - display: flex; - flex-wrap: wrap; - align-items: center; - line-height: 0; - - overflow: hidden; - line-clamp: 1; - -webkit-line-clamp: 1; - -webkit-box-orient: vertical; -} - -.authorSocialLink { - height: var(--docusaurus-blog-social-icon-size); - width: var(--docusaurus-blog-social-icon-size); - line-height: 0; - margin-right: 0.2rem; -} - -.authorSocialIcon { - width: var(--docusaurus-blog-social-icon-size); - height: var(--docusaurus-blog-social-icon-size); -} - .authorTitle { margin-top: 0.06rem; font-size: 0.8rem; diff --git a/website/docs/api/plugins/plugin-content-blog.mdx b/website/docs/api/plugins/plugin-content-blog.mdx index c8931e4222c9..2eb10ccfb42c 100644 --- a/website/docs/api/plugins/plugin-content-blog.mdx +++ b/website/docs/api/plugins/plugin-content-blog.mdx @@ -251,12 +251,19 @@ type Tag = string | {label: string; permalink: string}; // An author key references an author from the global plugin authors.yml file type AuthorKey = string; +// Social platform name -> Social platform link +// Example: {MyPlatform: 'https://myplatform.com/myusername'} +// Pre-defined platforms ("x", "github", "twitter", "linkedin", "stackoverflow") accept handles: +// Example: {github: 'slorber'} +type AuthorSocials = Record; + type Author = { key?: AuthorKey; name: string; title?: string; url?: string; image_url?: string; + socials?: AuthorSocials; }; // The front matter authors field allows various possible shapes @@ -275,6 +282,9 @@ authors: title: Co-creator of Docusaurus 1 url: https://github.com/JoelMarcey image_url: https://github.com/JoelMarcey.png + socials: + x: joelmarcey + github: JoelMarcey tags: [docusaurus] description: This is my first post on Docusaurus. image: https://i.imgur.com/mErPwqL.png diff --git a/website/docs/blog.mdx b/website/docs/blog.mdx index 75e4fa09a978..8ec62d11fea7 100644 --- a/website/docs/blog.mdx +++ b/website/docs/blog.mdx @@ -52,10 +52,16 @@ authors: title: Co-creator of Docusaurus 1 url: https://github.com/JoelMarcey image_url: https://github.com/JoelMarcey.png + socials: + x: joelmarcey + github: JoelMarcey - name: Sébastien Lorber title: Docusaurus maintainer url: https://sebastienlorber.com image_url: https://github.com/slorber.png + socials: + x: sebastienlorber + github: slorber tags: [hello, docusaurus-v2] image: https://i.imgur.com/mErPwqL.png hide_table_of_contents: false @@ -214,6 +220,9 @@ authors: url: https://github.com/JoelMarcey image_url: https://github.com/JoelMarcey.png email: jimarcey@gmail.com + socials: + x: joelmarcey + github: JoelMarcey --- ``` @@ -230,10 +239,16 @@ authors: url: https://github.com/JoelMarcey image_url: https://github.com/JoelMarcey.png email: jimarcey@gmail.com + socials: + x: joelmarcey + github: JoelMarcey - name: Sébastien Lorber title: Docusaurus maintainer url: https://sebastienlorber.com image_url: https://github.com/slorber.png + socials: + x: sebastienlorber + github: slorber --- ``` @@ -276,12 +291,18 @@ jmarcey: url: https://github.com/JoelMarcey image_url: https://github.com/JoelMarcey.png email: jimarcey@gmail.com + socials: + x: joelmarcey + github: JoelMarcey slorber: name: Sébastien Lorber title: Docusaurus maintainer url: https://sebastienlorber.com image_url: https://github.com/slorber.png + socials: + x: sebastienlorber + github: slorber ``` :::tip From d19480d748823369fffc3d573052717638ee58ee Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 11 Jul 2024 20:01:03 +0200 Subject: [PATCH 26/35] Add socials to init template --- .../create-docusaurus/templates/shared/blog/authors.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/create-docusaurus/templates/shared/blog/authors.yml b/packages/create-docusaurus/templates/shared/blog/authors.yml index bcb29915635c..69b2ee20a7b1 100644 --- a/packages/create-docusaurus/templates/shared/blog/authors.yml +++ b/packages/create-docusaurus/templates/shared/blog/authors.yml @@ -9,9 +9,16 @@ yangshun: title: Front End Engineer @ Facebook url: https://github.com/yangshun image_url: https://github.com/yangshun.png + socials: + x: yangshunz + github: yangshun slorber: name: Sébastien Lorber title: Docusaurus maintainer url: https://sebastienlorber.com image_url: https://github.com/slorber.png + socials: + x: sebastienlorber + github: slorber + Newsletter: https://thisweekinreact.com From 5e1723f75d8090c307cfeda28e2042f2f60053cd Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 11 Jul 2024 20:05:07 +0200 Subject: [PATCH 27/35] Add socials to init template + newsletter extra as a demo --- packages/create-docusaurus/templates/shared/blog/authors.yml | 2 +- website/blog/authors.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/create-docusaurus/templates/shared/blog/authors.yml b/packages/create-docusaurus/templates/shared/blog/authors.yml index 69b2ee20a7b1..60ffff219074 100644 --- a/packages/create-docusaurus/templates/shared/blog/authors.yml +++ b/packages/create-docusaurus/templates/shared/blog/authors.yml @@ -21,4 +21,4 @@ slorber: socials: x: sebastienlorber github: slorber - Newsletter: https://thisweekinreact.com + newsletter: https://thisweekinreact.com diff --git a/website/blog/authors.yml b/website/blog/authors.yml index 965d9bf94d05..bfeba1b66584 100644 --- a/website/blog/authors.yml +++ b/website/blog/authors.yml @@ -26,6 +26,7 @@ slorber: x: sebastienlorber github: slorber stackoverflow: /82609/sebastien-lorber + newsletter: https://thisweekinreact.com yangshun: name: Yangshun Tay From 605ceed1a0e36c5516e8e5ec3ba1ab2f5034a606 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 11 Jul 2024 22:31:45 +0200 Subject: [PATCH 28/35] better blog author socials normalization --- .../src/__tests__/authorsSocials.test.ts | 44 +++++++++------ .../src/authorsSocials.ts | 55 ++++++++++++------- .../Header/Author/Socials/styles.module.css | 2 +- 3 files changed, 61 insertions(+), 40 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts index 1888be8df99a..af408e3dedb0 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts @@ -20,8 +20,26 @@ describe('normalizeSocials', () => { expect(normalizeSocials(socials)).toMatchInlineSnapshot(` { "github": "https://github.com/ozakione", - "linkedin": "https://www.linkedin.com/ozakione", - "stackoverflow": "https://stackoverflow.com/ozakione", + "linkedin": "https://www.linkedin.com/in/ozakione/", + "stackoverflow": "https://stackoverflow.com/users/ozakione", + "twitter": "https://twitter.com/ozakione", + } + `); + }); + + it('only username - case insensitive', () => { + const socials: AuthorSocials = { + Twitter: 'ozakione', + linkedIn: 'ozakione', + gitHub: 'ozakione', + STACKoverflow: 'ozakione', + }; + + expect(normalizeSocials(socials)).toMatchInlineSnapshot(` + { + "github": "https://github.com/ozakione", + "linkedin": "https://www.linkedin.com/in/ozakione/", + "stackoverflow": "https://stackoverflow.com/users/ozakione", "twitter": "https://twitter.com/ozakione", } `); @@ -49,7 +67,7 @@ describe('normalizeSocials', () => { expect(normalizeSocials(socials)).toMatchInlineSnapshot(` { "github": "https://github.com/ozakione", - "linkedin": "https://www.linkedin.com/ozakione", + "linkedin": "https://www.linkedin.com/in/ozakione/", "stackoverflow": "https://stackoverflow.com/ozakione", "twitter": "https://twitter.com/ozakione", } @@ -68,24 +86,14 @@ describe('normalizeSocials', () => { `); }); - it('normalize link url', () => { - // stackoverflow doesn't like multiple slashes, as we have trailing slash - // in socialPlatforms, if the user add a prefix slash the url will contain - // multiple slashes causing a 404 + it('rejects strings that do not look like username/userId/handle or fully-qualified URLs', () => { const socials: AuthorSocials = { - twitter: '//ozakione', - github: '/ozakione///', - linkedin: '//ozakione///', - stackoverflow: '///users///82609/sebastien-lorber', + twitter: '/ozakione/XYZ', }; - expect(normalizeSocials(socials)).toMatchInlineSnapshot(` - { - "github": "https://github.com/ozakione/", - "linkedin": "https://www.linkedin.com/ozakione/", - "stackoverflow": "https://stackoverflow.com/users/82609/sebastien-lorber", - "twitter": "https://twitter.com/ozakione", - } + expect(() => normalizeSocials(socials)).toThrowErrorMatchingInlineSnapshot(` + "Author socials should be usernames/userIds/handles, or fully qualified HTTP(s) absolute URLs. + Social platform 'twitter' has illegal value '/ozakione/XYZ'" `); }); diff --git a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts index 2ec75b7e3fbb..1f7a131f734b 100644 --- a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts +++ b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts @@ -5,34 +5,47 @@ * LICENSE file in the root directory of this source tree. */ -import {normalizeUrl} from '@docusaurus/utils'; import type { AuthorSocials, SocialPlatformKey, } from '@docusaurus/plugin-content-blog'; -const socialPlatforms: Record = { - twitter: 'https://twitter.com/', - github: 'https://github.com/', - linkedin: 'https://www.linkedin.com/', - stackoverflow: 'https://stackoverflow.com/', - x: 'https://x.com/', +type PredefinedPlatformNormalizer = (value: string) => string; + +const PredefinedPlatformNormalizers: Record< + SocialPlatformKey | string, + PredefinedPlatformNormalizer +> = { + x: (handle: string) => `https://x.com/${handle}`, + twitter: (handle: string) => `https://twitter.com/${handle}`, + github: (handle: string) => `https://github.com/${handle}`, + linkedin: (handle: string) => `https://www.linkedin.com/in/${handle}/`, + stackoverflow: (userId: string) => + `https://stackoverflow.com/users/${userId}`, }; -const SocialPlatformKeys = Object.keys(socialPlatforms) as SocialPlatformKey[]; +type SocialEntry = [string, string]; -export const normalizeSocials = (value: AuthorSocials): AuthorSocials => { - SocialPlatformKeys.forEach((platform) => { - if ( - value[platform] && - !value[platform]!.startsWith(socialPlatforms[platform]) - ) { - value[platform] = normalizeUrl([ - socialPlatforms[platform], - value[platform]!, - ]); - } - }); +function normalizeSocialEntry([platform, value]: SocialEntry): SocialEntry { + const normalizer = PredefinedPlatformNormalizers[platform.toLowerCase()]; + const isAbsoluteUrl = + value.startsWith('http://') || value.startsWith('https://'); + if (isAbsoluteUrl) { + return [platform, value]; + } else if (value.includes('/')) { + throw new Error( + `Author socials should be usernames/userIds/handles, or fully qualified HTTP(s) absolute URLs. +Social platform '${platform}' has illegal value '${value}'`, + ); + } + if (normalizer && !isAbsoluteUrl) { + const normalizedPlatform = platform.toLowerCase(); + const normalizedValue = normalizer(value); + return [normalizedPlatform as SocialPlatformKey, normalizedValue]; + } + return [platform, value]; +} - return value; +export const normalizeSocials = (socials: AuthorSocials): AuthorSocials => { + return Object.fromEntries(Object.entries(socials).map(normalizeSocialEntry)); }; diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/Socials/styles.module.css b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/Socials/styles.module.css index 583f120571ac..1fca8b7e385e 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/Socials/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/Socials/styles.module.css @@ -25,7 +25,7 @@ height: var(--docusaurus-blog-social-icon-size); width: var(--docusaurus-blog-social-icon-size); line-height: 0; - margin-right: 0.2rem; + margin-right: 0.3rem; } .authorSocialIcon { From 229c4c2700621916807a9f13d2e3a4ccf2f1beaa Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 11 Jul 2024 22:31:58 +0200 Subject: [PATCH 29/35] Add authors slorber linkedin platform --- packages/create-docusaurus/templates/shared/blog/authors.yml | 1 + website/blog/authors.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/create-docusaurus/templates/shared/blog/authors.yml b/packages/create-docusaurus/templates/shared/blog/authors.yml index 60ffff219074..39734f65b9cf 100644 --- a/packages/create-docusaurus/templates/shared/blog/authors.yml +++ b/packages/create-docusaurus/templates/shared/blog/authors.yml @@ -20,5 +20,6 @@ slorber: image_url: https://github.com/slorber.png socials: x: sebastienlorber + linkedin: sebastienlorber github: slorber newsletter: https://thisweekinreact.com diff --git a/website/blog/authors.yml b/website/blog/authors.yml index bfeba1b66584..318effc9b46b 100644 --- a/website/blog/authors.yml +++ b/website/blog/authors.yml @@ -24,8 +24,8 @@ slorber: image_url: https://github.com/slorber.png socials: x: sebastienlorber + linkedin: sebastienlorber github: slorber - stackoverflow: /82609/sebastien-lorber newsletter: https://thisweekinreact.com yangshun: From b3d5942871d1b655a3241cb227c73e76ea13243b Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 11 Jul 2024 22:42:24 +0200 Subject: [PATCH 30/35] fix SO social platforms --- website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx | 4 ++-- website/_dogfooding/_blog tests/2024-07-03-single-author.mdx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx b/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx index 025001460de1..0a7ff12b993b 100644 --- a/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx +++ b/website/_dogfooding/_blog tests/2024-07-03-dual-author.mdx @@ -6,7 +6,7 @@ authors: socials: twitter: sebastienlorber github: slorber - stackoverflow: /users/82609/sebastien-lorber + stackoverflow: 82609 linkedin: sebastienlorber newsletter: https://thisweekinreact.com/newsletter - name: Sébastien Lorber @@ -14,7 +14,7 @@ authors: socials: x: https://x.com/sebastienlorber github: https://github.com/slorber - stackoverflow: https://stackoverflow.com/users/82609/sebastien-lorber + stackoverflow: 82609 linkedin: https://www.linkedin.com/in/sebastienlorber/ newsletter: https://thisweekinreact.com/newsletter --- diff --git a/website/_dogfooding/_blog tests/2024-07-03-single-author.mdx b/website/_dogfooding/_blog tests/2024-07-03-single-author.mdx index 8d89fb1fd996..0a418f42e283 100644 --- a/website/_dogfooding/_blog tests/2024-07-03-single-author.mdx +++ b/website/_dogfooding/_blog tests/2024-07-03-single-author.mdx @@ -8,7 +8,7 @@ authors: x: https://x.com/sebastienlorber twitter: https://twitter.com/sebastienlorber github: https://github.com/slorber - stackoverflow: https://stackoverflow.com/users/82609/sebastien-lorber + stackoverflow: 82609 linkedin: https://www.linkedin.com/in/sebastienlorber/ newsletter: https://thisweekinreact.com/newsletter --- From 497542722fcd0f1f52fe3a0d08c3b7f71003c3e1 Mon Sep 17 00:00:00 2001 From: slorber Date: Thu, 11 Jul 2024 20:47:17 +0000 Subject: [PATCH 31/35] refactor: apply lint autofix --- project-words.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/project-words.txt b/project-words.txt index af729e8ade47..b9db52dfb400 100644 --- a/project-words.txt +++ b/project-words.txt @@ -167,7 +167,6 @@ linkify Linkify Localizable lockb -lorber Lorber Lorber's lqip From c01fe892f015bd6dacbe4ade7ddad428bdb15adc Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 12 Jul 2024 09:18:14 +0200 Subject: [PATCH 32/35] Joi schema should validate inline socials --- .../__fixtures__/authorsMapFiles/authors.yml | 2 ++ .../src/__tests__/authors.test.ts | 2 ++ .../docusaurus-plugin-content-blog/src/authors.ts | 12 +++--------- .../src/authorsSocials.ts | 13 +++++++++++++ .../src/frontMatter.ts | 2 ++ 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/authorsMapFiles/authors.yml b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/authorsMapFiles/authors.yml index 62f84790dade..1d0cb11cd6ea 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/authorsMapFiles/authors.yml +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/authorsMapFiles/authors.yml @@ -7,6 +7,7 @@ JMarcey: socials: twitter: https://twitter.com/JoelMarcey x: https://x.com/JoelMarcey + stackoverflow: https://stackoverflow.com/users/102705/Joel-Marcey slorber: name: Sébastien Lorber @@ -17,6 +18,7 @@ slorber: socials: twitter: sebastienlorber x: sebastienlorber + stackoverflow: 82609 yangshun: name: Yangshun Tay diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts index 51576d635a55..851bf77fa2fd 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts @@ -467,12 +467,14 @@ describe('getAuthorsMap', () => { }); expect(authorsMap.slorber.socials).toMatchInlineSnapshot(` { + "stackoverflow": "https://stackoverflow.com/users/82609", "twitter": "https://twitter.com/sebastienlorber", "x": "https://x.com/sebastienlorber", } `); expect(authorsMap.JMarcey.socials).toMatchInlineSnapshot(` { + "stackoverflow": "https://stackoverflow.com/users/102705/Joel-Marcey", "twitter": "https://twitter.com/JoelMarcey", "x": "https://x.com/JoelMarcey", } diff --git a/packages/docusaurus-plugin-content-blog/src/authors.ts b/packages/docusaurus-plugin-content-blog/src/authors.ts index 557180279a06..541521286e02 100644 --- a/packages/docusaurus-plugin-content-blog/src/authors.ts +++ b/packages/docusaurus-plugin-content-blog/src/authors.ts @@ -8,7 +8,7 @@ import * as _ from 'lodash'; import {getDataFileData, normalizeUrl} from '@docusaurus/utils'; import {Joi, URISchema} from '@docusaurus/utils-validation'; -import {normalizeSocials} from './authorsSocials'; +import {AuthorSocialsSchema, normalizeSocials} from './authorsSocials'; import type {BlogContentPaths} from './types'; import type { Author, @@ -22,19 +22,13 @@ export type AuthorsMap = {[authorKey: string]: Author}; const AuthorsMapSchema = Joi.object() .pattern( Joi.string(), - Joi.object({ + Joi.object({ name: Joi.string(), url: URISchema, imageURL: URISchema, title: Joi.string(), email: Joi.string(), - socials: Joi.object({ - twitter: Joi.string(), - github: Joi.string(), - linkedin: Joi.string(), - stackoverflow: Joi.string(), - x: Joi.string(), - }).unknown(), + socials: AuthorSocialsSchema, }) .rename('image_url', 'imageURL') .or('name', 'imageURL') diff --git a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts index 1f7a131f734b..cc4c2992f9eb 100644 --- a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts +++ b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts @@ -5,11 +5,24 @@ * LICENSE file in the root directory of this source tree. */ +import {Joi} from '@docusaurus/utils-validation'; + import type { AuthorSocials, SocialPlatformKey, } from '@docusaurus/plugin-content-blog'; +export const AuthorSocialsSchema = Joi.object({ + twitter: Joi.string(), + github: Joi.string(), + linkedin: Joi.string(), + // StackOverflow userIds like '82609' are parsed as numbers by Yarml + stackoverflow: Joi.alternatives() + .try(Joi.number(), Joi.string()) + .custom((val) => String(val)), + x: Joi.string(), +}).unknown(); + type PredefinedPlatformNormalizer = (value: string) => string; const PredefinedPlatformNormalizers: Record< diff --git a/packages/docusaurus-plugin-content-blog/src/frontMatter.ts b/packages/docusaurus-plugin-content-blog/src/frontMatter.ts index 3c3f0f8883ee..6c3436198038 100644 --- a/packages/docusaurus-plugin-content-blog/src/frontMatter.ts +++ b/packages/docusaurus-plugin-content-blog/src/frontMatter.ts @@ -13,6 +13,7 @@ import { URISchema, validateFrontMatter, } from '@docusaurus/utils-validation'; +import {AuthorSocialsSchema} from './authorsSocials'; import type {BlogPostFrontMatter} from '@docusaurus/plugin-content-blog'; const BlogPostFrontMatterAuthorSchema = Joi.object({ @@ -21,6 +22,7 @@ const BlogPostFrontMatterAuthorSchema = Joi.object({ title: Joi.string(), url: URISchema, imageURL: Joi.string(), + socials: AuthorSocialsSchema, }) .or('key', 'name', 'imageURL') .rename('image_url', 'imageURL', {alias: true}); From 9005a4f03c9df680e6ea3426d5592a9ebc8b97f6 Mon Sep 17 00:00:00 2001 From: slorber Date: Fri, 12 Jul 2024 07:23:17 +0000 Subject: [PATCH 33/35] refactor: apply lint autofix --- project-words.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/project-words.txt b/project-words.txt index b9db52dfb400..ab45516e1d59 100644 --- a/project-words.txt +++ b/project-words.txt @@ -413,6 +413,7 @@ Yacop yangshun Yangshun yangshunz +Yarml Zhou zoomable zpao From 91ca3af68744489f7efb08d1887fa22b8106935e Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 12 Jul 2024 09:34:11 +0200 Subject: [PATCH 34/35] remove word --- packages/docusaurus-plugin-content-blog/src/authorsSocials.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts index cc4c2992f9eb..8ca12169a3b0 100644 --- a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts +++ b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts @@ -16,7 +16,7 @@ export const AuthorSocialsSchema = Joi.object({ twitter: Joi.string(), github: Joi.string(), linkedin: Joi.string(), - // StackOverflow userIds like '82609' are parsed as numbers by Yarml + // StackOverflow userIds like '82609' are parsed as numbers by Yaml stackoverflow: Joi.alternatives() .try(Joi.number(), Joi.string()) .custom((val) => String(val)), From 42dae65e2e67d478a0174ef8176c9f973c5786b3 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 12 Jul 2024 09:34:25 +0200 Subject: [PATCH 35/35] remove word --- project-words.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/project-words.txt b/project-words.txt index ab45516e1d59..b9db52dfb400 100644 --- a/project-words.txt +++ b/project-words.txt @@ -413,7 +413,6 @@ Yacop yangshun Yangshun yangshunz -Yarml Zhou zoomable zpao