کارت مفهوم (ConceptCard)
کارت headline پایش برای کلاسترینگ نظرات — ترکیب وضعیت، شدت، توزیع گرایش، sentiment، sparkline، خلاصه AI، و چکباکس مقایسه
معرفی
ConceptCard کارت تک-مفهومی برای dashboardهای کلاسترینگ نظرات است: هر کارت یک خوشه (concept) از نظرات همگرا را نمایش میدهد. composition آن شامل شدت (severity)، توزیع گرایش مخاطب (5-class)، توزیع sentiment (3-class)، trend sparkline، و یک خلاصهی AI است. مناسب grid 3-ستونه در صفحهی کلاسترها.
چه زمانی استفاده کنیم:
- صفحهی کلاسترها/خوشهها که دهها concept را بهصورت grid قابل-مقایسه نشان میدهد
- خروجی تحلیل ML که برای هر cluster signalهای متنوع تولید میکند (flow، emotion، trend)
- صفحهی انتخاب چندتایی برای مقایسه —
comparisonprop checkbox header را اضافه میکند - کارت مسئله در صفحهٔ «مسائل رصدشده»: عنوان پیوند واقعی (
href)، اقدامهای کارت (actions)، دو خط خلاصه، عددهای برچسبدار (stats) و تغییر با دورهٔ مقایسهٔ نامبرده (trendDelta) — بدون ساختن کارت دومی
چه زمانی استفاده نکنیم:
- یک concept تکی در detail view → از
MetricCard+ Charts جداگانه برای هر signal استفاده کنید (نمایش بزرگتر) - لیست خبر/پست با کاربرد متفاوت →
Post، و فهرستشEntityCollectionباentity="post" - وقتی فقط نام و یک متریک میخواهید →
Cardپایه
رونمایی گوشی جدید
فوریخوشه 4 — 1,240 پست
حجم نظرات منفی در 24 ساعت اخیر سه برابر شده. تمرکز روی شهرهای بزرگ.
زمین بازی
رونمایی گوشی جدید
فوریخوشه 4 — 1,240 پست
حجم نظرات منفی در 24 ساعت اخیر سه برابر شده.
استفاده
import { ConceptCard } from '@partodata/ui'
;<ConceptCard
title="رونمایی گوشی جدید"
subtitle="خوشه 4 — 1,240 پست"
severity="urgent"
flow={{ 'pro-gov': 80, 'internal-critic': 320, 'internal-opponent': 540, 'external-opponent': 200, grey: 100 }}
sentiment={{ positive: 120, negative: 920, neutral: 200 }}
trend={[8, 12, 15, 22, 35, 48, 56, 78]}
totalCount={1240}
aiSummary="حجم نظرات منفی در 24 ساعت اخیر سه برابر شده."
/>حالتها
کارت مسئله در شبکهٔ صفحهکلیدی
از 7.9 ConceptCard همان کارت یک مسئله (یا موضوع) در صفحهٔ فهرست است: عنوان یک پیوند واقعی است که روی کل کارت کشیده میشود (کلیک وسط و «باز کردن در تب تازه» کار میکند)، actions در انتهای سربرگ بالای پیوند مینشیند و کلیک یا Enter روی آنها کارت را باز نمیکند. EntityCollection entity="concept" کارتها را در شبکه میچیند و همهٔ ناوبری صفحهکلید (یک توقف Tab، فلشها، j/k، Home/End، Enter) را رایگان میدهد.
<EntityCollection
entity="concept"
label="مسائل"
items={issues}
getId={(issue) => issue.id}
renderItem={(issue, item) => (
<ConceptCard
{...item}
title={issue.title}
href={`/issues/${issue.id}`}
severity={issue.severity}
eyebrow="زیرساختی · در حال پردازش"
aiSummary={issue.summary}
summaryLines={2}
sentiment={issue.sentiment}
trend={issue.trend}
trendTone="neutral"
trendDelta={{ value: issue.delta, comparisonLabel: 'در برابر 7 روز قبل', tone: 'negative' }}
stats={[{ label: 'محتوا در بازه', value: issue.count }]}
actions={<FollowButton issue={issue} />}
/>
)}
/>trendTone: رنگ نمودار کوچک بر پایهٔ قطبیت. حجم قطبیت ندارد، پسneutral؛ نمودار شکل است و عدد کنارش مقدار را میرساند.trendDeltaهمیشه باcomparisonLabelمیآید («در برابر 7 روز قبل»)، وtoneآن بهطور پیشفرضneutralاست؛ برای مسئلهای که رشدش خبر بد استtone: 'negative'بدهید.statsعددهای برچسبدار با جداکنندهٔ هزارگان (ارقام ASCII) است و جایtotalCountرا میگیرد: «مجموع» بدون «از چه و در کدام بازه» نیمحرف است.summaryLinesارتفاع کارتهای یک شبکه را یکی میکند.
مقایسه
بازخورد بستهبندی جدید
بالابا تنظیم comparison، یک checkbox در هدر کارت ظاهر میشود. checkbox خواهرِ کنترلِ فعالسازی کارت است، نه فرزندِ آن؛ بنابراین نقش و وضعیت انتخابشدنش برای screen reader کاملاً نمایان میماند. هندلر کلیکِ کارت هر کلیکی را که از داخل یک کنترل تودرتو (از جمله همین checkbox) شروع شده باشد نادیده میگیرد تا کلیک روی checkbox باعث activate شدن کل کارت نشود.
وقتی comparison.selected برابر true باشد، خودِ کارت هم data-selected میگیرد و border/background آن با رنگ برند تغییر میکند — نه فقط چکباکس 16 پیکسلی. در یک grid 3-ستونهی مقایسه، این یعنی کارتهای انتخابشده بدون نیاز به شکار کردن چکباکسها قابل تشخیصند.
const [selected, setSelected] = React.useState(false)
<ConceptCard
title="کمپین تخفیف فصلی"
comparison={{ selected, onSelectionChange: setSelected, label: 'مقایسه' }}
...
/>راهنمای استفاده
بکنید
- برای کلاسترهای فوری
severity="urgent"بدهید — نشان شعله و رنگ قرمز سیگنال قوی میسازند -aiSummaryرا به 1-2 جمله محدود کنید — کارت clamp خودکار ندارد و متن بلند بهطور کامل رندر میشود -trendرا با 8-14 نقطه پاس بدهید — sparkline ضد-noise است
نکنید
- بیش از 9 کارت در یک ردیف نگذارید — grid شلوغ و غیر-قابلاسکن میشود -
flowرا وقتی فقط 2 گرایش غالب دارید پاس ندهید — distribution flat میشود و ارزش بصری ندارد
جدول ویژگیها
دسترسیپذیری
- ریشهی کارت همیشه
role="article"است و باaria-labelledbyبه عنوان کارت گره میخورد؛ هیچوقتrole="button"نمیگیرد. نقشbuttonفرزندانش را presentational میکند و همین باعث میشد checkboxcomparisonو badgeها برای screen reader تخت شوند. - وقتی
interactive=true(یاonClick) پاس شود، تنها تباستاپ کارت یک<button data-slot="concept-card-trigger">روی عنوان است؛ با Enter/Space فعال میشود و ring فوکوس روی همان دکمه مینشیند. کلیک روی کل سطح کارت هم کار میکند، ولی صرفاً یک میانبر ماوس است. - هندلر کلیکِ کارت هر کلیکی را که از داخل یک کنترل تودرتو (
a،button،input،select،textareaیا هر عنصر باroleتعاملی) شروع شده باشد نادیده میگیرد، مگر آنکه خودِ trigger کارت باشد؛ بنابراین کلیک روی checkboxcomparisonکارت را فعال نمیکند و ترتیب فوکوس مستقل میماند. - سطح اولویت با
SeverityBadgeنشان داده میشود (5.0:statusدر آن ادغام شد) و معنا از رنگ + آیکون + برچسب سطح منتقل میشود. - توزیع flow و sentiment بهصورت segmentهای رنگی نمایش داده میشوند ولی متن جداگانه (مثل subtitle یا total count) معنا را منتقل میکند تا کاربر color-blind محروم نماند.
aiSummaryبهطور پیشفرض clamp ندارد؛ برای شبکهٔ همارتفاعsummaryLinesبدهید.- با
href، عنوان یک<a>است و همان تنها هدف کارت؛ حلقهٔ فوکوس دور کل کارت مینشیند. درEntityCollection(کهtabIndexمیدهد) خود کارت توقف Tab است، پیوند عنوان از ترتیب Tab بیرون میرود وEnterروی کارت آن را باز میکند،Spaceانتخاب را عوض میکند و فلشها بین کارتها میروند؛Tabواردactionsهمان کارت میشود. - جهت
trendDeltaبا پیکان و علامت چاپی نمایش داده میشود، نه با رنگ تنها.
کامپوننتهای مرتبط
- شمارِ شاخص که به فهرست مسائل میرود →
MetricCardباhref؛ شمار روی کارت با شمار فهرست مقصد برابر باشد - برای حساب/پیج بهجای مفهوم →
Account - برای یک پست تکی →
Post - توزیع گرایش بهصورت standalone →
Distribution kind="flow" - برای ترکیب چندتا کارت در یک گزارش →
ReportComposer+ConceptCardبهعنوان children