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' }