Skip to content

Commit be6655d

Browse files
committed
Refactor social icons to reduce repetition. Thanks @gauravmm and the changes from transitive-bullshit#629
1 parent bd6ae7f commit be6655d

File tree

4 files changed

+100
-130
lines changed

4 files changed

+100
-130
lines changed

components/Footer.tsx

Lines changed: 18 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
import * as React from 'react'
2-
import {
3-
FaEnvelopeOpenText,
4-
FaGithub,
5-
FaLinkedin,
6-
FaMastodon,
7-
FaTwitter,
8-
FaYoutube,
9-
FaZhihu
10-
} from 'react-icons/fa'
2+
import cs from 'classnames'
113
import { IoMoonSharp, IoSunnyOutline } from 'react-icons/io5'
124

135
import * as config from '@/lib/config'
146
import { useDarkMode } from '@/lib/use-dark-mode'
7+
import { socialLinks } from './PageSocial'
158

169
import styles from './styles.module.css'
1710

@@ -54,89 +47,29 @@ export function FooterImpl() {
5447
)}
5548
</div>
5649

57-
<div className={styles.social}>
58-
{config.twitter && (
59-
<a
60-
className={styles.twitter}
61-
href={`https://twitter.com/${config.twitter}`}
62-
title={`Twitter @${config.twitter}`}
63-
target='_blank'
64-
rel='noopener noreferrer'
65-
>
66-
<FaTwitter />
67-
</a>
68-
)}
50+
<style
51+
dangerouslySetInnerHTML={{
52+
__html: socialLinks.map((action) => (
53+
`.social-link-footer-${action.name} {}
54+
.social-link-footer-${action.name}:hover { color: ${action.color}; }
55+
`
56+
)).join('\n')
57+
}}
58+
/>
6959

70-
{config.mastodon && (
71-
<a
72-
className={styles.mastodon}
73-
href={config.mastodon}
74-
title={`Mastodon ${config.getMastodonHandle()}`}
75-
rel='me'
76-
>
77-
<FaMastodon />
78-
</a>
79-
)}
80-
81-
{config.zhihu && (
82-
<a
83-
className={styles.zhihu}
84-
href={`https://zhihu.com/people/${config.zhihu}`}
85-
title={`Zhihu @${config.zhihu}`}
86-
target='_blank'
87-
rel='noopener noreferrer'
88-
>
89-
<FaZhihu />
90-
</a>
91-
)}
92-
93-
{config.github && (
94-
<a
95-
className={styles.github}
96-
href={`https://github.com/${config.github}`}
97-
title={`GitHub @${config.github}`}
98-
target='_blank'
99-
rel='noopener noreferrer'
100-
>
101-
<FaGithub />
102-
</a>
103-
)}
104-
105-
{config.linkedin && (
106-
<a
107-
className={styles.linkedin}
108-
href={`https://www.linkedin.com/in/${config.linkedin}`}
109-
title={`LinkedIn ${config.author}`}
110-
target='_blank'
111-
rel='noopener noreferrer'
112-
>
113-
<FaLinkedin />
114-
</a>
115-
)}
116-
117-
{config.newsletter && (
60+
<div className={styles.social}>
61+
{socialLinks.map((action) => (
11862
<a
119-
className={styles.newsletter}
120-
href={`${config.newsletter}`}
121-
title={`Newsletter ${config.author}`}
63+
className={cs(styles[action.name], `social-link-footer-${action.name}`)}
64+
href={action.href}
65+
title={action.title}
12266
target='_blank'
12367
rel='noopener noreferrer'
12468
>
125-
<FaEnvelopeOpenText />
69+
{action.icon({ size: 16 })}
12670
</a>
127-
)}
71+
))}
12872

129-
{config.youtube && (
130-
<a
131-
className={styles.youtube}
132-
href={`https://www.youtube.com/${config.youtube}`}
133-
title={`YouTube ${config.author}`}
134-
target='_blank'
135-
rel='noopener noreferrer'
136-
>
137-
<FaYoutube />
138-
</a>
139-
)}
14073
</div>
14174
</footer>
14275
)

components/PageSocial.tsx

Lines changed: 76 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,90 +4,121 @@ import cs from 'classnames'
44
import * as config from '@/lib/config'
55

66
import styles from './PageSocial.module.css'
7+
import { FaGithub, FaLinkedin, FaTwitter, FaYoutube } from 'react-icons/fa'
8+
import { FaXTwitter, FaGitlab, FaEnvelopeOpenText } from 'react-icons/fa6'
9+
import { IoIosBug } from 'react-icons/io'
710

