Profile Section Component
A component for displaying user profile information.
Installation
pnpm dlx shadcn@latest add https://ui.vllnt.com/r/profile-section.jsonbash
Usage
import { ProfileSection } from '@vllnt/ui'
export function ProfileSectionExample() {
return (
<ProfileSection
dict={{
profile: {
name: 'John Doe',
tagline: 'Full-stack developer',
},
}}
imageAlt="John Doe Profile"
imageSource="/avatar.jpg"
socialLinks={[
{ href: 'https://x.com/johndoe', label: 'X (Twitter)' },
{ href: 'https://github.com/johndoe', label: 'GitHub' },
]}
/>
)
}tsx
Code
import Image from "next/image";
import Link from "next/link";
import { Button } from "../button/button";
type ProfileDict = {
profile: {
name: string;
tagline: string;
};
};
type SocialLink = {
href: string;
label: string;
};
type ProfileSectionProps = {
compact?: boolean;
dict: ProfileDict;
imageAlt?: string;
imageSource?: string;
socialLinks?: SocialLink[];
};
export function ProfileSection({
compact = false,
dict,
imageAlt,
imageSource = "/profile.png",
socialLinks,
}: ProfileSectionProps) {
const displayImageAlt = imageAlt ?? `${dict.profile.name} Profile`;
const showImage = !compact && Boolean(imageSource);
const showSocialLinks =
!compact && Boolean(socialLinks && socialLinks.length > 0);
return (
<div className="text-center space-y-4">
{showImage ? (
<div className="relative w-24 h-24 mx-auto overflow-hidden rounded-md">
<Image
alt={displayImageAlt}
className="w-full h-full object-cover rounded-md"
height={96}
priority={true}
src={imageSource}
width={96}
/>
</div>
) : null}
<div className="space-y-2">
<h3 className={`font-semibold ${compact ? "text-lg" : "text-xl"}`}>
{dict.profile.name}
</h3>
<p className="text-sm text-muted-foreground">
{compact ? dict.profile.tagline : `> ${dict.profile.tagline}`}
</p>
</div>
{showSocialLinks ? (
<div className="flex flex-wrap justify-center items-center gap-2">
{socialLinks?.map((link) => (
<Link
href={link.href}
key={link.href}
rel="noopener noreferrer"
target="_blank"
>
<Button className="w-32" size="sm" variant="outline">
{link.label}
</Button>
</Link>
))}
</div>
) : null}
</div>
);
}
typescript
