You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

87 lines
2.5 KiB

export type SocialLinkIconInput = {
label: string
url: string
icon?: string | null
}
/** 优先使用条目中的 icon;否则按域名与标题推断 */
export function socialLinkIconName(link: SocialLinkIconInput): string {
const raw = link.icon?.trim()
if (raw) {
return raw
}
return inferSocialLinkIconName(link.label, link.url)
}
function inferSocialLinkIconName(label: string, url: string): string {
const lowerLabel = label.toLowerCase()
try {
const u = new URL(url.trim())
if (u.protocol === 'mailto:') {
return 'i-lucide-mail'
}
const host = u.hostname.replace(/^www\./i, '').toLowerCase()
const byHost: [string, string][] = [
['github.com', 'i-simple-icons-github'],
['gist.github.com', 'i-simple-icons-github'],
['github.io', 'i-simple-icons-github'],
['twitter.com', 'i-simple-icons-x'],
['x.com', 'i-simple-icons-x'],
['linkedin.com', 'i-simple-icons-linkedin'],
['youtube.com', 'i-simple-icons-youtube'],
['youtu.be', 'i-simple-icons-youtube'],
['gitlab.com', 'i-simple-icons-gitlab'],
['reddit.com', 'i-simple-icons-reddit'],
['discord.com', 'i-simple-icons-discord'],
['discord.gg', 'i-simple-icons-discord'],
['t.me', 'i-simple-icons-telegram'],
['telegram.org', 'i-simple-icons-telegram'],
['medium.com', 'i-simple-icons-medium'],
['stackoverflow.com', 'i-simple-icons-stackoverflow'],
['bsky.app', 'i-simple-icons-bluesky'],
['mastodon.social', 'i-simple-icons-mastodon'],
['bilibili.com', 'i-simple-icons-bilibili'],
['space.bilibili.com', 'i-simple-icons-bilibili'],
['weibo.com', 'i-simple-icons-sinaweibo'],
['zhihu.com', 'i-simple-icons-zhihu'],
]
for (const [h, icon] of byHost) {
if (host === h || host.endsWith(`.${h}`)) {
return icon
}
}
if (host.endsWith('.github.io')) {
return 'i-simple-icons-github'
}
if (host.includes('mastodon')) {
return 'i-simple-icons-mastodon'
}
}
catch {
// fall through to label heuristics
}
if (/\bgithub\b/i.test(lowerLabel)) {
return 'i-simple-icons-github'
}
if (/\b(x|twitter)\b/i.test(lowerLabel)) {
return 'i-simple-icons-x'
}
if (/\blinkedin\b/i.test(lowerLabel)) {
return 'i-simple-icons-linkedin'
}
if (/\byoutube\b|\byt\b/i.test(lowerLabel)) {
return 'i-simple-icons-youtube'
}
if (/\bmail\b|邮箱|电子邮件/i.test(lowerLabel)) {
return 'i-lucide-mail'
}
return 'i-lucide-link-2'
}