102 lines
2.4 KiB
TypeScript
102 lines
2.4 KiB
TypeScript
import {
|
|
siBluesky,
|
|
siLinktree,
|
|
siMastodon,
|
|
siPaypal,
|
|
siTelegram,
|
|
siTwitch,
|
|
type SimpleIcon,
|
|
} from "simple-icons";
|
|
|
|
type SocialKey = "paypal" | "telegram" | "mastodon" | "bluesky" | "linktree" | "twitch";
|
|
|
|
const SOCIALS: Record<
|
|
SocialKey,
|
|
{ label: string; icon: SimpleIcon; href: string }
|
|
> = {
|
|
paypal: {
|
|
label: "PayPal",
|
|
icon: siPaypal,
|
|
href: "https://paypal.me/Gaertan",
|
|
},
|
|
telegram: {
|
|
label: "Telegram",
|
|
icon: siTelegram,
|
|
href: "https://t.me/Gaertan",
|
|
},
|
|
mastodon: {
|
|
label: "Mastodon",
|
|
icon: siMastodon,
|
|
href: "https://mastodon.social/@Gaertan",
|
|
},
|
|
bluesky: {
|
|
label: "Bluesky",
|
|
icon: siBluesky,
|
|
href: "https://bsky.app/profile/gaertan.bsky.social",
|
|
},
|
|
linktree: {
|
|
label: "Linktree",
|
|
icon: siLinktree,
|
|
href: "https://linktr.ee/gaertan",
|
|
},
|
|
twitch: {
|
|
label: "Twitch",
|
|
icon: siTwitch,
|
|
href: "https://www.twitch.tv/gaertan_art",
|
|
}
|
|
};
|
|
|
|
function BrandSvg({ icon }: { icon: SimpleIcon }) {
|
|
// Simple Icons SVGs are typically 24x24 viewBox.
|
|
return (
|
|
<svg
|
|
viewBox="0 0 24 24"
|
|
className="h-5 w-5 fill-current"
|
|
aria-hidden="true"
|
|
focusable="false"
|
|
dangerouslySetInnerHTML={{ __html: icon.svg }}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export function SocialLinks({
|
|
items = ["paypal", "telegram", "mastodon", "bluesky", "linktree", "twitch"],
|
|
size = "md",
|
|
}: {
|
|
items?: SocialKey[];
|
|
size?: "sm" | "md" | "lg";
|
|
}) {
|
|
const sizeClass =
|
|
size === "sm" ? "h-9 w-9" : size === "lg" ? "h-12 w-12" : "h-10 w-10";
|
|
|
|
return (
|
|
<div className="flex flex-wrap gap-2">
|
|
{items.map((key) => {
|
|
const s = SOCIALS[key];
|
|
|
|
return (
|
|
<a
|
|
key={key}
|
|
href={s.href}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
aria-label={s.label}
|
|
title={s.label}
|
|
className={[
|
|
"inline-flex items-center justify-center rounded-full",
|
|
"border border-border bg-background",
|
|
"text-foreground hover:text-primary",
|
|
"hover:bg-accent transition-colors",
|
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
"ring-offset-background",
|
|
sizeClass,
|
|
].join(" ")}
|
|
>
|
|
<BrandSvg icon={s.icon} />
|
|
<span className="sr-only">{s.label}</span>
|
|
</a>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
} |