فارسیمحور بودن
اصل اول پرتو — طراحی از ابتدا برای زبان فارسی، نه ترجمه از انگلیسی
چرا فارسی اول؟
اکثر کتابخانههای UI برای LTR (انگلیسی) ساخته شدهاند و RTL به عنوان «حالت جایگزین» اضافه میشود. این رویکرد مشکلات زیادی ایجاد میکند: فاصلهگذاری معکوس، آیکونهای برعکس، انیمیشنهای ناهماهنگ.
پرتو از صفر برای فارسی طراحی شده است. RTL تنها حالت اصلی است، نه یک افزونه.
یکی از اصول بنیادین پرتو این است: فارسی اول، RTL بومی. این صفحه آنچه را که این اصل در عمل معنا میدهد توضیح میدهد.
پیکربندی پایه
تگ HTML
<html lang="fa" dir="rtl"></html>این دو attribute باید همیشه روی تگ <html> باشند:
lang="fa"— برای screen readerها و موتورهای جستجوdir="rtl"— برای کارکرد صحیح CSS Logical Properties
CSS Logical Properties
پرتو از CSS Logical Properties به جای مقادیر فیزیکی استفاده میکند. این یعنی چیدمانها به صورت خودکار با جهت متن تطبیق مییابند.
جدول معادلها
| فیزیکی — استفاده نکنید | Logical — استفاده کنید | معنا |
|---|---|---|
ml-* | ms-* | margin-inline-start |
mr-* | me-* | margin-inline-end |
pl-* | ps-* | padding-inline-start |
pr-* | pe-* | padding-inline-end |
left-* | start-* | موقعیت از ابتدای خط |
right-* | end-* | موقعیت از انتهای خط |
border-l-* | border-s-* | حاشیه ابتدای خط |
border-r-* | border-e-* | حاشیه انتهای خط |
rounded-l-* | rounded-s-* | گوشه ابتدای خط |
rounded-r-* | rounded-e-* | گوشه انتهای خط |
text-left | text-start | تراز متن |
text-right | text-end | تراز متن |
مثال
// درست — با dir="rtl" به سمت راست قرار میگیرد
<div className="ms-4 ps-6 border-s-2 text-start">
محتوا
</div>
// غلط — در RTL و LTR یکسان عمل میکند، تغییر جهت نمیدهد
<div className="ml-4 pl-6 border-l-2 text-left">
محتوا
</div>استثنا: مرکزگرایی مطلق
left-1/2 -translate-x-1/2 برای مرکز قرار دادن المانهای absolute جهتدار نیستند و این یک استثنا مجاز است:
// این استفاده صحیح است
<div className="absolute left-1/2 -translate-x-1/2">محتوای مرکزی</div>اعداد فارسی
ارقام فارسی از فونت میآیند، نه از جاوااسکریپت. این تنها یک ترجیح سبکی نیست؛ نتیجهٔ یک واقعیت قابلاندازهگیری است.
چرا — اثبات، نه ادعا
قابلیت ss01 در YekanBakh-VF یک lookup جانشینی است که هر ده گلیف رقم لاتین را به گلیف رقم فارسی نگاشت میکند (این با پارس مستقیم جدول GSUB فونت تأیید شده)، و globals.css آن را سراسری روشن میکند:
/* پیشفرضِ خودِ دیزاینسیستم — لازم نیست کاری کنید */
font-feature-settings: 'rlig' 1, 'calt' 1, 'ss01' 1;نتیجه: مینویسید 1234، کاربر میبیند «۱۲۳۴»، و codepointها لاتین میمانند. این چهار چیز را سالم نگه میدارد که تبدیل با جاوااسکریپت هر چهار را میشکند:
| چه چیزی سالم میماند | چرا با تبدیل JS میشکند |
|---|---|
| Copy/Paste | رقم U+06F۱ در Excel یا ماشینحساب عدد نیست |
| Screen reader | رفتار قارئها روی U+06Fx یکدست نیست |
| مرتبسازی و مقایسه | رشتهٔ «۱۰» و «۹» درست مرتب نمیشوند |
Ctrl+F | کاربری که «1234» تایپ کند، پیدا نمیکند |
این را در کد محصول خودتان تکرار نکنید
چند صفحهٔ الگو قبلاً toLocaleString('fa-IR') را توصیه میکردند که با همین اصل در تناقض
بود. تناقض به نفع همین صفحه حل شد: در کد محصولی که روی پرتو سوار است، تبدیل دستی هیچ
سودی ندارد و آن چهار مورد بالا را از بین میبرد.
چه چیزی مجاز است
جداکننده و مختصرسازی کار جاوااسکریپت است — چون آنها شکل عدد نیستند، قالب آناند:
import { , } from '@partodata/ui/server'
// جداکنندهٔ هزارها. خروجی رقم لاتین است و فونت آن را فارسی نشان میدهد.
// دقت: ss01 فقط ارقام را جانشین میکند. کاما، نقطه و ٪ دستنخورده میمانند —
// پوشش آن lookup با پارس مستقیم GSUB سنجیده شد و فقط ده گلیف رقم است.
(1234567) // → «1,234,567»، که «۱,۲۳۴,۵۶۷» دیده میشود
(1234567, 'short') // → «1.2M» — فقط بسترِ لاتین؛ هشدار زیر را ببینید
// مقدار مختصر با پسوند فارسی. پسوند لاتین را هرگز روی رقم فارسی نگذارید.
(1234567, 'fa') // → «۱.۲ میلیون»
(1234567, 'en') // → «1.2M»`formatNumber(n, 'short')` را در رابط فارسی به کار نبرید
خروجیاش 1.2M است و چون ss01 سراسری است، کاربر «۱.۲M» میبیند — رقم فارسی با
پسوند لاتین، همان چیزی که چند خط بالاتر منع شد. برای مقدار مختصر در رابط فارسی
formatLargeNumber(n, 'fa') را به کار ببرید؛ 'short' برای locale="en" است.
`convertToLocalNumbers` کجا جا دارد
این تابع export شده و برای مسیرهای غیرنمایشی لازم است — جایی که فونت در دسترس نیست:
خروجی PDF، رندر روی canvas، یا عنصری که font-family را عوض میکند. برای متن معمولیِ
رابط لازم نیست. خودِ کامپوننتهای دیزاینسیستم آن را صدا میزنند چون یک کتابخانه نمیتواند
فرض کند مصرفکننده فونت یکان بخ را نگه داشته است.
خلاف جهت: وقتی رقم لاتین میخواهید
چون ss01 سراسری است، ارقام لاتین را همهجا فارسی میکند. اگر جایی واقعاً رقم لاتین
لازم دارید (تقویم میلادی، شناسه، کد رهگیری) باید صریحاً خلافش را بگویید — همان کاری که
globals.css برای تقویم LTR میکند: font-variant-numeric: lining-nums بههمراه عوضکردن
font-family.
آیکونهای جهتدار
برخی آیکونها مانند فلشها در RTL باید چرخانده شوند:
import { Icons } from '@partodata/ui'
// آیکون فلش که در RTL چرخش میخورد
<Icons.arrowRight className="rtl:rotate-180" />
<Icons.chevronRight className="rtl:rotate-180" />کلاسهای Tailwind برای RTL
// فقط در RTL نمایش داده میشود
<div className="hidden rtl:block">محتوای RTL</div>
// فقط در LTR نمایش داده میشود
<div className="hidden ltr:block">LTR Content</div>چکلیست RTL
قبل از commit کردن هر کامپوننت جدید:
- هیچ property فیزیکی (
ml,mr,pl,pr,left,right,border-l,border-r) در کد وجود ندارد - متنها
text-startدارند (نهtext-right) - آیکونهای جهتدار کلاس
rtl:rotate-180دارند - dropdownها و popoverها از طرف درست باز میشوند
- انیمیشنهای کشویی جهت RTL را رعایت میکنند
تایپوگرافی فارسی
فضاگذاری (letter-spacing)
در متن فارسی، letter-spacing مثبت اغلب خوانایی را کاهش میدهد:
// مناسب برای فارسی
<h1 className="tracking-normal">عنوان</h1>
// نامناسب — فاصله بیش از حد بین حروف فارسی
<h1 className="tracking-widest">عنوان</h1>شکستن خط
برای متنهای طولانی فارسی، overflow-wrap را تنظیم کنید:
word-break: normal;
overflow-wrap: break-word;خلاصه
| قانون | توضیح |
|---|---|
lang="fa" dir="rtl" روی <html> | پایه هر صفحه |
| CSS Logical Properties | ms/me نه ml/mr، ps/pe نه pl/pr |
| OpenType برای اعداد | font-feature-settings: "ss01" 1 — پیشفرض سیستم |
rtl:rotate-180 | آیکونهای جهتدار مثل فلشها |
| فونت یکان بخ | پیشفرض سیستم — تغییر ندهید |
صفحات مرتبط
- دسترسیپذیری —
lang="fa"برای screen reader، کنتراست - تایپوگرافی — فونت یکان بخ و ویژگیهای OpenType
- فضابندی — CSS Logical Properties در padding و margin