اشتباهات رایج
الگوهایی که باید از آنها پرهیز کنید — بر اساس مشکلات واقعی در محصولات پرتو
اشتباهات رایج
این صفحه اشتباهات پرتکرار را که در محصولات پرتو دیده شدهاند مستند میکند. هر آیتم یک نام، توضیح، مشکل، و راهحل دارد.
رنگهای Hardcode
مشکل: استفاده از رنگهای مستقیم Tailwind به جای توکنهای سیستم.
// ❌ غلط
<span className="text-gray-500">توضیحات</span>
<div className="bg-gray-900 text-white">محتوا</div>
<div style={{ color: '#22c55e' }}>موفقیت</div>
// ✅ درست
<span className="text-muted-foreground">توضیحات</span>
<div className="bg-foreground text-background">محتوا</div>
<span className="text-brand">موفقیت</span>چرا اشتباه است: رنگهای hardcode در تم dark کار نمیکنند و WCAG contrast را نقض میکنند.
CSS Properties فیزیکی در RTL
مشکل: استفاده از ml، mr، pl، pr، left، right به جای Logical Properties.
// ❌ غلط — در RTL چیدمان معکوس میشود
<div className="ml-4 pl-6 border-l-2 text-left">محتوا</div>
// ✅ درست — با RTL و LTR هر دو کار میکند
<div className="ms-4 ps-6 border-s-2 text-start">محتوا</div>چرا اشتباه است: در محیط RTL (فارسی)، ml به چپ اضافه میشود اما انتظار داریم به راست اضافه شود.
| فیزیکی ❌ | Logical ✅ |
|---|---|
ml-* | ms-* |
mr-* | me-* |
pl-* | ps-* |
pr-* | pe-* |
text-left | text-start |
text-right | text-end |
چند دکمه Primary در یک صفحه
مشکل: بیش از یک variant="primary" در یک view.
// ❌ غلط — کاربر نمیداند کجا کلیک کند
<div className="flex gap-2">
<Button variant="primary">ذخیره</Button>
<Button variant="primary">انتشار</Button>
<Button variant="primary">پیشنویس</Button>
</div>
// ✅ درست — سلسلهمراتب واضح
<div className="flex gap-2">
<Button variant="primary">انتشار</Button>
<Button variant="default">ذخیره</Button>
<Button variant="outline">پیشنویس</Button>
</div>چرا اشتباه است: primary باید یک عمل اصلی در هر view داشته باشد. وقتی همه چیز مهم است، هیچ چیز مهم نیست.
Dialog به جای Drawer در موبایل
مشکل: استفاده از Dialog در صفحههای موبایل که فضای کافی ندارند.
// ❌ غلط — Dialog در موبایل فضای کمی دارد
<Dialog>
<DialogContent>
<FilterForm />
</DialogContent>
</Dialog>
// ✅ درست — Drawer از پایین صفحه باز میشود
<Drawer>
<DrawerContent>
<FilterForm />
</DrawerContent>
</Drawer>راهحل بهتر: از responsive pattern استفاده کنید — Dialog در desktop، Drawer در موبایل.
ساختن کامپوننت Domain از صفر
مشکل: ساختن EngagementRate، SentimentBadge، یا SocialPlatformBadge از صفر.
// ❌ غلط — چرخ را دوباره اختراع نکنید
function MyEngagementRate({ rate }: { rate: number }) {
const color = rate > 5 ? 'green' : rate > 3 ? 'yellow' : 'red'
return <div style={{ color }}>{rate}%</div>
}
// ✅ درست — استانداردهای دامنه داخل کامپوننت کد شده
import { EngagementRate } from '@parto-system-design/ui'
;<EngagementRate currentRate={0.042} followers={15000} />کامپوننتهای domain-specific موجود:
EngagementRate— ۵ دسته اینفلوئنسر × ۶ سطح تعاملEngagementRateBar— نوار سادهترSentimentBadge/SentimentDistribution— سه نوع احساسSocialPlatformBadge— ۷ پلتفرم با رنگ برندProfileCard/ProfileInfo— پروفایل اینفلوئنسر
Compound Component ناقص
مشکل: استفاده از MetricCard، Card، یا Table بدون sub-component های لازم.
// ❌ غلط — MetricCard بدون MetricCardContent
<MetricCard>
<MetricCardHeader>
<MetricCardLabel>کاربران</MetricCardLabel>
</MetricCardHeader>
<p>۱,۲۳۴</p>
</MetricCard>
// ✅ درست
<MetricCard>
<MetricCardHeader>
<MetricCardLabel>کاربران</MetricCardLabel>
</MetricCardHeader>
<MetricCardContent>
<MetricCardValue>۱,۲۳۴</MetricCardValue>
<MetricCardDifferential variant="positive">+۵٪</MetricCardDifferential>
</MetricCardContent>
</MetricCard>Input بدون FormField در react-hook-form
مشکل: استفاده مستقیم از Input در form های react-hook-form بدون FormField.
// ❌ غلط — validation و error message کار نمیکند
<form onSubmit={handleSubmit(onSubmit)}>
<Input {...register('email')} />
</form>
// ✅ درست
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>ایمیل</FormLabel>
<FormControl><Input {...field} /></FormControl>
<FormMessage />
</FormItem>
)}
/>
</form>
</Form>Skeleton با ابعاد اشتباه
مشکل: Skeleton هایی که شکل محتوای واقعی را منعکس نمیکنند.
// ❌ غلط — Skeleton با ابعاد random
<Skeleton className="h-4 w-24" />
<Skeleton className="h-4 w-48" />
// ✅ درست — Skeleton شکل محتوای واقعی را تقلید میکند
<div className="bg-surface-100 p-4 rounded-lg border space-y-2">
<div className="flex items-center gap-3">
<Skeleton className="h-10 w-10 rounded-full" />
<div className="space-y-2">
<Skeleton className="h-4 w-32" />
<Skeleton className="h-3 w-20" />
</div>
</div>
<Skeleton className="h-4 w-full" />
<Skeleton className="h-4 w-3/4" />
</div>