پرتوپرتو

لیست پست (PostList)

کانتینر لیست پست‌ها با toggle حالت نمایش، ناوبری کیبورد، و پشتیبانی از انتخاب چندتایی

معرفی

PostList یک wrapper برای PostCard است که نیازمندی‌های مشترک صفحه‌ی feed — toggle حالت نمایش (view)، keyboard navigation (↑↓ / j/k)، نگهداری انتخاب کاربر، و deep-linking — را به صورت یکپارچه ارائه می‌دهد.

چه زمانی استفاده کنیم:

  • صفحه نتایج جستجو یا feed پست‌های چندپلتفرمی
  • لیست‌هایی که کاربر باید بین فشرده، راحت و گرید سوییچ کند
  • لیست‌هایی با نیاز به انتخاب چندتایی برای bulk actions

چه زمانی استفاده نکنیم:

  • اگر فقط یک یا دو پست نمایش می‌دهید → PostCard مستقیم
  • اگر نیاز به ساختار جدولی با ستون‌های دلخواه دارید → DataTable
  • اگر لیست کامنت زیر پست است → CommentCard در یک اسکرول ساده

زمین بازی

با تغییر تنظیمات زیر، پیش‌نمایش زنده را مشاهده کنید.

زمین بازی
@علی_رضایی
پست نمونه از علی رضایی برای نمایش لیست.
۱۰۰۱۰۲
@مریم_اکبری
پست نمونه از مریم اکبری برای نمایش لیست.
۱۰۰۱۰۲
@حسین_کریمی
پست نمونه از حسین کریمی برای نمایش لیست.
۱۰۰۱۰۲
تنظیمات
ظاهر
کد این نمونه به‌صورت خودکار قابل تولید نیست — برای کد آماده‌ی copy/paste به بخش «استفاده» در بالای صفحه مراجعه کنید.

استفاده

@sara.ahmadi
تجربه خریدم از #دیجی‌کالا واقعاً عالی بود! محصول دقیقاً همان‌طور که توضیح داده شده بود و ظرف ۲۴ ساعت به دستم رسید. #رضایت_مشتری
۸۷۶۱۲۴۴۳۱۲.۴K
مثبت
@ali_r
·۸۹ کامنت
سه بار با پشتیبانی تماس گرفتم ولی هنوز مشکل بازگشت کالا حل نشده. خدمات پس از فروش واقعاً افت کرده @DigiKala
۸.۹K۲۳۴۸۹
منفی
@digimag_ir
گزارش سه‌ماهه دیجی‌کالا: رشد ۳۴٪ در تراکنش‌های موبایل، افزایش ۱۸٪ در میانگین سبد خرید. مدیرعامل: «هدف تا پایان سال ۵ میلیون کاربر فعال روزانه است.»
۴۵.۲K
خنثی
@TechPlusIR
·تحلیلرونوشت
۲۰:۳۸
آنباکسینگ و بررسی کامل لپ‌تاپ خریداری‌شده از #دیجی‌کالا آیا ارزش قیمت را دارد؟
۱۵۶K۸.۹K۱.۲K
مثبت
import { PostList, type PostData } from '@parto-system-design/ui'

const posts: PostData[] = [...]

export default function Feed() {
  const [selectedIds, setSelectedIds] = React.useState<string[]>([])
  const [activeId, setActiveId] = React.useState<string>()

  return (
    <PostList
      posts={posts}
      activeId={activeId}
      selectedIds={selectedIds}
      onSelectedIdsChange={setSelectedIds}
      onOpen={(post) => setActiveId(post.id)}
    />
  )
}

حالت‌های نمایش (view)

پراپ view تنها مسیر تغییر چینش کارت‌هاست و سه مقدار می‌گیرد:

مقدار viewlayoutکاربرد
compactردیف فشرده — thumbnail کناری + پیش‌نمایش متن یک‌خطیfeed با حجم زیاد، triage و اسکن سریع
comfortableکارت عمودی کامل — هدر، بدنه، رسانه، metrics و signals (پیش‌فرض)حالت پیش‌فرض، خواندنی، تحلیل تک‌پست
gridکاشی مربعی media-dominant در گرید چندستونهfeed بصری شبیه اینستاگرام، گالری رسانه‌ای

حالت کنترل‌نشده (پیش‌فرض)

