I recently created this SocialLinks
component while working on my portfolio. It wasn't something I planned to create explicitly, but it turned out to be quite useful! I'm sharing it here so others can benefit from it as well. I'd love to hear your opinions and suggestions on how to improve it. Your feedback is greatly appreciated! π
The Component
import React, { forwardRef } from "react";
import { Button } from "./ui/button";
import Link from "next/link";
import { cn } from "@/lib/utils";
import { VariantProps, cva } from "class-variance-authority";
// Styles for the social link container
const socialLinkVariants = cva("flex items-center justify-around", {
variants: {
variant: {
horizontal: "flex-row gap-4 md:gap-6 lg:gap-8",
vertical: "flex-col gap-4 md:gap-6 lg:gap-8",
},
spacing: {
small: "gap-2 md:gap-3 lg:gap-4",
medium: "gap-4 md:gap-6 lg:gap-8",
large: "gap-6 md:gap-8 lg:gap-10",
},
padding: {
none: "p-0",
small: "p-2 md:p-3 lg:p-4",
medium: "p-4 md:p-6 lg:p-8",
large: "p-6 md:p-8 lg:p-10",
},
},
defaultVariants: {
variant: "horizontal",
spacing: "medium",
padding: "none",
},
});
// Type for individual social link
type SocialLink = {
href: string;
label: string;
icon: React.ReactNode;
};
// Props for the SocialLinks component
type SocialLinksProps = React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement>,
HTMLElement
> &
VariantProps<typeof socialLinkVariants> & {
links: SocialLink[];
buttonSize?: "default" | "sm" | "lg" | "icon";
buttonVariant?:
| "link"
| "default"
| "destructive"
| "outline"
| "secondary"
| "ghost";
};
// Forward ref component
const SocialLinks = forwardRef<HTMLElement, SocialLinksProps>(
(
{
variant,
spacing,
padding,
buttonSize = "icon",
buttonVariant = "link",
className,
links,
...props
},
ref
) => {
return (
<nav
ref={ref}
className={cn(
socialLinkVariants({ variant, spacing, padding }),
className
)}
{...props}
>
{links.map((link, index) => (
<Button
key={index}
asChild
variant={buttonVariant}
size={buttonSize}
className="text-foreground hover:text-primary"
>
<Link href={link.href} aria-label={link.label}>
{link.icon}
</Link>
</Button>
))}
</nav>
);
}
);
// Set display name for better debugging and readability
SocialLinks.displayName = "SocialLinks";
export default SocialLinks;
Usage
Here's an example of how you can use the SocialLinks
component in your project:
import { SocialLinks } from "./components/SocialLinks";
import { Github, Instagram, Linkedin, Twitter } from "lucide-react";
const socialLinks = [
{ href: "https://twitter.com/yourprofile", label: "Twitter", icon: <Twitter /> },
{ href: "https://instagram.com/yourprofile", label: "Instagram", icon: <Instagram /> },
{ href: "https://linkedin.com/in/yourprofile", label: "LinkedIn", icon: <Linkedin /> },
{ href: "https://github.com/yourprofile", label: "GitHub", icon: <Github /> },
];
const App = () => (
<div>
<SocialLinks links={socialLinks} />
</div>
);
export default App;
Feedback
I'd love to hear your opinions and suggestions! Please feel free to reach out to me on Twitter, LinkedIn, or drop a comment below.
Check out the GitHub Gist for the complete code.
Thanks for reading and happy coding! π
Top comments (0)