متن پست (PostBody)
محتوای متن + media یک پست — text، image، carousel، video، missing-media
معرفی
PostBody رندرر محتوای یک پست است: متن، تصویر، carousel، ویدیو، یا حالت "media مفقود". building block داخلی PostCard که برای layout های سفارشی نیز export شده. الگوی centering تصویر در packages/ui/CLAUDE.md ("Media centering — canonical pattern") مستند است.
متن خالص
نمونهی متن خالص بدون رسانه — مناسب کوتاهنوشتهها و quote-feedها.
تصویر تکی
نمونهی استفاده مستقیم از سازندههای PostCard در یک کارت سفارشی.
زمین بازی
زمین بازی
تجربهام از خرید آنلاین #دیجیکالا عالی بود. @sara_pm نظرت چیه؟
تنظیمات
داده
ظاهر
کد این نمونه بهصورت خودکار قابل تولید نیست — برای کد آمادهی copy/paste به بخش «استفاده» در بالای صفحه مراجعه کنید.
چه زمانی مستقیم استفاده کنیم:
- detail-view پست با sidebar (PostDetailsDrawer از این استفاده میکند)
- لیست fragment-های پست در یک گزارش
- preview در composer ها
چه زمانی استفاده نکنیم:
- یک پست در feed →
PostCardکه خودPostBodyرا داخل header/actions/metadata قرار میدهد
ساختار body
PostBodyData یک discriminated union است:
{ type: 'text', text }— فقط متن{ type: 'image', media, caption? }— یک تصویر{ type: 'carousel', media[], caption? }— چند تصویر{ type: 'video', media, caption? }— ویدیو با thumbnail{ type: 'missing-media', caption?, reason? }— تصویر/ویدیو در دسترس نیست (پلتفرم آن را حذف کرده، fetch fail شد، …)
import { PostBody } from '@parto-system-design/ui'
;<PostBody
body={{
type: 'image',
media: { url: '/post.jpg', alt: 'پست' },
caption: 'متن زیر تصویر',
}}
/>نکته centering
برای letterbox media (image/carousel/video)، الگوی centering canonical بهصورت:
<div className="relative w-full overflow-hidden flex items-center justify-center">
{/* blur backdrop */}
<img src={src} className="absolute inset-0 size-full object-cover object-center blur-2xl opacity-50" aria-hidden />
{/* foreground */}
<img src={src} alt={alt} className="relative block max-h-full max-w-full w-auto h-auto object-contain" />
</div>این از PostBody بهعنوان implementation reference استفاده میشود. هرگز <img class="mx-auto h-full w-auto"> استفاده نکنید — این الگوی شکستخوردهی شناختهشده در DS است.
استفاده
import { PostCard, PostBody } from '@parto-system-design/ui'
// بهصورت معمول داخل PostCard wired است:
<PostCard post={post} />
// استفاده مستقیم در detail-view یا composer:
<PostBody
body={post.body}
context="comfortable"
/>راهنمای استفاده
بکنید
contextرا با والد همگام نگه دارید (compactدر feed،comfortableدر detail) — این aspect handling و text-clamping را تنظیم میکند - برای تصاویر با aspect ratio غیرعادی،media.aspectRatioرا رویPostMediaItemست کنید تا layout shift نداشته باشید - برای کارتهای thumbnail-only ازthumbnailOnlyاستفاده کنید — body text را خود والد رندر میکند
نکنید
- الگوی
<img class="mx-auto h-full w-auto">را برای centering استفاده نکنید — این bug-known در DS است (به CLAUDE.md رجوع کنید) -body.typeرا بهصورت دلخواه گسترش ندهید — discriminated union درpost-card.types.tsتعریف شده و TypeScript exhaustiveness را تأمین میکند
جدول ویژگیها
دسترسیپذیری
- تصاویر
altمعنادار ازPostMediaItem.altمیگیرند؛ اگرaltخالی باشد، تصویر decorative تلقی میشود. - ویدیوها با آیکون Play overlay رندر میشوند؛ Play بهصورت
aria-hiddenاست و کنترل اصلی از طریق consumer wired میشود (PostCardonClickپست را دنبال میکند). - Carousel از Embla مبتنی است و دکمههای Previous/Next ARIA-labeled هستند؛ keyboard navigation با Arrow keys کار میکند.
- لینکهای داخل متن (URL) با
dir="ltr"وtarget="_blank"+rel="noreferrer"رندر میشوند تا screen reader آدرس را بهدرستی بخواند. - حالت
missing-mediaبا ImageOff icon + caption descriptive رندر میشود تا کاربر بفهمد رسانه قابل بازیابی نیست (نه bug سمت کلاینت).
کامپوننتهای مرتبط
- کارت کامل پست →
PostCard - detail drawer →
PostDetailsDrawer - بازیابی fail-safe تصویر →
SafeImage