اگر prop view را ندهید، کامپوننت حالت نمایش را در localStorage نگه می‌دارد و کاربر می‌تواند بین سه حالت سوییچ کند.

<PostList posts={posts} />

حالت کنترل‌شده

برای زمانی که می‌خواهید view را از URL یا state بالاتر کنترل کنید (مثلاً همگام‌سازی بین tabها یا persist روی URL):

const [view, setView] = React.useState<'compact' | 'comfortable' | 'grid'>('comfortable')

<PostList
  posts={posts}
  view={view}
  onViewChange={setView}
/>

بدون toolbar — toggle بیرونی

اگر toggle حالت نمایش را خودتان در یک header سفارشی رندر می‌کنید، با showToolbar={false} toolbar داخلی را خاموش کنید.

<PostList posts={posts} showToolbar={false} view={view} onViewChange={setView} />

toolbarExtra — افزودن کنترل کنار toggle

با toolbarExtra می‌توانید فیلتر، dropdown مرتب‌سازی، یا breadcrumb را در همان نوار toolbar در کنار toggle view قرار دهید.

<PostList
  posts={posts}
  toolbarExtra={
    <div className="flex items-center gap-2">
      <FilterChip label="پلتفرم: توییتر" />
      <FilterChip label="احساس: مخالف" />
    </div>
  }
/>

انتخاب چندتایی برای bulk actions

با ارائه selectedIds و onSelectedIdsChange Checkbox روی هر کارت فعال می‌شود و Space از روی صفحه‌کلید وضعیت انتخاب را toggle می‌کند.

const [selectedIds, setSelectedIds] = React.useState<string[]>([])

<PostList
  posts={posts}
  selectedIds={selectedIds}
  onSelectedIdsChange={setSelectedIds}
/>

حالت read با readIds

با پاس دادن readIds (آرایه یا Set) پست‌های قبلاً بازشده با visual «دیده‌شده» متفاوت رندر می‌شوند. مناسب برای feed افکارسنجی روزانه.

<PostList
  posts={posts}
  readIds={new Set(['post-1', 'post-3'])}
  activeId="post-2"
  onOpen={(post) => router.push(`/posts/${post.id}`)}
/>

اکشن‌های مشترک روی همه کارت‌ها

با actions می‌توانید مجموعه اکشن یکسانی (ذخیره، گزارش، اشتراک) را برای تمام کارت‌های لیست تعریف کنید.

<PostList
  posts={posts}
  actions={[
    { id: 'save', label: 'ذخیره', onClick: (p) => savePost(p.id) },
    { id: 'flag', label: 'گزارش تخلف', onClick: (p) => flagPost(p.id) },
  ]}
/>

راهنمای استفاده

بکن

  • برای deep-linking، activeId را از URL بگیرید تا با back/forward مرورگر کار کند. - برای bulk actions، کنترل‌شده بودن selectedIds را حفظ کنید تا بتوانید لیست را خارج از PostList خالی کنید. - در صورت تغییر حالت پیش‌فرض برای کاربران جدید، localStorage را پاک کنید.

نکن

  • از PostList برای لیست‌های ۵۰۰۰+ بدون virtualization استفاده نکنید — virtualization در Phase 4 اضافه می‌شود. - ناوبری کیبورد خودکار را با onKeyDown سفارشی روی کارت‌ها overwrite نکنید — PostCard خودش Enter/Space را می‌پذیرد.

جدول ویژگی‌ها

PostList

Prop

Type

دسترسی‌پذیری

  • ↑/↓ و j/k بین کارت‌ها focus را جابجا می‌کنند.
  • Enter روی کارت focus شده پست را باز می‌کند.
  • Space وضعیت انتخاب را toggle می‌کند (اگر onSelectedIdsChange ارائه شده باشد).
  • ToggleGroup حالت نمایش aria-label فارسی دارد (حالت فشرده / حالت راحت / حالت گرید).

کامپوننت‌های مرتبط

  • PostCard — بلوک سازنده‌ی لیست. اگر فقط یک پست دارید، مستقیم از این استفاده کنید.
  • DataTable — اگر نیاز به ستون‌های دلخواه و sort دارید، نه ساختار پست.
  • Pagination — PostList در حال حاضر pagination داخلی ندارد؛ آن را بیرون wrap کنید.