اندازه و چگالی
یک نردبان برای همهٔ کنترلها، دو پیشفرض، جدول 40/44، کف لمسی — و دلیل هر عدد
اصل
چگالی را سیستم طراحی تعیین میکند، نه هر صفحه. همهٔ عددهای این صفحه تصمیماند، نه بازه: صفحهای که فقط با پیشفرضها ساخته شود متوازن است و هیچ صفحهای نباید عدد تازه بنویسد.
جهت: ساختار سوپابیس، یک پله راحتتر برای فارسی. دلیلش اندازهگیری فونت است، نه سلیقه:
- جعبهٔ محتوای یکانبخ 1.55em است (ascent 1000 و descent 550 از 1000)، در برابر 1.21em در Inter فونت سوپابیس. پس با همان عددهای سوپابیس، متن فارسی در جعبهای حدود 30٪ تنگتر مینشیند.
- متن 12 پیکسلی فارسی مثل 11 پیکسل Inter خوانده میشود و متن 14 پیکسلی یکانبخ هماندازهٔ دیداری 13 پیکسل Inter است.
برای همین هر عدد سوپابیس یک پله بالا رفته است: دکمهٔ 26 با متن 12 ← 30 با 13؛ فیلد 34 با متن 13 ← 38 با 14؛ جدول 40 / حدود 52 با متن 13 ← 40 / 44 با 14. نوارهای ثابت (48) و ریتم صفحه (48 / 24 / 16 / 8) همان سوپابیس است؛ آرامش سوپابیس از همینجاست (هندسهٔ صفحه).
نمونه بصری
| اندازه | دکمه | ورودی |
|---|---|---|
| xs | … | … |
| sm | … پیشفرض | … |
| md | … | … پیشفرض |
| lg | … | … |
| xl | … | … |
قدها از lib/constants.ts میآیند و عددِ کنار هر کنترل، ارتفاعِ اندازهگیریشده از خودِ DOM است — نه عددی که جدولی ادعا کند.
قوانین اجباری
یک نردبان برای همهٔ کنترلها
| پله | ارتفاع | متن | کاربرد |
|---|---|---|---|
xs | 26 پیکسل | 12 | ردیفهای خیلی فشرده داخل کارت یا پنل |
sm | 30 پیکسل | 13 | همهٔ اقدامها؛ نوار ابزار و ردیف فیلتر |
md | 38 پیکسل | 14 | فیلدهای فرم |
lg | 42 پیکسل | 14 | صفحههای کمتراکم (ورود) |
xl | 50 پیکسل | 16 | صفحههای معرفی |
قاب بیرونی هر کنترل دقیقاً همین عدد است، دکمه، فیلد، انتخابگر و کنترل قطعهای (PeriodSelector) یکسان. متن هر پله
وسط کنترل است: فاصلهٔ بالا و پایین متن برابر است، و با جعبهٔ خطِ وسطچین جوهر حروف فارسی یکانبخ در مرکز کنترل مینشیند
(در Chrome با فونت یکانبخ روی گلیفهای رندرشده اندازهگیری شده است؛ حداکثر 0.75 پیکسل فاصله از مرکز). فقط حروف بزرگ
لاتین و ارقام یک تا دو پیکسل بالاتر مینشینند؛ خط اصلی فارسی است. همهٔ کنترلهای یک ردیف، دکمه و فیلد و کنترل قطعهای،
برچسبشان را روی یک خط کرسی میگذارند.
دو پیشفرض: دکمه sm، فیلد md
- دکمه (و کنترلهای دکمهمانند:
Toggle،ToggleGroup،PeriodSelector،ViewToggle، دکمههای نوار ابزار جدول) بدونsize، 30 پیکسل است. دکمهٔ بدونvariantهم خنثی (default) است؛ دکمهٔ اصلی همیشه صریح است و در هر نما فقط یکی (دکمه). - فیلد فرم (
Input،Textarea،SelectTrigger،NativeSelect،SearchInput،MultiSelect،Autocomplete،TagInput،InputOTPو انتخابگرهای تاریخ) بدونsize، 38 پیکسل است: فرم فضای خواندن و نوشتن دارد.
هر ردیف، یک ارتفاع
ردیفی که فیلد و دکمه را کنار هم دارد باید یک اندازه بگیرد، و آن اندازه را یک جا تعیین کنید:
- نوار ابزار صفحهٔ فهرست (آنچه
ListPageازsearchوfiltersمیسازد؛ درون یکCustomPageخودِPageToolbar) همهٔ کنترلهایش راsmمیکند، فیلدها را هم؛ FilterBarهم بستر فیلتر است: کنترلهای داخلشsmمیشوند، مگر Provider بیرونی اندازهٔ دیگری بدهد؛- ردیفهای اقدامِ خود سیستم طراحی هم خودشان
smمیکنند: سرِ کارت نمودار (ChartCardHeader)،actionsوprimaryActionسربرگ صفحه (PageHeader،PageHeaderAside)،actionsدرFormHeaderو نوار بالایSiteHeader؛ - هر ردیف دیگر (ردیف فیلتر یک پنل، ردیف ابزار خودتان) داخل
ControlSizeProviderباcontrolWidth="intrinsic".
// ✅ یک اندازه برای کل ردیف، در یک جا
<ControlSizeProvider size="sm" controlWidth="intrinsic">
<Input aria-label="نام" />
<PeriodSelector value={period} onValueChange={setPeriod} />
<Button>اعمال</Button>
</ControlSizeProvider>
// ❌ فیلد 38 کنار دکمهٔ 30: ردیف دو ارتفاع دارد
<div className="flex items-center gap-2">
<Input aria-label="نام" />
<Button>اعمال</Button>
</div>دکمهٔ فقطآیکون، مربعی روی همان نردبان
دکمهٔ آیکوندار بدون متن (icon و aria-label) مربعی به ارتفاع پلهٔ خودش است: 26، 30، 38 و … پس کنار دکمهٔ متنی همقد
است. اندازههای قدیمی icon (36)، icon-sm (28)، icon-xs (24) و icon-lg (40) هیچوقت با دکمهٔ متنی همقد
نمیشدند؛ در 5.0 حذف شدند (npx --no parto-migrate-v5 هر کدام را به پلهای میبرد که در 4.x میداد: icon ← بدون
size یعنی sm، icon-sm و icon-xs ← xs، icon-lg ← md). زنگولههای نوار بالا
(NotificationCenter، WhatsNewBell)، ThemeToggle و UserMenu هم روی همین نردباناند: یک نوار بالا، یک ارتفاع.
جدول: 40 / 44 / 14، و compact
| تراکم | سرِ جدول | ردیف (حداقل) | متن | سرِ ستون |
|---|---|---|---|---|
default | 40 | 44 | 14 | 13 / 500 |
compact | 36 | 36 | 13 | 12 / 500 |
ارتفاع ردیف حداقل است: سلولی که به خط بعد میرود ردیف را بلند میکند و بریده نمیشود. compact فقط برای
جدولهای پرتراکم منشن (جدول). یک ردیف، یک ارتفاع: ردیف default کنترلهای sm و آواتار
تا 32 پیکسل را جا میدهد و ردیف compact کنترلهای xs و نشانهای 24 پیکسلی را (فاصلهٔ بالا و پایین سلول 4 پیکسل
است). تراکم مال خود جدول است؛ صفحه یا کارتِ بالادست آن را عوض نمیکند.
| حساب | منشن |
|---|---|
| فروشگاه آفتاب | 1,240 |
| کافه نارنج | 860 |
| نشر پرتو | 415 |
| حساب | منشن |
|---|---|
| فروشگاه آفتاب | 1,240 |
| کافه نارنج | 860 |
| نشر پرتو | 415 |
لمس: حداقل 38 با ناحیهٔ 44
روی اشارهگر درشت (هر گوشی و تبلت، حتی تبلتی که عرض دسکتاپ دارد) یا زیر data-touch هر کنترل روی نردبان دستکم
38 پیکسل است و دکمهها، انتخابگرها و کلیدها ناحیهٔ لمس 44 پیکسلی هم دارند؛ فیلدهای متنی فقط ارتفاع را
میگیرند. کنترل قطعهای کلاً 38 پیکسل میشود (گزینههایش 32). این یک حداقل است، پس sm نوار ابزار یا ردیف فرم
آن را پایین نگه نمیدارد و کل ردیف با هم بالا میرود. روی دسکتاپ همان 30 پیکسل میماند. برای لمس، اندازه را روی
تکتک کنترلها ننویسید.
data-touchرا روی<html>بگذارید (مینیاپ پیامرسان). روی عنصر دربرگیرندهٔ یک بخش فقط همان بخش را میگیرد: Dialog، Sheet، Select و منوها در<body>باز میشوند و بیرون آن میمانند.data-touch="false"(همان چیزی که React برایdata-touch={false}مینویسد) ناحیهٔ لمسی نیست.- خاموش کردن:
data-touch="off"روی یک بخش (یا روی<html>) کف لمسی را در همان بخش خاموش میکند، روی اشارهگر درشت هم. فقط برای صفحهٔ پرتراکمی که واقعاً دسکتاپی است؛ هیچsizeو هیچ کلاس ارتفاعی کنترل را زیر کف نگه نمیدارد. - بیرون از کف (با اندازهٔ خودشان):
Checkbox،RadioGroupItem،Switch، دکمههای منوی نوار کناری،ItemوCardروی پیوند،TabsTrigger، گزینههای منو وInputOTP. دکمهٔ داخل یک کنترل دیگر (دکمهٔ نمایشInput kind="password"، دکمهٔ حذف تراشهٔMultiSelectوTagInput، دکمهٔ آدورنمنتInput) نه ارتفاع 38 را میگیرد نه ناحیهٔ 44 را؛ تابع ظرف خود است و ظرف بالا میرود. - ردیف جدول با کنترل درونش بلند میشود: ردیف
compactبا دکمهٔxsاز 36 به 46 و ردیفdefaultبا دکمهٔsmاز 44 به 46 میرسد (کنترل 38 بهاضافهٔ 4 پیکسل بالا و پایین سلول). - دکمههای چسبیده (
ButtonGroup، و شمارههای صفحهبندی با فاصلهٔ 4 پیکسل) لبهٔ ناحیهٔ لمس را با هم شریکاند و کنترل بعدی همپوشانی را میگیرد. - کنترلی که
::beforeخودش را دارد (کلاسbefore:یاhit-area-*) آن را نگه میدارد و فقط ارتفاع 38 را میگیرد. - هر کنترل نردبان نشانگر
data-ladderرا دارد (buttonیاfield) و کف لمسی همین نشانگر را میخواند، نهdata-slotرا که یک Trigger باasChildعوض میکند (فقط دکمههای پایAlertDialogباdata-slotخودشان شناخته میشوند). آن را روی عنصرهای خودتان نگذارید؛ کنترل خودتان را ازButtonوInputبسازید.
یک کارت، یک قرص، یک نوار
خانوادههایی که شبیه هم دیده میشدند ولی جدا کشیده میشدند، حالا از یک مقیاس میخوانند:
| خانواده | قاعده |
|---|---|
هر جزء کارتمانند (Card، ChartCard، MetricCard، کارتهای دامنه) | یک قاب: rounded-lg، حاشیهٔ دیدنی، زمینهٔ surface-100 و سایهٔ کوچک؛ یک نقش عنوان (text-subheading، 14 / 600)؛ یک نقش عدد اصلی (.text-stat، 24 / 400) در همهٔ اندازهها |
نشانها و چیپها (Badge، SeverityBadge، SentimentBadge، EmotionBadge، FlowBadge، ActionTypeChip، LabelChip) | یک قرص برای هر اندازه: xs 20، sm 24، md 28، lg 32، xl 36 پیکسل ارتفاع، با فاصلهٔ داخلی 6 تا 14 پیکسل |
نوارهای پیشرفت و سنجه (Progress، QuotaProgressBar، BotDetectionMeter، نوار EngagementRate) | یک ارتفاع برای هر اندازه: xs 4، sm 6، md 8، lg 12 پیکسل |
موارد استفاده رایج
- صفحهٔ فهرست:
ListPage(نوار ابزارش همهsm)، جدولdefault، اقدام اصلیprimaryActionقالب. - فرم و تنظیمات: فیلدها
md(پیشفرض)، دکمههای پای فرمsm(پیشفرض)،variant="primary"روی تأیید (درFormPageوSettingsSectionقالب دکمهٔ ذخیره را خودش میگذارد). - داشبورد: سرِ کارت نمودار (
ChartCardHeader) خودشsmاست، بیsizeروی کنترلها؛ عدد شاخص با نقش.text-stat(تایپوگرافی). - جدول پرتراکم منشن:
size="compact". - جدول پژوهشی 10 تا 12 ستونی: تراکم سومی (حدود 32 / 32 / 12) هنوز در سیستم طراحی نیست. تا تصمیم آن
compactرا به کار ببرید و نیاز را به مسئول سیستم طراحی بگویید.
اندازهٔ آیکون
آیکونِ داخل دکمه با پلهٔ دکمه بزرگ میشود: 14 · 16 · 18 · 20 · 24 پیکسل برای xs تا xl. توکنهای آیکون برای جاهای
دیگر:
| توکن | مقدار |
|---|---|
--icon-xs | 12px |
--icon-sm | 16px |
--icon-md | 18px |
--icon-lg | 24px |
--icon-xl | 32px |
چه نکنیم
- ارتفاع دستی.
h-[34px]یاh-9روی یک کنترل یعنی آن کنترل دیگر با هیچ کنترلی همقد نیست؛ 34 دیگر پله نیست. sizeروی تکتک کنترلهای یک ردیف. ردیف را یک جا اندازه بدهید (PageToolbar،FilterBar،ControlSizeProvider).- دکمهٔ آیکونی با آیکون در children. آیکون را با
iconبدهید تا مربع روی نردبان شود. - جدول
sm/md/lg. منسوخاند؛defaultیاcompact. - ارتفاع ثابت برای ردیف جدول. ردیف باید بتواند با متن بلند رشد کند.
صفحات مرتبط
- تایپوگرافی — نقشهای متنی و وزن یگانهٔ عنوانها
- هندسهٔ صفحه — نوارها، حاشیه، ریتم و عرضها
- اندازهٔ پیشفرض کنترلها —
ControlSizeProvider: یک اندازه برای یک ردیف - دکمه — پیشفرض خنثی و دکمهٔ اصلی صریح
- جدول — دو تراکم