کارت پست (PostCard)
نمایش یکپارچه پست از تمام پلتفرمهای سوشاللیسنینگ — اینستاگرام، توییتر، تلگرام، یوتیوب، تیکتاک، لینکدین، ترِدز — با دو چگالی فشرده و راحت، handling خودکار نسبتهای ابعادی، و اکشنهای آیکنی روی هاور.
معرفی
PostCard اصلیترین کامپوننت نمایش پست در دیزاینسیستم پارتو است. به جای تقلید از UI هر پلتفرم، ساختار یکسانی ارائه میدهد و بدنهی پست را بر اساس نوع محتوا (متن، تصویر تکی، کاروسل، ویدیو، مدیای دانلودنشده) رندر میکند. تصاویر با هر نسبت ابعادی (1:1، 4:5، 9:16، 16:9) بهصورت یکنواخت با بکدراپ بلور نمایش داده میشن — بدون کراپ، بدون فضای خالی زشت.
چه زمانی استفاده کنیم:
- فید نتایج جستجو / پایش در محصولات سوشاللیسنینگ و افکارسنجی
- triage روزانه تحلیلگر (حالت فشرده) و مرور عمیق (حالت راحت)
- لیست چندمنبعی پستها با نیاز به اسکنپذیری بالا یا بررسی دقیق
- داشبورد تحلیل برند، ردیابی هشتگ، یا بولتن تحلیلی
چه زمانی استفاده نکنیم:
- نمایش یک کامنت مجزا → از
CommentCardاستفاده کنید - نمایش کارت اطلاعاتی بدون ساختار پست (محصول، پروفایل، کار) → از
Card،ProfileCard، یاJobCardاستفاده کنید - فقط نشان پلتفرم بدون ساختار پست → از
SocialPlatformBadgeاستفاده کنید
زمین بازی
با تغییر تنظیمات زیر، پیشنمایش زنده را مشاهده کنید.
استفاده
import { PostCard, type PostData } from '@parto-system-design/ui'
const post: PostData = {
id: 'p1',
source: 'instagram',
author: { name: 'سارا احمدی', handle: 'sara.ahmadi', verified: true },
timestamp: Date.now() - 60_000 * 23,
body: { type: 'text', text: 'تجربه خریدم از #دیجیکالا عالی بود!' },
sentiment: 'positive',
metrics: { views: 12400, likes: 876, comments: 124 },
}
export default function Example() {
return (
<PostCard
post={post}
view="comfortable"
onOpen={(p) => console.log('open', p.id)}
onOpenDetails={(p) => console.log('details', p.id)}
/>
)
}حالتها و انواع
چگالی فشرده (Triage)
برای فیدهایی که کاربر باید سریع اسکن کند. ارتفاع ردیف ثابت، متن تا دو خط، thumbnail کوچک. اکشنهای آیکنی فقط در زمان هاور یا فوکوس ظاهر میشن.
آخرین گزارش از وضعیت بازار سرمایه طی هفته جاری منتشر شد؛ شاخص کل با رشد ۲.۳ درصدی به رکورد تاریخی رسید و حجم معاملات به طور چشمگیری افزایش یافت.
تحلیل کارشناسان درباره تأثیر تصمیم جدید بانک مرکزی بر نرخ ارز و شاخص تورم در ماههای آینده.
نمودار تغییرات شاخص بورس طی هفته گذشته — رشد قابل توجه در سه روز پایانی.
چگالی راحت (Reading)
کارت کامل با padding، مدیای inline با نسبت ابعادی حفظشده، متریکهای کامل، چیپهای تگ و وضعیت enrichment. اکشنهای آیکنی فقط روی هاور نمایش داده میشن — کارت مینیمال باقی میمونه.
همه نسبتهای ابعادی (بکدراپ بلور)
هر نسبت ابعادی بهصورت یکنواخت رندر میشه. تصویر کامل (object-contain) در مرکز نمایش داده میشه و فضای خالی اطراف با همان تصویر بلورشده + scale-110 پر میشه. بدون کراپ = بدون از دست رفتن اطلاعات. 9:16 ریل/استوری، 4:5 فید پرتره، 1:1 مربع، 16:9 یوتیوب — همگی در یک کانتینر سازگار.
انواع بدنه
فقط متن
اگر body.type === 'text'، کارت بدون کانتینر مدیا رندر میشه. هشتگها، منشنها و URL ها خودکار با رنگ برند هایلایت میشن.
ویدیو
پوستر ویدیو با overlay دایرهای Play + مدت زمان، حتی برای 9:16 و 16:9 بهصورت letterbox با بکدراپ بلور.
کاروسل (گالری چندتایی)
چند اسلاید با navigator RTL-آگاه. نسبت ابعادی container بر اساس اسلاید غالب محاسبه میشه و همه اسلایدها در همون container ثابت با بکدراپ بلور رندر میشن.
مدیای دانلودنشده
اگر مدیا موجود بود ولی نتونستیم دانلود/ذخیره کنیم، از body: { type: 'missing-media' } استفاده کنید تا به جای img شکسته، placeholder واضح نمایش داده بشه.
چهار حالت احساس (Sentiment)
positive / negative / neutral / mixed — هرکدام chip خاص خودش رو داره. در حالت راحت کنار نام نویسنده، در حالت فشرده قبل از اکشنها.
وضعیت enrichment + تگهای دامنه
پرچمهای ocr / transcript / aiAnalysis / commentCount در header نمایش داده میشن. تگهای دامنه (رضایت مشتری، شکایت، …) در فوتر. authorityScore هم در header قابل نمایش است.
۷ پلتفرم پشتیبانیشده
نشان پلتفرم (اینستاگرام، توییتر، تلگرام، یوتیوب، تیکتاک، لینکدین، ترِدز) بهصورت نقطه رنگی کوچک روی avatar نویسنده رندر میشه.
پست جدیدم با هایلایت محصولات تازهرسیده — هفتهی بعد لایو میذارم. #خرید_آنلاین
پشتیبانی باید سریعتر پاسخ بده — سه روز منتظر جواب تیکت بودم @DigiKala
گزارش سهماهه: رشد ۳۴٪ در تراکنشهای موبایل و افزایش ۱۸٪ در میانگین سبد خرید.
آنباکسینگ و بررسی کامل لپتاپ جدید — آیا ارزش خرید دارد؟ لینک در توضیحات.
تِرِند جدید: چالش هفته با فیلترهای تازه. چه کسی جرأت میکنه؟ #چالش_هفته
پنل امروز: سه درس کلیدی از ۵ سال تجربه در صنعت تجارت الکترونیک ایران.
کمپین تابستانه ۳۴٪ درآمد بیشتر — استراتژی قیمتگذاری پویا نقش کلیدی داشت.
تجربه خرید آنلاین در سال جدید — مقایسهی پلتفرمهای مختلف.
حالتهای انتخاب و خواندهشده
read={true}→ opacity کاهش یافته (پست قبلاً باز شده)selected={true}→ پسزمینه برند ملایمselectable={true}→ checkbox برای انتخاب چندتایی
این کارت هنوز خواندهنشده است — نقطه برند در ابتدای ردیف نشانگر آن است.
این کارت قبلاً باز شده — opacity کمتر شده تا توجه به پستهای جدید جلب شود.
این کارت انتخابشده است — پسزمینه برند ملایم نشانگر selection در حالت چندگزینهای.
اکشنهای آیکنی (Icon-only با Tooltip)
اکشنهای پیشفرض همگی بهصورت آیکن (بدون متن) با Tooltip نمایش داده میشن و فقط روی هاور یا فوکوس کارت ظاهر میشن:
| آیکن | اکشن | Tooltip |
|---|---|---|
Maximize2 | باز کردن مدال جزئیات | «مشاهده جزئیات کامل پست» |
Flag | ارجاع به تحلیلگر | «ارجاع به تحلیلگر» |
Bookmark | افزودن به بولتن | «افزودن به بولتن» |
FileSearch | ارسال به کامنتسنج | «ارسال به کامنتسنج» |
Sparkles | تحلیل هوشمند | «تحلیل هوشمند» |
ExternalLink | مشاهده در مبدأ | «مشاهده در مبدأ» |
برای کاستومایز کردن یا حذف/افزودن اکشن، prop actions رو پاس بدید:
import { Bookmark, Flag, Maximize2 } from 'lucide-react'
;<PostCard
post={post}
actions={[
{ id: 'details', label: 'باز کردن', icon: Maximize2, onClick: (p) => openModal(p) },
{ id: 'bookmark', label: 'ذخیره', icon: Bookmark, onClick: (p) => saveToBulletin(p) },
{ id: 'flag', label: 'گزارش', icon: Flag, onClick: (p) => report(p), variant: 'danger' },
]}
/>ترکیب با PostList
برای نمایش لیست چندپست با toggle چگالی، keyboard nav (Arrow/j/k)، و انتخاب چندتایی، از PostList استفاده کنید:
import { PostList, type PostData } from '@parto-system-design/ui'
const [readIds, setReadIds] = React.useState<Set<string>>(new Set())
<PostList
posts={posts}
readIds={readIds}
onOpen={(p) => { setReadIds((s) => new Set([...s, p.id])); open(p) }}
onOpenDetails={(p) => openDetailsModal(p)}
/>ترکیب با PostDetailsDrawer
با کلیک روی آیکن Maximize2 (یا هرچیز که به onOpenDetails وصل کردید)، پنل کناری جزئیات باز میشه. drawer تبهای پست، کامنتها، تحلیل هوشمند و متن استخراجشده رو نشون میده، و با j/k بین پستهای فید جابهجا میشه.
برای API کامل drawer، صفحه PostDetailsDrawer رو ببینید.
راهنمای استفاده
بکنید
- برای لیستهای طولانی، از
PostListاستفاده کنید تا toggle چگالی، keyboard nav و bulk selection خودکار داشته باشید. - پرچمهای
enrichmentsرا فقط وقتی ست کنید که داده واقعاً موجود است — chip بیپشتوانه کاربر را گمراه میکند. - برای پستهای بدون مدیای قابلدانلود از
body: { type: 'missing-media' }استفاده کنید، نهimgشکسته. sourceUrlرا ست کنید تا اکشن «مشاهده در مبدأ» کار کند.- برای انتخاب چندتایی،
selectableوonSelectرا از بالا کنترل کنید.
نکنید
- رنگ پلتفرم را به پسزمینهی کارت نزنید — فقط نقطه رنگی کوچک روی avatar. - sentiment را روی کل کارت رنگ نکنید — فقط
chip سنجاقی در header. - چگالی پیشفرض را از
compactتغییر ندهید؛ کاربر فشرده را برای triage انتخاب کرده است. - عکسها را خودتان crop نکنید؛aspectRatioطبیعی را پاس بدید تا کامپوننت letterbox + بکدراپ بلور بزنه. -actionsرا با کامپوننت Button خارجی جایگزین نکنید — ازPostAction[]استفاده کنید تا ساختار یکپارچه بمونه.
جدول ویژگیها
PostCard
PostData
PostAuthor
PostBodyData (Discriminated Union)
PostMediaItem
PostEnrichmentFlags
PostAction
دسترسیپذیری
- کارت
role="button"وtabIndex=0دارد — با Tab قابل focus است. - Enter پست را باز میکند (
onOpen). - Space وضعیت انتخاب را toggle میکند (
onSelectوقتیselectable). - Escape روی کارت اثری ندارد — در
PostDetailsDrawerبرای بستن drawer استفاده میشود. - Checkbox و اکشنهای آیکنی همگی
aria-labelدارند. - Tooltip زمان مطلق روی timestamp با keyboard focus ظاهر میشود.
- اکشنهای آیکنی فقط روی hover/focus ظاهر میشوند اما همیشه در DOM هستند (screen-reader دسترسی دارد).
- در
PostListبا Arrow Up/Down یا j/k بین کارتها حرکت میکنید.
کامپوننتهای مرتبط
- PostList — اگر نیاز به toggle چگالی + keyboard nav + bulk selection دارید.
- PostDetailsDrawer — برای نمایش کامل پست همراه کامنت، تحلیل هوشمند، OCR و متادیتای پلتفرم.
- CommentCard — برای نمایش تحلیلشده یک کامنت مستقل با تگهای موضوعی.
- SocialPlatformBadge — اگر فقط نشان پلتفرم میخواهید بدون ساختار پست.
- EmotionDistribution — توزیع احساسات ۹-کلاسه (داخل
PostDetailsDrawerاستفاده میشود).
ویزارد کار (JobWizard)
wizard چندمرحلهای canonical برای راهاندازی کارهای async — تحلیل، کمپین، ارزیابی، ایمپورت — با per-step validation، draft persistence، و finish state (submitting/success/error).
لیست پست (PostList)
کانتینر لیست پستها با toggle حالت نمایش، ناوبری کیبورد، و پشتیبانی از انتخاب چندتایی