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 af408e3dedb0..28db8aed0f7b 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/authorsSocials.test.ts @@ -15,14 +15,25 @@ describe('normalizeSocials', () => { linkedin: 'ozakione', github: 'ozakione', stackoverflow: 'ozakione', + threads: 'gingergeekuk', + bluesky: 'gingergeek.co.uk', + twitch: 'gingergeek', + youtube: 'gingergeekuk', + mastodon: 'Mastodon', }; + // eslint-disable-next-line jest/no-large-snapshots expect(normalizeSocials(socials)).toMatchInlineSnapshot(` { + "bluesky": "https://bsky.app/profile/gingergeek.co.uk", "github": "https://github.com/ozakione", "linkedin": "https://www.linkedin.com/in/ozakione/", + "mastodon": "https://mastodon.social/@Mastodon", "stackoverflow": "https://stackoverflow.com/users/ozakione", + "threads": "https://www.threads.net/@gingergeekuk", + "twitch": "https://twitch.tv/gingergeek", "twitter": "https://twitter.com/ozakione", + "youtube": "https://youtube.com/@gingergeekuk", } `); }); @@ -33,13 +44,17 @@ describe('normalizeSocials', () => { linkedIn: 'ozakione', gitHub: 'ozakione', STACKoverflow: 'ozakione', + BLUESKY: 'gingergeek.co.uk', + tHrEaDs: 'gingergeekuk', }; expect(normalizeSocials(socials)).toMatchInlineSnapshot(` { + "bluesky": "https://bsky.app/profile/gingergeek.co.uk", "github": "https://github.com/ozakione", "linkedin": "https://www.linkedin.com/in/ozakione/", "stackoverflow": "https://stackoverflow.com/users/ozakione", + "threads": "https://www.threads.net/@gingergeekuk", "twitter": "https://twitter.com/ozakione", } `); @@ -62,12 +77,14 @@ describe('normalizeSocials', () => { linkedin: 'ozakione', github: 'https://github.com/ozakione', stackoverflow: 'https://stackoverflow.com/ozakione', + mastodon: 'https://hachyderm.io/@hachyderm', }; expect(normalizeSocials(socials)).toMatchInlineSnapshot(` { "github": "https://github.com/ozakione", "linkedin": "https://www.linkedin.com/in/ozakione/", + "mastodon": "https://hachyderm.io/@hachyderm", "stackoverflow": "https://stackoverflow.com/ozakione", "twitter": "https://twitter.com/ozakione", } diff --git a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts index b190e3e09dc2..674df7cef01f 100644 --- a/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts +++ b/packages/docusaurus-plugin-content-blog/src/authorsSocials.ts @@ -21,6 +21,11 @@ export const AuthorSocialsSchema = Joi.object({ .try(Joi.number(), Joi.string()) .custom((val) => String(val)), x: Joi.string(), + bluesky: Joi.string(), + threads: Joi.string(), + mastodon: Joi.string(), + twitch: Joi.string(), + youtube: Joi.string(), }).unknown(); type PredefinedPlatformNormalizer = (value: string) => string; @@ -35,6 +40,11 @@ const PredefinedPlatformNormalizers: Record< linkedin: (handle: string) => `https://www.linkedin.com/in/${handle}/`, stackoverflow: (userId: string) => `https://stackoverflow.com/users/${userId}`, + bluesky: (handle: string) => `https://bsky.app/profile/${handle}`, + threads: (handle: string) => `https://www.threads.net/@${handle}`, + mastodon: (handle: string) => `https://mastodon.social/@${handle}`, // can be in format user@other.server and it will redirect if needed + twitch: (handle: string) => `https://twitch.tv/${handle}`, + youtube: (handle: string) => `https://youtube.com/@${handle}`, // https://support.google.com/youtube/answer/6180214?hl=en }; type SocialEntry = [string, 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 f13f42ec1df2..2c1a400afc7e 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 @@ -46,7 +46,13 @@ declare module '@docusaurus/plugin-content-blog' { | 'github' | 'linkedin' | 'stackoverflow' - | 'x'; + | 'x' + | 'bluesky' + | 'threads' + | 'mastodon' + | 'bluesky' + | 'youtube' + | 'twitch'; /** * Social platforms of the author. diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 6b5c40d73047..7d6c36296244 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -1708,6 +1708,46 @@ declare module '@theme/Icon/Socials/StackOverflow' { export default function StackOverflow(props: Props): ReactNode; } +declare module '@theme/Icon/Socials/Bluesky' { + import type {ComponentProps, ReactNode} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function Bluesky(props: Props): ReactNode; +} + +declare module '@theme/Icon/Socials/Threads' { + import type {ComponentProps, ReactNode} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function Threads(props: Props): ReactNode; +} + +declare module '@theme/Icon/Socials/YouTube' { + import type {ComponentProps, ReactNode} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function YouTube(props: Props): ReactNode; +} + +declare module '@theme/Icon/Socials/Twitch' { + import type {ComponentProps, ReactNode} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function Twitch(props: Props): ReactNode; +} + +declare module '@theme/Icon/Socials/Mastodon' { + import type {ComponentProps, ReactNode} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function Mastodon(props: Props): ReactNode; +} + declare module '@theme/TagsListByLetter' { import type {ReactNode} from 'react'; import type {TagsListItem} from '@docusaurus/utils'; diff --git a/packages/docusaurus-theme-classic/src/theme/Blog/Components/Author/Socials/index.tsx b/packages/docusaurus-theme-classic/src/theme/Blog/Components/Author/Socials/index.tsx index a632bd62addd..373bda8e7b5a 100644 --- a/packages/docusaurus-theme-classic/src/theme/Blog/Components/Author/Socials/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Blog/Components/Author/Socials/index.tsx @@ -17,6 +17,11 @@ 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 Bluesky from '@theme/Icon/Socials/Bluesky'; +import Threads from '@theme/Icon/Socials/Threads'; +import Youtube from '@theme/Icon/Socials/YouTube'; +import Mastodon from '@theme/Icon/Socials/Mastodon'; +import Twitch from '@theme/Icon/Socials/Twitch'; import styles from './styles.module.css'; @@ -30,6 +35,11 @@ const SocialPlatformConfigs: Record = { stackoverflow: {Icon: StackOverflow, label: 'Stack Overflow'}, linkedin: {Icon: LinkedIn, label: 'LinkedIn'}, x: {Icon: X, label: 'X'}, + bluesky: {Icon: Bluesky, label: 'Bluesky'}, + threads: {Icon: Threads, label: 'Threads'}, + mastodon: {Icon: Mastodon, label: 'Mastodon'}, + youtube: {Icon: Youtube, label: 'YouTube'}, + twitch: {Icon: Twitch, label: 'Twitch'}, }; function getSocialPlatformConfig(platformKey: string): SocialPlatformConfig { diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Bluesky/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Bluesky/index.tsx new file mode 100644 index 000000000000..0f0c400bb42b --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Bluesky/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, ReactNode} from 'react'; + +// SVG Source: https://svgl.app/ +function Bluesky(props: SVGProps): ReactNode { + return ( + + + + ); +} +export default Bluesky; diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Mastodon/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Mastodon/index.tsx new file mode 100644 index 000000000000..47f3790a8705 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Mastodon/index.tsx @@ -0,0 +1,43 @@ +/** + * 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, ReactNode} from 'react'; + +// SVG Source: https://svgl.app/ +function Mastodon(props: SVGProps): ReactNode { + return ( + + + + + + + + + + + ); +} +export default Mastodon; diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Threads/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Threads/index.tsx new file mode 100644 index 000000000000..76e33d036eae --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Threads/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, ReactNode} from 'react'; + +import clsx from 'clsx'; +import styles from './styles.module.css'; + +// SVG Source: https://svgl.app/ +function Threads(props: SVGProps): ReactNode { + return ( + + + + ); +} +export default Threads; diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Threads/styles.module.css b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Threads/styles.module.css new file mode 100644 index 000000000000..a8031d376c96 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Threads/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'] .threadsSvg { + fill: var(--light); +} + +[data-theme='light'] .threadsSvg { + fill: var(--dark); +} diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Twitch/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Twitch/index.tsx new file mode 100644 index 000000000000..4ec52c0ae335 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/Twitch/index.tsx @@ -0,0 +1,39 @@ +/** + * 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, ReactNode} from 'react'; + +// SVG Source: https://svgl.app/ +function Twitch(props: SVGProps): ReactNode { + return ( + + + + + + + + ); +} +export default Twitch; diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/Socials/YouTube/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/YouTube/index.tsx new file mode 100644 index 000000000000..41688dd1d6f8 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/Socials/YouTube/index.tsx @@ -0,0 +1,26 @@ +/** + * 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, ReactNode} from 'react'; + +function YouTube(props: SVGProps): ReactNode { + return ( + + + + + ); +} +export default YouTube; diff --git a/project-words.txt b/project-words.txt index 9cef579226d0..5b119f470b43 100644 --- a/project-words.txt +++ b/project-words.txt @@ -25,6 +25,9 @@ beforeinstallprompt Bhatt blockquotes Blockquotes +bluesky +Bluesky +BLUESKY Bokmål bunx caabernathy @@ -95,6 +98,8 @@ funboxteam gabrielcsapo getcanary Gifs +gingergeek +gingergeekuk Goss Goyal gtag @@ -175,6 +180,7 @@ metrica Metrika microdata Microdata +Milnes mindmap Mindmap mkdn @@ -367,6 +373,7 @@ Yacop yangshun Yangshun yangshunz +zedspencermilnes Zhou zoomable zpao diff --git a/website/_dogfooding/_blog tests/2024-12-14-all-thesocials.mdx b/website/_dogfooding/_blog tests/2024-12-14-all-thesocials.mdx new file mode 100644 index 000000000000..2522b03b1dfb --- /dev/null +++ b/website/_dogfooding/_blog tests/2024-12-14-all-thesocials.mdx @@ -0,0 +1,21 @@ +--- +title: Social media test +authors: + - name: Zed Spencer-Milnes + title: All the socials test + urL: https://gingergeek.co.uk + image_url: https://github.com/GingerGeek.png + page: false + socials: + x: GingerGeek + github: gingergeek + linkedin: zedspencermilnes + youtube: gingergeekuk + bluesky: gingergeek.co.uk + stackoverflow: 2064409 + twitch: gingergeek + threads: gingergeekuk + mastodon: https://hachyderm.io/@zed +--- + +Well, that's a lot of social media profiles.