diff --git a/components/Footer.tsx b/components/Footer.tsx
index e927b79606..5d8a42fe7b 100644
--- a/components/Footer.tsx
+++ b/components/Footer.tsx
@@ -1,16 +1,10 @@
-import { FaEnvelopeOpenText } from '@react-icons/all-files/fa/FaEnvelopeOpenText'
-import { FaGithub } from '@react-icons/all-files/fa/FaGithub'
-import { FaLinkedin } from '@react-icons/all-files/fa/FaLinkedin'
-import { FaMastodon } from '@react-icons/all-files/fa/FaMastodon'
-import { FaTwitter } from '@react-icons/all-files/fa/FaTwitter'
-import { FaYoutube } from '@react-icons/all-files/fa/FaYoutube'
-import { FaZhihu } from '@react-icons/all-files/fa/FaZhihu'
-import { IoMoonSharp } from '@react-icons/all-files/io5/IoMoonSharp'
-import { IoSunnyOutline } from '@react-icons/all-files/io5/IoSunnyOutline'
import * as React from 'react'
+import cs from 'classnames'
+import { IoMoonSharp, IoSunnyOutline } from 'react-icons/io5'
import * as config from '@/lib/config'
import { useDarkMode } from '@/lib/use-dark-mode'
+import { PageSocialButtons } from './PageSocial'
import styles from './styles.module.css'
@@ -54,88 +48,7 @@ export function FooterImpl() {
- {config.twitter && (
-
-
-
- )}
-
- {config.mastodon && (
-
-
-
- )}
-
- {config.zhihu && (
-
-
-
- )}
-
- {config.github && (
-
-
-
- )}
-
- {config.linkedin && (
-
-
-
- )}
-
- {config.newsletter && (
-
-
-
- )}
-
- {config.youtube && (
-
-
-
- )}
+
)
diff --git a/components/NotionPageHeader.tsx b/components/NotionPageHeader.tsx
index 5fbb087ce3..36a6658c1f 100644
--- a/components/NotionPageHeader.tsx
+++ b/components/NotionPageHeader.tsx
@@ -1,8 +1,7 @@
import type * as types from 'notion-types'
-import { IoMoonSharp } from '@react-icons/all-files/io5/IoMoonSharp'
-import { IoSunnyOutline } from '@react-icons/all-files/io5/IoSunnyOutline'
import cs from 'classnames'
import * as React from 'react'
+import { IoMoonSharp, IoSunnyOutline } from 'react-icons/io5'
import { Breadcrumbs, Header, Search, useNotionContext } from 'react-notion-x'
import { isSearchEnabled, navigationLinks, navigationStyle } from '@/lib/config'
diff --git a/components/PageActions.tsx b/components/PageActions.tsx
index 755c60880c..e6ec96cf6b 100644
--- a/components/PageActions.tsx
+++ b/components/PageActions.tsx
@@ -1,5 +1,5 @@
-import { AiOutlineRetweet } from '@react-icons/all-files/ai/AiOutlineRetweet'
-import { IoHeartOutline } from '@react-icons/all-files/io5/IoHeartOutline'
+import { AiOutlineRetweet } from 'react-icons/ai'
+import { IoHeartOutline } from 'react-icons/io5'
import styles from './styles.module.css'
diff --git a/components/PageSocial.module.css b/components/PageSocial.module.css
index c82a8ee9a9..855e45db80 100644
--- a/components/PageSocial.module.css
+++ b/components/PageSocial.module.css
@@ -6,11 +6,10 @@
color: var(--fg-color);
}
-.action {
+.pageSocial a {
position: relative;
border-radius: 50%;
border: 2px solid var(--fg-color-6);
- transition: all 300ms ease-out;
width: 3.5em;
height: 3.5em;
margin: 0 0 1em;
@@ -23,111 +22,24 @@
cursor: pointer;
}
-.action:last-child {
- margin-bottom: 0;
+.pageSocial a:hover {
+ border: 2px solid var(--hover-background);
}
-.actionBg {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
-
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
+.socialLink {
+ transition: all 500ms ease-out;
}
-.actionBg svg {
- width: 50%;
- height: 50%;
- fill: var(--fg-color-6);
-}
-
-.actionBgPane {
- transition: all 300ms ease-out;
+.socialLink:hover {
border-radius: 50%;
- width: 0;
- height: 0;
+ color: var(--hover-color);
+ background: var(--hover-background);
}
-.action:hover {
- transition: all 100ms ease-out;
-}
-
-.action:hover .actionBgPane {
- width: 100%;
- height: 100%;
- transition: all 100ms ease-out;
-}
-
-.action:hover svg {
- transition: fill 100ms ease-out;
- fill: var(--bg-color);
-}
-
-:global(.dark-mode) .action:hover svg {
+:global(.dark-mode) .socialLink:hover svg {
fill: var(--fg-color);
}
-.facebook .actionBgPane {
- background: #3b5998;
-}
-.facebook:hover {
- border-color: #3b5998;
-}
-
-.twitter .actionBgPane {
- background: #2795e9;
-}
-.twitter:hover {
- border-color: #2795e9;
-}
-
-.linkedin .actionBgPane {
- background: #0077b5;
-}
-.linkedin:hover {
- border-color: #0077b5;
-}
-
-.github .actionBgPane {
- background: #c9510c;
-}
-.github:hover {
- border-color: #c9510c;
-}
-
-.youtube .actionBgPane {
- background: #ff0000;
-}
-.youtube:hover {
- border-color: #ff0000;
-}
-
-.medium .actionBgPane {
- background: #00ab6c;
-}
-.medium:hover {
- border-color: #00ab6c;
-}
-
-.newsletter .actionBgPane {
- background: #777777;
-}
-.newsletter:hover {
- border-color: #777777;
-}
-
-.email .actionBgPane {
- background: #777;
-}
-.email:hover {
- border-color: #777;
-}
-
@media only screen and (max-width: 768px) {
.links {
position: relative;
@@ -135,7 +47,7 @@
flex-wrap: wrap;
}
- .action:last-child {
+ .pageSocial a:last-child {
margin-right: 1em;
}
}
diff --git a/components/PageSocial.tsx b/components/PageSocial.tsx
index 5301c06656..3dfff267e2 100644
--- a/components/PageSocial.tsx
+++ b/components/PageSocial.tsx
@@ -4,90 +4,143 @@ import cs from 'classnames'
import * as config from '@/lib/config'
import styles from './PageSocial.module.css'
+import { FaGithub, FaInstagram, FaLinkedin, FaMastodon, FaReddit, FaTwitter, FaYoutube } from 'react-icons/fa'
+import { FaXTwitter, FaGitlab, FaEnvelopeOpenText } from 'react-icons/fa6'
+import { IoIosBug } from 'react-icons/io'
interface SocialLink {
name: string
title: string
- icon: React.ReactNode
+ icon: ({ size }: { size: number }) => React.ReactNode
+ color: string
href?: string
+ // Currently only used for instagram
+ background?: string
}
-const socialLinks: SocialLink[] = [
+export const socialLinks: SocialLink[] = [
config.twitter && {
name: 'twitter',
href: `https://twitter.com/${config.twitter}`,
title: `Twitter @${config.twitter}`,
- icon: (
-
- )
+ color: "#ffffff",
+ background: "#2795e9",
+ icon: FaTwitter
+ },
+ config.twitterX && {
+ name: 'twitterX',
+ href: `https://x.com/${config.twitterX}`,
+ title: `X.com @${config.twitterX}`,
+ color: "#222",
+ icon: FaXTwitter
+ },
+
+ config.mastodon && {
+ name: 'mastodon',
+ href: config.mastodon,
+ title: 'Mastodon',
+ color: "#5a4be1",
+ icon: FaMastodon
},
config.github && {
name: 'github',
href: `https://github.com/${config.github}`,
title: `GitHub @${config.github}`,
- icon: (
-
- )
+ // FIXME: Figure out great way to preserve github black and white theme, For now it uses rainbow
+ color: "#ffffff",
+ // Fun rainbow background, similarl as their pride logo
+ // FIXME: Gradients can't be transitioned with css :(
+ background: "linear-gradient(to bottom, #C6474E 0%, #C6474E 17%, #D67940 17%, #D67940 33%, #F8D45C 33%, #F8D45C 50%, #67A25A 50%, #67A25A 67%, #3A63C7 67%, #3A63C7 84%, #6446B4 84%)",
+ icon: FaGithub
+ },
+
+ config.gitlab && {
+ name: 'gitlab',
+ href: `https://gitlab.com/${config.github}`,
+ title: `GitLab @${config.github}`,
+ color: "#e24329",
+ icon: FaGitlab
},
config.linkedin && {
name: 'linkedin',
href: `https://www.linkedin.com/in/${config.linkedin}`,
title: `LinkedIn ${config.author}`,
- icon: (
-
- )
+ color: "#ffffff",
+ background: "#0077b5",
+ icon: FaLinkedin
},
config.newsletter && {
name: 'newsletter',
href: `${config.newsletter}`,
title: `Newsletter ${config.author}`,
- icon: (
-
- )
+ color: "#777",
+ icon: FaEnvelopeOpenText
},
config.youtube && {
name: 'youtube',
href: `https://www.youtube.com/${config.youtube}`,
- title: `YouTube ${config.youtube}`,
- icon: (
-
- )
+ title: `YouTube @${config.youtube}`,
+ color: "#ff0000",
+ icon: FaYoutube
+ },
+
+ config.instagram && {
+ name: 'instagram',
+ href: `https://instagram.com/${config.instagram}`,
+ title: `Instagram @${config.instagram}`,
+ color: "#ffffff",
+ background: "radial-gradient(circle at 30% 107%, #fdf497 0%, #fdf497 5%, #fd5949 45%,#d6249f 60%, #285AEB 90%)",
+ icon: FaInstagram
+ },
+
+ config.reddit && {
+ name: 'reddit',
+ href: `https://www.reddit.com/u/${config.reddit}`,
+ title: `Reddit @${config.reddit}`,
+ color: "#ffffff",
+ background: "#FF5700",
+ icon: FaReddit
+ },
+
+ config.bugtracker && {
+ name: 'bugtracker',
+ href: `${config.bugtracker}`,
+ title: 'Bugtracker',
+ color: "#e24329",
+ icon: IoIosBug
}
].filter(Boolean)
export function PageSocial() {
return (
-
+ >
)
}
diff --git a/components/styles.module.css b/components/styles.module.css
index bea8ff1ed9..900c19bde7 100644
--- a/components/styles.module.css
+++ b/components/styles.module.css
@@ -90,34 +90,6 @@
color: #2795e9;
}
-.twitter:hover {
- color: #2795e9;
-}
-
-.mastodon:hover {
- color: #5a4be1;
-}
-
-.zhihu:hover {
- color: #0066ff;
-}
-
-.github:hover {
- color: #c9510c;
-}
-
-.youtube:hover {
- color: #ff0000;
-}
-
-.linkedin:hover {
- color: #0077b5;
-}
-
-.newsletter:hover {
- color: #777777;
-}
-
.comments {
width: 100%;
margin-top: 2em;
diff --git a/lib/config.ts b/lib/config.ts
index 4e74d12c97..41843fd931 100644
--- a/lib/config.ts
+++ b/lib/config.ts
@@ -55,12 +55,17 @@ export const language: string = getSiteConfig('language', 'en')
// social accounts
export const twitter: string | null = getSiteConfig('twitter', null)
+export const twitterX: string | null = getSiteConfig('twitterX', null)
export const mastodon: string | null = getSiteConfig('mastodon', null)
export const github: string | null = getSiteConfig('github', null)
+export const gitlab: string | null = getSiteConfig('gitlab', null)
export const youtube: string | null = getSiteConfig('youtube', null)
+export const instagram: string | null = getSiteConfig('instagram', null)
+export const reddit: string | null = getSiteConfig('reddit', null)
export const linkedin: string | null = getSiteConfig('linkedin', null)
export const newsletter: string | null = getSiteConfig('newsletter', null)
export const zhihu: string | null = getSiteConfig('zhihu', null)
+export const bugtracker: string | null = getSiteConfig('bugtracker', null)
export const getMastodonHandle = (): string | null => {
if (!mastodon) {
diff --git a/lib/site-config.ts b/lib/site-config.ts
index cfd538e767..922c11b744 100644
--- a/lib/site-config.ts
+++ b/lib/site-config.ts
@@ -11,12 +11,17 @@ export interface SiteConfig {
language?: string
twitter?: string
+ twitterX?: string
github?: string
+ gitlab?: string
linkedin?: string
newsletter?: string
youtube?: string
+ instagram?: string
+ reddit?: string
zhihu?: string
mastodon?: string
+ bugtracker?: string
defaultPageIcon?: string | null
defaultPageCover?: string | null
diff --git a/package.json b/package.json
index 11c066255e..f59569ad5a 100644
--- a/package.json
+++ b/package.json
@@ -33,7 +33,7 @@
"@fisch0920/use-dark-mode": "^2.4.0",
"@keyvhq/core": "^1.6.9",
"@keyvhq/redis": "^1.6.10",
- "@react-icons/all-files": "^4.1.0",
+ "react-icons": "^5.3.0",
"@vercel/og": "^0.6.3",
"classnames": "^2.5.1",
"date-fns": "^2.30.0",
diff --git a/pages/_document.tsx b/pages/_document.tsx
index 28cc023758..1b0f437ce3 100644
--- a/pages/_document.tsx
+++ b/pages/_document.tsx
@@ -1,5 +1,5 @@
-import { IconContext } from '@react-icons/all-files'
import Document, { Head, Html, Main, NextScript } from 'next/document'
+import { IconContext } from 'react-icons'
export default class MyDocument extends Document {
render() {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5f3290c0f8..5eea58c91e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -17,9 +17,6 @@ importers:
'@keyvhq/redis':
specifier: ^1.6.10
version: 1.6.28
- '@react-icons/all-files':
- specifier: ^4.1.0
- version: 4.1.0(react@18.3.1)
'@vercel/og':
specifier: ^0.6.3
version: 0.6.3
@@ -74,6 +71,9 @@ importers:
react-dom:
specifier: ^18.2.0
version: 18.3.1(react@18.3.1)
+ react-icons:
+ specifier: ^5.3.0
+ version: 5.3.0(react@18.3.1)
react-notion-x:
specifier: ^7.0.1
version: 7.0.1(@babel/runtime@7.26.0)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -388,11 +388,6 @@ packages:
'@polka/url@1.0.0-next.28':
resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==}
- '@react-icons/all-files@4.1.0':
- resolution: {integrity: sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==}
- peerDependencies:
- react: '*'
-
'@resvg/resvg-wasm@2.4.0':
resolution: {integrity: sha512-C7c51Nn4yTxXFKvgh2txJFNweaVcfUPQxwEUFw4aWsCmfiBDJsTSwviIF8EcwjQ6k8bPyMWCl1vw4BdxE569Cg==}
engines: {node: '>= 10'}
@@ -1929,6 +1924,11 @@ packages:
react: '>=16.8.1'
react-dom: '>=16.8.1'
+ react-icons@5.3.0:
+ resolution: {integrity: sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==}
+ peerDependencies:
+ react: '*'
+
react-image@4.1.0:
resolution: {integrity: sha512-qwPNlelQe9Zy14K2pGWSwoL+vHsAwmJKS6gkotekDgRpcnRuzXNap00GfibD3eEPYu3WCPlyIUUNzcyHOrLHjw==}
peerDependencies:
@@ -2758,10 +2758,6 @@ snapshots:
'@polka/url@1.0.0-next.28': {}
- '@react-icons/all-files@4.1.0(react@18.3.1)':
- dependencies:
- react: 18.3.1
-
'@resvg/resvg-wasm@2.4.0': {}
'@rtsao/scc@1.1.0': {}
@@ -3386,7 +3382,7 @@ snapshots:
debug: 4.3.7
enhanced-resolve: 5.17.1
eslint: 8.57.1
- eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
+ eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
fast-glob: 3.3.2
get-tsconfig: 4.8.1
is-bun-module: 1.2.1
@@ -3399,7 +3395,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
- eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
+ eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1):
dependencies:
debug: 3.2.7
optionalDependencies:
@@ -3421,7 +3417,7 @@ snapshots:
doctrine: 2.1.0
eslint: 8.57.1
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
+ eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
hasown: 2.0.2
is-core-module: 2.15.1
is-glob: 4.0.3
@@ -4452,6 +4448,10 @@ snapshots:
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
+ react-icons@5.3.0(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+
react-image@4.1.0(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
'@babel/runtime': 7.26.0
diff --git a/site.config.ts b/site.config.ts
index cded79c3bf..dc8f87567b 100644
--- a/site.config.ts
+++ b/site.config.ts
@@ -18,11 +18,19 @@ export default siteConfig({
// social usernames (optional)
twitter: 'transitive_bs',
+ // twitterX: 'transitive_bs', // If you want to use X.com logo instead
+ // mastodon: '#' // optional mastodon profile URL, provides link verification
+
github: 'transitive-bullshit',
+ // gitlab: 'transitive-bullshit', // optional gitlab account
+
linkedin: 'fisch2',
// mastodon: '#', // optional mastodon profile URL, provides link verification
// newsletter: '#', // optional newsletter URL
// youtube: '#', // optional youtube channel name or `channel/UCGbXXXXXXXXXXXXXXXXXXXXXX`
+ // instagram: '#', // optional instagram account
+ // reddit: '#', // optional reddit account
+ // bugtracker: '#', // optional bugtracker URL
// default notion icon and cover images for site-wide consistency (optional)
// page-specific values will override these site-wide defaults