کارت پروفایل (Profile Card)
نمایش کارت پروفایل عمودی با آواتار، نام، یوزرنیم و تعداد فالوور
معرفی
کامپوننت Profile Card برای نمایش کارت پروفایل کاربر به صورت عمودی استفاده میشود. این کامپوننت شامل آواتار با حاشیه سفارشی، نام کاربر، نام کاربری (username) و تعداد فالوورها با فرمت کوتاه شده است.
چه زمانی استفاده کنیم:
- برای نمایش پروفایل کاربران در grid یا carousel
- برای صفحههای پیشنهاد دنبال کردن و نتایج جستجوی کاربران
- وقتی نمایش عمودی و بصری پروفایل مناسبتر است
چه زمانی استفاده نکنیم:
- برای موجودیتهای غیرشخصی (برند، شرکت) — از
Cardساده استفاده کنید - برای نمایش inline در جدول — از
ProfileInfoاستفاده کنید
استفاده پایه
محسن یگانه
mohsene
import { ProfileCard } from '@parto-system-design/ui'
import { Users } from 'lucide-react'
export default function MyComponent() {
return (
<ProfileCard
name="محسن یگانه"
username="mohsene"
avatarSrc="https://example.com/avatar.jpg"
followers={125000}
followersIcon={<Users className="h-3.5 w-3.5" />}
onCardClick={() => console.log('Card clicked')}
/>
)
}مثالها
اندازههای مختلف
کامپوننت در سه اندازه sm، md و lg موجود است.
احمد رضایی
ahmad.rezaei
فاطمه کریمی
fateme_karimi
علی محمدی
ali.m
<ProfileCard
size="sm"
name="احمد رضایی"
username="ahmad.rezaei"
avatarSrc="/avatar.jpg"
followers={5400}
followersIcon={<Users className="h-3 w-3" />}
/>
<ProfileCard
size="md"
name="فاطمه کریمی"
username="fateme_karimi"
avatarSrc="/avatar.jpg"
followers={82000}
followersIcon={<Users className="h-3.5 w-3.5" />}
/>
<ProfileCard
size="lg"
name="علی محمدی"
username="ali.m"
avatarSrc="/avatar.jpg"
followers={1200000}
followersIcon={<Users className="h-4 w-4" />}
/>حالتهای مختلف (Variants)
کامپوننت در سه variant موجود است: default، dark و transparent.
سارا احمدی
sara_ahmadi
حسین رضایی
hosein.r
مریم جعفری
maryam_jafari
<ProfileCard
variant="default"
name="سارا احمدی"
username="sara_ahmadi"
followers={45000}
followersIcon={<Users className="h-3.5 w-3.5" />}
/>
<ProfileCard
variant="dark"
name="حسین رضایی"
username="hosein.r"
followers={98000}
followersIcon={<Users className="h-3.5 w-3.5" />}
/>
<ProfileCard
variant="transparent"
name="مریم جعفری"
username="maryam_jafari"
followers={23500}
followersIcon={<Users className="h-3.5 w-3.5" />}
/>گرید کارتها
نمایش چند کارت در کنار هم به صورت گرید.
محسن یگانه
mohsene
سارا احمدی
sara_ahmadi
علی محمدی
ali.m
فاطمه کریمی
fateme_karimi
const users = [
{
name: 'محسن یگانه',
username: 'mohsene',
avatarSrc: '/avatar1.jpg',
followers: 125000,
},
// ...
]
;<div className="grid grid-cols-2 md:grid-cols-4 gap-4" dir="rtl">
{users.map((user) => (
<ProfileCard
key={user.username}
name={user.name}
username={user.username}
avatarSrc={user.avatarSrc}
followers={user.followers}
followersIcon={<Users className="h-3.5 w-3.5" />}
onCardClick={() => console.log(`${user.name} clicked`)}
/>
))}
</div>بدون تعداد فالوور
میتوانید کارت را بدون نمایش تعداد فالوور نیز استفاده کنید.
کاربر جدید
new_user
<ProfileCard name="کاربر جدید" username="new_user" initials="ک ج" avatarBorderVariant="primary" />Props
ProfileCard
مثالهای کاربردی
لیست پیشنهادی کاربران
import { ProfileCard } from '@parto-system-design/ui'
import { Users } from 'lucide-react'
const suggestedUsers = [
{
id: '1',
name: 'محسن یگانه',
username: 'mohsene',
avatarSrc: '/avatars/mohsen.jpg',
followers: 125000,
},
{
id: '2',
name: 'علی احمدی',
username: 'ali.a',
avatarSrc: '/avatars/ali.jpg',
followers: 82000,
},
// ...
]
export default function SuggestedUsers() {
return (
<div className="space-y-4" dir="rtl">
<h2 className="text-lg font-semibold">پیشنهاد دنبال کردن</h2>
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4">
{suggestedUsers.map((user) => (
<ProfileCard
key={user.id}
name={user.name}
username={user.username}
avatarSrc={user.avatarSrc}
followers={user.followers}
followersIcon={<Users className="h-3.5 w-3.5" />}
avatarBorderVariant="gold"
onCardClick={() => navigateToProfile(user.username)}
/>
))}
</div>
</div>
)
}جستجوی کاربران
import { ProfileCard } from '@parto-system-design/ui'
import { Users } from 'lucide-react'
import { useState } from 'react'
export default function UserSearch() {
const [searchResults, setSearchResults] = useState([])
return (
<div className="space-y-4" dir="rtl">
<Input placeholder="جستجوی کاربران..." onChange={(e) => handleSearch(e.target.value)} />
<div className="grid grid-cols-3 gap-4">
{searchResults.map((user) => (
<ProfileCard
key={user.id}
name={user.name}
username={user.username}
avatarSrc={user.avatarSrc}
followers={user.followers}
followersIcon={<Users className="h-3.5 w-3.5" />}
onCardClick={() => viewProfile(user)}
/>
))}
</div>
</div>
)
}با دکمه دنبال کردن
import { ProfileCard, Button } from '@parto-system-design/ui'
import { Users, UserPlus } from 'lucide-react'
export default function ProfileWithFollow() {
const [isFollowing, setIsFollowing] = useState(false)
return (
<div className="relative" dir="rtl">
<ProfileCard
name="محسن یگانه"
username="mohsene"
avatarSrc="/avatar.jpg"
followers={125000}
followersIcon={<Users className="h-3.5 w-3.5" />}
/>
<div className="absolute top-2 left-2">
<Button size="sm" variant={isFollowing ? 'outline' : 'primary'} onClick={() => setIsFollowing(!isFollowing)}>
{isFollowing ? 'دنبالشده' : 'دنبال کردن'}
</Button>
</div>
</div>
)
}Carousel کارتهای پروفایل
import { ProfileCard, Carousel, CarouselContent, CarouselItem } from '@parto-system-design/ui';
import { Users } from 'lucide-react';
export default function ProfileCarousel() {
const users = [...]; // لیست کاربران
return (
<Carousel dir="rtl" className="w-full">
<CarouselContent>
{users.map((user) => (
<CarouselItem key={user.id} className="basis-1/2 md:basis-1/3 lg:basis-1/4">
<ProfileCard
name={user.name}
username={user.username}
avatarSrc={user.avatarSrc}
followers={user.followers}
followersIcon={<Users className="h-3.5 w-3.5" />}
avatarBorderVariant="gold"
/>
</CarouselItem>
))}
</CarouselContent>
</Carousel>
);
}نکات مهم
فرمت تعداد فالوور
تعداد فالوورها به صورت خودکار فرمت میشود:
- کمتر از 1,000: عدد کامل نمایش داده میشود (مثلاً
856) - 1,000 تا 999,999: با K نمایش داده میشود (مثلاً
5.4K) - 1,000,000 و بیشتر: با M نمایش داده میشود (مثلاً
1.2M)
حاشیه آواتار
gold: حاشیه طلایی با گرادیانت - مناسب برای پروفایلهای برجسته و ویژهprimary: حاشیه با رنگ اصلی برند - مناسب برای حالت فعالnone: بدون حاشیه - حالت ساده و مینیمال
اندازهها
sm: مناسب برای Sidebar و فضاهای محدودmd: اندازه پیشفرض، مناسب برای اکثر مواردlg: مناسب برای صفحات اصلی و نمایش برجسته
RTL Support
کامپوننت به طور کامل از RTL پشتیبانی میکند. برای استفاده در محیط انگلیسی:
<div dir="ltr">
<ProfileCard
name="Mohsen Yeganeh"
username="mohsene"
avatarSrc="/avatar.jpg"
followers={125000}
followersIcon={<Users className="h-3.5 w-3.5" />}
/>
</div>Accessibility
- کامپوننت از semantic HTML استفاده میکند
- تمام تصاویر دارای alt text مناسب هستند
- قابلیت ناوبری با کیبورد
- میتوانید
aria-labelسفارشی اضافه کنید:
<ProfileCard
name="محسن یگانه"
username="mohsene"
aria-label="کارت پروفایل محسن یگانه با ۱۲۵ هزار فالوور"
// ...
/>تفاوت با Profile Info
ProfileCard برای نمایش عمودی و متمرکز طراحی شده و مناسب گریدها و carouselها است.
ProfileInfo برای نمایش افقی طراحی شده و مناسب لیستها، منوها و sidebar است.
// استفاده از ProfileCard - عمودی
<div className="grid grid-cols-4 gap-4">
<ProfileCard name="..." username="..." />
</div>
// استفاده از ProfileInfo - افقی
<div className="space-y-2">
<ProfileInfo name="..." username="..." />
</div>راهنمای استفاده
بکنید
- همیشه
avatarAltیاinitialsبرای fallback آواتار مشخص کنید - ازsize="sm"برای فضاهای محدود مانند sidebar استفاده کنید -onCardClickرا برای ناوبری به صفحه پروفایل استفاده کنید
نکنید
- از ProfileCard در جدول یا لیست استفاده نکنید — از
ProfileInfoاستفاده کنید - بدونusernameاز کامپوننت استفاده نکنید — username برای شناسایی الزامی است - از variantdarkدر تم dark استفاده نکنید — کنتراست ناکافی خواهد بود
دسترسیپذیری
- کامپوننت از semantic HTML استفاده میکند
- تمام تصاویر دارای alt text مناسب هستند
- قابلیت ناوبری با کیبورد پشتیبانی میشود
- میتوانید
aria-labelسفارشی اضافه کنید
کامپوننتهای مرتبط
- ProfileInfo — اگر نیاز به نمایش افقی و فشرده پروفایل در لیست یا جدول دارید، از ProfileInfo استفاده کنید
- Avatar — اگر فقط نمایش تصویر پروفایل بدون اطلاعات اضافی نیاز دارید، از Avatar استفاده کنید
- Card — اگر محتوای کارت مربوط به پروفایل شخصی نیست، از Card عمومی استفاده کنید