اندازهٔ پیشفرض کنترلها (ControlSizeProvider)
یک اندازه برای همهٔ کنترلهای یک ردیف، بدون نوشتن size روی تکتک آنها
معرفی
ControlSizeProvider اندازهٔ پیشفرض کنترلهایی را که در جدول «کنترلهایی که از Provider پیروی
میکنند» آمدهاند، برای هر چیزی که داخلش قرار میگیرد تعیین میکند. کنترلی که size خودش را داشته باشد همان را نگه
میدارد؛ بقیه اندازهٔ Provider را میگیرند، و قاب بیرونی هر کدام دقیقاً به ارتفاع همان پله میشود. خودش هیچ
عنصری رندر نمیکند.
قاعدهٔ «همهٔ کنترلهای یک ردیف، یک اندازه» پیش از این فقط با نوشتن size روی تکتک کنترلها اجرا میشد، و
پیشفرض خود کنترلها با هم فرق داشت. این جزء آن قاعده را به کد میآورد. از نسخهٔ 4.0 پیشفرضها دو تا هستند:
دکمهها و کنترلهای دکمهمانند sm (30 پیکسل)، فیلدهای فرم md (38 پیکسل). هر ردیفی که هر دو را کنار هم دارد
(نوار ابزار، ردیف فیلتر) باید یک اندازه بگیرد؛ PageToolbar و FilterBar این کار را خودشان میکنند، و ردیفهای
اقدامِ خود سیستم طراحی هم: سرِ کارت نمودار (ChartCardHeader)، actions و primaryAction سربرگ صفحه
(PageHeader، PageHeaderAside)، actions در FormHeader و نوار بالای SiteHeader کنترلهای بی
size خود را sm میکنند، مگر یک Provider بیرونی اندازهٔ دیگری بدهد.
چه زمانی استفاده کنیم:
- برای یک ردیف کنترل از خودتان که نوارابزار صفحه نیست، مثل ردیف فیلتر داخل یک پنل کناری؛ یا برای ردیفی از
سیستم طراحی که باید فشردهتر از
smباشد (مثلاًxsدر سرِ کارت نمودار، مثل نمونهٔ زیر). - وقتی کنترل سفارشی خودتان باید از همان اندازهٔ ردیف پیروی کند: با
useControlSize()آن را بخوانید.
چه زمانی استفاده نکنیم:
- دور نوارابزار صفحه (نوارابزاری که
ListPageازsearchوfiltersمیسازد): اندازه و عرض کنترلهایش را خودش تعیین میکند. - دور کل صفحه یا کل برنامه: چگالی را سیستم طراحی تعیین میکند، نه هر محصول. Provider برای یک ردیف یا یک ظرف کوچک است.
- برای فرم صفحه: فیلدهای فرمی که در خود صفحه است اندازه و عرض پیشفرض خودشان را دارند. تنها استثنا فرم کوچک داخل یک لایهٔ رویی (مثلاً پاپاور) است که باید اندازهٔ دیگری بگیرد؛ بخش «هر لایهٔ رویی از نو شروع میکند» را ببینید.
استفاده
import {
Button,
ChartCardHeader,
ControlSizeProvider,
PeriodSelector,
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@partodata/ui'
import { Icons } from '@partodata/ui/icons'
export function TrendHeader({ period, onPeriodChange }: { period: string; onPeriodChange: (v: string) => void }) {
return (
<ChartCardHeader
title="روند منشنها"
actions={
<ControlSizeProvider size="xs" controlWidth="intrinsic">
<PeriodSelector value={period} onValueChange={onPeriodChange} />
<Select defaultValue="line">
<SelectTrigger aria-label="نوع نمودار">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="line">خطی</SelectItem>
<SelectItem value="bar">ستونی</SelectItem>
</SelectContent>
</Select>
<Button variant="ghost" icon={<Icons.download />} aria-label="خروجی نمودار" />
</ControlSizeProvider>
}
/>
)
}برای یک ردیف، controlWidth="intrinsic" را همیشه کنار size بنویسید؛ بدون آن SelectTrigger، Input و
جستوجو کل عرض ردیف را میگیرند.
Context این جزء بین همهٔ مسیرهای وارد کردن مشترک است: Provider از @partodata/ui/control-size به دکمهای که
از @partodata/ui یا @partodata/ui/button آمده هم میرسد.
حالتها و انواع
کنترلهایی که از Provider پیروی میکنند
| کنترل | بیرون از Provider | داخل Provider |
|---|---|---|
Button با متن | sm (30) | اندازهٔ Provider |
Button فقطآیکون (icon بدون children) | مربع sm (30) | مربعی به ارتفاع همان اندازه |
Input، SelectTrigger، SearchInput، MultiSelect، Autocomplete | md (38) | اندازهٔ Provider |
DatePicker، DateRangePicker | md (38) | اندازهٔ Provider |
NativeSelect | md (38) | اندازهٔ Provider |
PeriodSelector، ViewToggle، ToggleGroup تکانتخابی | sm (قاب 30) | اندازهٔ Provider؛ قاب همقد ردیف |
Toggle، ToggleGroup چندانتخابی | sm | اندازهٔ Provider |
DataTableFacetedFilter، FilterBarClear | sm | اندازهٔ Provider |
DataTableColumnVisibilityToggle، DataTableExportButton | sm (تا 3٫x xs) | اندازهٔ Provider |
ThemeToggle (@partodata/ui/theme-toggle) | مربع sm (30) | مربعی به ارتفاع همان اندازه |
UserMenu (trigger) | دایرهٔ sm (30؛ تا 3٫x 32) | دایرهای به ارتفاع همان اندازه |
TabsList (فقط sm/md/lg: 30 / 38 / 42) | sm (30) | xs ← sm، xl ← lg، بقیه همان |
کنترلهایی که روی Button یا Input ساخته شدهاند هم پیروی میکنند: Input با هر kind و آدورنمنت، و
دکمهٔ DateTimePicker.
عمداً پیروی نمیکنند: Checkbox، Switch، RadioGroup، FilterChip، CopyButton و InputGroupButton.
اینها روی مقیاس ارتفاع کنترلها نیستند و کنار یا داخل کنترل دیگری با اندازهٔ خودشان مینشینند.
قاب هر کنترل دقیقاً به ارتفاع پله
ارتفاع قاب بیرونی هر کنترل جدول همان عدد پله است: 26، 30، 38، 42 یا 50 پیکسل. این کنترلها برای رسیدن به آن کمی جمعوجورتر چیده میشوند:
- کنترلهای قطعهای (
PeriodSelector،ViewToggle،ToggleGroupتکانتخابی): گزینهها داخل یک ریل با حاشیهٔ یکپیکسلی و فاصلهٔ دوپیکسلی هستند، پس هر گزینه 6 پیکسل کوتاهتر از پله است تا کل ریل همقد ردیف شود. MultiSelect: فاصلهٔ عمودی داخلش کمتر میشود تا یک خط برچسبهای انتخابشده (یا متن راهنما) روی همان پله بنشیند. اگر برچسبها به خط دوم بروند، بلندتر میشود.
از نسخهٔ 4.0 این هندسه بیرون از Provider هم برقرار است (تا 3٫x بیرون از Provider کنترل قطعهای 6 پیکسل بلندتر از
دکمهٔ هماندازهاش بود). TabsList هم از 4.0 روی همین نردبان است (30، 38، 42؛ تا 3٫x 32، 36، 40)، پس کنار دکمهٔ
هماندازهاش همقد است؛ xs و xl ندارد و به نزدیکترین پله میرود.
لمس: حداقل 38 پیکسل
روی اشارهگر درشت (گوشی و تبلت) یا زیر data-touch روی <html> (مینیاپ پیامرسان) هر کنترل روی نردبان دستکم 38
پیکسل است و دکمهها، انتخابگرها و کلیدها ناحیهٔ لمس 44 پیکسلی هم دارند؛ کنترل قطعهای کلاً 38 پیکسل میشود. این یک
حداقل است، پس اندازهٔ sm نوار ابزار، Provider یا ردیف فرم آن را پایین نگه نمیدارد و کل ردیف با هم بالا میرود؛ روی
دسکتاپ همان 30 پیکسل میماند. تنها راه نگه داشتن اندازهٔ دسکتاپ روی دستگاه لمسی data-touch="off" روی آن بخش است.
جزئیات، و کنترلهایی که بیرون از این کفاند، در اندازه و تراکم.
اندازهٔ صریح برنده است
<ControlSizeProvider size="xs">
<Button variant="default">خروجی</Button>
<Button variant="default" size="md">
گزارش کامل
</Button>
</ControlSizeProvider>دکمهٔ اول 26 پیکسل (اندازهٔ Provider) و دکمهٔ دوم 38 پیکسل (md خودش) است.
هر لایهٔ رویی از نو شروع میکند
هر سطحی که روی صفحه باز میشود، یعنی Dialog، AlertDialog، Sheet، Drawer، Popover، DropdownMenu،
ContextMenu و HoverCard، کنترلهایش را با پیشفرض سیستم طراحی میچیند: اندازهٔ sm و عرض کامل.
این قاعده حتی وقتی برقرار است که دکمهٔ بازکننده داخل Provider یا PageToolbar باشد. یعنی فرم فیلتری که از
نوارابزار در یک پاپاور باز میشود، مثل هر فرم دیگری کل عرض پاپاور را میگیرد.
اگر کنترلهای یک پاپاور باید اندازهٔ دیگری داشته باشند، Provider را داخل PopoverContent بگذارید.
<PopoverContent>
<ControlSizeProvider size="xs">
<Input aria-label="از تاریخ" />
<Button variant="default">اعمال</Button>
</ControlSizeProvider>
</PopoverContent>عرض ذاتی: controlWidth="intrinsic"
Input، SelectTrigger، SearchInput، MultiSelect، Autocomplete و انتخابگرهای تاریخ بهطور پیشفرض
کل عرض ظرفشان را میگیرند، که در یک ردیف یعنی هر کدام یک خط کامل. با controlWidth="intrinsic" هر کدام
بهاندازهٔ محتوایش میشود، SearchInput عرض نامدار --layout-search-width (256 پیکسل) را میگیرد، و
انتخابگرهای تاریخ مثل autoWidth رفتار میکنند. کلاس عرض یا autoWidth صریح روی کنترل همچنان برنده است.
پیشفرض fill است، چون Provider دو کاربرد دارد و فقط یکی از آنها ردیف است: Provider ردیف (سرِ کارت، ردیف فیلتر
پنل) همیشه controlWidth="intrinsic" میگیرد، و Provider داخل یک لایهٔ رویی (فرم یک پاپاور) کنترلها را مثل هر
فرمی تمامعرض نگه میدارد. داخل PageToolbar لازم نیست چیزی بنویسید؛ خود نوارابزار intrinsic است.
<ControlSizeProvider size="xs" controlWidth="intrinsic">
<SearchInput placeholder="جستوجو" />
<Select>
<SelectTrigger aria-label="مرتبسازی">
<SelectValue placeholder="جدیدترین" />
</SelectTrigger>
</Select>
</ControlSizeProvider>Providerهای تودرتو
نزدیکترین Provider برنده است. Provider درونیای که controlWidth ندارد، عرض را از Provider بیرونی میگیرد.
راهنمای استفاده
بکنید
- برای یک ردیف کنترل، یک Provider با
sizeوcontrolWidth="intrinsic"بگذارید وsizeو کلاس عرض را از تکتک کنترلها بردارید. - دکمهٔ فقطآیکون را با
icon(یاiconEnd) وaria-labelبسازید تا داخل ردیف مربعی و همقد بقیه شود. برچسبی که گاهی نمایش داده نمیشود ({!isMobile && 'خروجی'}) هم وقتیfalseاست دکمه را مربعی میکند. - در کنترل سفارشی، اندازه را با
useControlSize()بخوانید و اگرundefinedبود پیشفرض خودتان را بگذارید.
نکنید
- Provider را دور کل صفحه یا layout برنامه نگذارید.
- داخل یک ردیف به بعضی کنترلها
sizeمتفاوت ندهید؛ همین تفاوت است که ردیف را ناهمقد میکند. - دور
PageToolbarProvider دیگری نگذارید؛ نوارابزار اندازهٔ خودش را دارد.
Props
ControlSizeProvider
useControlSize
useControlSize(): 'xs' | 'sm' | 'md' | 'lg' | 'xl' | undefined — اندازهٔ نزدیکترین Provider، یا undefined
بیرون از هر Provider.
دسترسیپذیری
- Provider هیچ عنصر و نقشی به صفحه اضافه نمیکند؛ فقط اندازه عوض میشود.
- دکمهٔ فقطآیکون مربعی همچنان به
aria-labelنیاز دارد. - اندازهٔ
xs(26 پیکسل) برای ردیفهای متراکم است؛ برای کنترلهایی که هدف لمسی اصلیاند اندازهٔ بزرگتر انتخاب کنید.
کامپوننتهای مرتبط
PageToolbar— ردیف فیلتر و اقدامی کهListPageمیسازد (مستقیم فقط درونCustomPage)؛ همین Provider را باcontrolWidth="intrinsic"برای کنترلهایش میگذارد، پس برای نوارابزار صفحه به Provider جداگانه نیاز ندارید.FilterBar— ردیف فیلتر؛FilterBarClearداخل Provider همقد بقیهٔ ردیف میشود.- اندازه و چگالی — مقیاس پنجپلهای که این جزء از آن انتخاب میکند.
Button— اگر فقط یک دکمه اندازهٔ دیگری لازم دارد،sizeخودش را بدهید، نه Provider.