811
interface SocialLink {
912
name: string
1013
title: string
11-
icon: React.ReactNode
14+
icon: ({ size }: { size: number }) => React.ReactNode
15+
color: string
1216
href?: string
1317
}
1418

15-
const socialLinks: SocialLink[] = [
19+
export const socialLinks: SocialLink[] = [
1620
config.twitter && {
1721
name: 'twitter',
1822
href: `https://twitter.com/${config.twitter}`,
1923
title: `Twitter @${config.twitter}`,
20-
icon: (
21-
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'>
22-
<path d='M23.44 4.83c-.8.37-1.5.38-2.22.02.93-.56.98-.96 1.32-2.02-.88.52-1.86.9-2.9 1.1-.82-.88-2-1.43-3.3-1.43-2.5 0-4.55 2.04-4.55 4.54 0 .36.03.7.1 1.04-3.77-.2-7.12-2-9.36-4.75-.4.67-.6 1.45-.6 2.3 0 1.56.8 2.95 2 3.77-.74-.03-1.44-.23-2.05-.57v.06c0 2.2 1.56 4.03 3.64 4.44-.67.2-1.37.2-2.06.08.58 1.8 2.26 3.12 4.25 3.16C5.78 18.1 3.37 18.74 1 18.46c2 1.3 4.4 2.04 6.97 2.04 8.35 0 12.92-6.92 12.92-12.93 0-.2 0-.4-.02-.6.9-.63 1.96-1.22 2.56-2.14z' />
23-
</svg>
24-
)
24+
color: "#2795e9",
25+
icon: FaTwitter
26+
},
27+
28+
config.twitterX && {
29+
name: 'twitterX',
30+
href: `https://x.com/${config.twitterX}`,
31+
title: `X @${config.twitterX}`,
32+
color: "#222",
33+
icon: FaXTwitter
2534
},
2635

2736
config.github && {
2837
name: 'github',
2938
href: `https://github.com/${config.github}`,
3039
title: `GitHub @${config.github}`,
31-
icon: (
32-
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'>
33-
<path d='M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22'></path>
34-
</svg>
35-
)
40+
color: "#c9510c",
41+
icon: FaGithub
42+
},
43+
44+
config.gitlab && {
45+
name: 'gitlab',
46+
href: `https://gitlab.com/${config.github}`,
47+
title: `GitLab @${config.github}`,
48+
color: "#e24329",
49+
icon: FaGitlab
3650
},
3751

3852
config.linkedin && {
3953
name: 'linkedin',
4054
href: `https://www.linkedin.com/in/${config.linkedin}`,
4155
title: `LinkedIn ${config.author}`,
42-
icon: (
43-
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'>
44-
<path d='M6.5 21.5h-5v-13h5v13zM4 6.5C2.5 6.5 1.5 5.3 1.5 4s1-2.4 2.5-2.4c1.6 0 2.5 1 2.6 2.5 0 1.4-1 2.5-2.6 2.5zm11.5 6c-1 0-2 1-2 2v7h-5v-13h5V10s1.6-1.5 4-1.5c3 0 5 2.2 5 6.3v6.7h-5v-7c0-1-1-2-2-2z' />
45-
</svg>
46-
)
56+
color: "#0077b5",
57+
icon: FaLinkedin
4758
},
4859

4960
config.newsletter && {
5061
name: 'newsletter',
5162
href: `${config.newsletter}`,
5263
title: `Newsletter ${config.author}`,
53-
icon: (
54-
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'>
55-
<path d='M12 .64L8.23 3H5V5L2.97 6.29C2.39 6.64 2 7.27 2 8V18C2 19.11 2.9 20 4 20H20C21.11 20 22 19.11 22 18V8C22 7.27 21.61 6.64 21.03 6.29L19 5V3H15.77M7 5H17V9.88L12 13L7 9.88M8 6V7.5H16V6M5 7.38V8.63L4 8M19 7.38L20 8L19 8.63M8 8.5V10H16V8.5Z' />
56-
</svg>
57-
)
64+
color: "#777",
65+
icon: FaEnvelopeOpenText
5866
},
5967

6068
config.youtube && {
6169
name: 'youtube',
6270
href: `https://www.youtube.com/${config.youtube}`,
6371
title: `YouTube ${config.youtube}`,
64-
icon: (
65-
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'>
66-
<path d='M10,15L15.19,12L10,9V15M21.56,7.17C21.69,7.64 21.78,8.27 21.84,9.07C21.91,9.87 21.94,10.56 21.94,11.16L22,12C22,14.19 21.84,15.8 21.56,16.83C21.31,17.73 20.73,18.31 19.83,18.56C19.36,18.69 18.5,18.78 17.18,18.84C15.88,18.91 14.69,18.94 13.59,18.94L12,19C7.81,19 5.2,18.84 4.17,18.56C3.27,18.31 2.69,17.73 2.44,16.83C2.31,16.36 2.22,15.73 2.16,14.93C2.09,14.13 2.06,13.44 2.06,12.84L2,12C2,9.81 2.16,8.2 2.44,7.17C2.69,6.27 3.27,5.69 4.17,5.44C4.64,5.31 5.5,5.22 6.82,5.16C8.12,5.09 9.31,5.06 10.41,5.06L12,5C16.19,5 18.8,5.16 19.83,5.44C20.73,5.69 21.31,6.27 21.56,7.17Z' />
67-
</svg>
68-
)
72+
color: "#ff0000",
73+
icon: FaYoutube
74+
},
75+
76+
config.bugtracker && {
77+
name: 'bugtracker',
78+
href: `${config.bugtracker}`,
79+
title: `Bugtracker`,
80+
color: "#e24329",
81+
icon: IoIosBug
6982
}
7083
].filter(Boolean)
7184

72-
export function PageSocial() {
85+
function generateCssFrag(prefix: string) {
86+
return socialLinks.map((action) => (
87+
`.social-link-${prefix}-${action.name} {}
88+
.social-link-${prefix}-${action.name}:hover {
89+
background: ${action.color};
90+
color: white;
91+
}
92+
`
93+
)).join('\n');
94+
}
95+
96+
export function PageSocial(prefix: string) {
7397
return (
74-
<div className={styles.pageSocial}>
75-
{socialLinks.map((action) => (
76-
<a
77-
className={cs(styles.action, styles[action.name])}
78-
href={action.href}
79-
key={action.name}
80-
title={action.title}
81-
target='_blank'
82-
rel='noopener noreferrer'
83-
>
84-
<div className={styles.actionBg}>
85-
<div className={styles.actionBgPane} />
86-
</div>
98+
<>
99+
<style
100+
dangerouslySetInnerHTML={{ __html: generateCssFrag("side") }}
101+
/>
102+
<div className={styles.pageSocial}>
103+
{socialLinks.map((action) => (
104+
<>
105+
<a
106+
className={cs(styles.action, styles[action.name], `social-link-side-${action.name}`)}
107+
href={action.href}
108+
key={action.name}
109+
title={action.title}
110+
target='_blank'
111+
rel='noopener noreferrer'
112+
>
113+
<div className={styles.actionBg}>
114+
<div className={styles.actionBgPane} />
115+
</div>
87116

88-
<div className={styles.actionBg}>{action.icon}</div>
89-
</a>
90-
))}
91-
</div>
117+
<div className={styles.actionBg}>{action.icon({ size: 24 })}</div>
118+
</a>
119+
</>
120+
))}
121+
</div>
122+
</>
92123
)
93124
}

lib/config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,15 @@ export const language: string = getSiteConfig('language', 'en')
5555

5656
// social accounts
5757
export const twitter: string | null = getSiteConfig('twitter', null)
58+
export const twitterX: string | null = getSiteConfig('twitterX', null)
5859
export const mastodon: string | null = getSiteConfig('mastodon', null)
5960
export const github: string | null = getSiteConfig('github', null)
61+
export const gitlab: string | null = getSiteConfig('gitlab', null)
6062
export const youtube: string | null = getSiteConfig('youtube', null)
6163
export const linkedin: string | null = getSiteConfig('linkedin', null)
6264
export const newsletter: string | null = getSiteConfig('newsletter', null)
6365
export const zhihu: string | null = getSiteConfig('zhihu', null)
66+
export const bugtracker: string | null = getSiteConfig('bugtracker', null)
6467

6568
export const getMastodonHandle = (): string | null => {
6669
if (!mastodon) {

lib/site-config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@ export interface SiteConfig {
1111
language?: string
1212

1313
twitter?: string
14+
twitterX?: string
1415
github?: string
16+
gitlab?: string
1517
linkedin?: string
1618
newsletter?: string
1719
youtube?: string
1820
zhihu?: string
1921
mastodon?: string
22+
bugtracker?: string
2023

2124
defaultPageIcon?: string | null
2225
defaultPageCover?: string | null

0 commit comments

Comments
 (0)