انتقل إلى المحتوى
TopClass UI

من اليمين إلى اليسار

العربية تعمل دون تغيير في الشيفرة: التخطيط والأيقونات والأرقام تتبع الصفحة.

القاعدة

يُضبط الاتجاه مرة واحدة، على العنصر html. وتقرؤه المكوّنات عبر CSS المنطقي، لا عبر JavaScript أبدًا.

app/layout.tsx
import { TopClassProvider } from 'topclassui/provider'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="ar" dir="rtl">
      <body>
        {/* the provider forwards direction to Base UI and to gestures */}
        <TopClassProvider direction="rtl" locale="ar">{children}</TopClassProvider>
      </body>
    </html>
  )
}
dir="ltr"
dir="rtl"

الأصناف المنطقية فقط

ما زال Tailwind يوفّر الأصناف الفيزيائية. هذه المكتبة لا تستخدمها أبدًا، فالصيغة المنطقية تؤدي العمل بدلًا منها.

ممنوع, استخدم بدلًا منه
ممنوعاستخدم بدلًا منه
ml-* mr-*ms-* me-*
pl-* pr-*ps-* pe-*
left-* right-*inset-s-* inset-e-*
start-* end-*inset-s-* inset-e-*
text-left text-righttext-start text-end
border-l border-rborder-s border-e
rounded-l-* rounded-r-*rounded-s-* rounded-e-*
space-x-* divide-x-*gap-*، وborder-s على العنصر
tracking-*لا شيء، فالخط العربي لا يستخدم تباعد الأحرف

التحويلات والإيماءات

الإزاحة ونقطة أصل التحويل والتدرّج اللوني والسحب لا صيغة منطقية لها في CSS. لذا تُضرب في --tc-dir، وقيمته 1 من اليسار إلى اليمين و-1 من اليمين إلى اليسار.

styles.css
[dir="rtl"] { --tc-dir: -1; }

/* the switch thumb */
--tc-slide: calc(1rem * var(--tc-dir));
className="translate-x-(--tc-slide)"

/* object and background positions have no logical form */
className="object-left rtl:object-right"

الموضع لا الجهة

كل طبقة عائمة تأخذ placement بدلًا من side. تُحَلّ start وend إلى بداية السطر ونهايته، لذا تُفتح القائمة في مكانها الصحيح في الاتجاهين.

خطأ
<PopoverPopup side="left" align="start" />
صواب
import { PopoverPopup } from 'topclassui/popover'

<PopoverPopup placement="start-top" />

// start   -> inline-start, mirrors
// bottom  -> bottom, does not

الخط والجمع والأرقام

يأخذ النص العربي --tc-font-arabic عبر قاعدة [lang|='ar']، فلا تبدّل متغيّر خط أبدًا. والتسمية التي تحوي عددًا دالةٌ في ذلك العدد.

labels/ar.ts
// labels/ar.ts
const plural = new Intl.PluralRules('ar')

selected: (n, fmt) => {
  const rule = plural.select(n)
  const value = fmt.format(n)
  if (rule === 'zero') return 'لم يتم تحديد شيء'
  if (rule === 'one') return 'عنصر واحد محدد'
  if (rule === 'two') return 'عنصران محددان'
  if (rule === 'few') return `${value} عناصر محددة`
  if (rule === 'many') return `${value} عنصرًا محددًا`
  return `${value} عنصر محدد`
}

<TopClassProvider direction="rtl" locale="ar" numberingSystem="arab">

ما تلتقطه قاعدة التدقيق

تعمل القاعدة على كل سلسلة أصناف في المكتبة، وتُفشل التدقيق عند أي صنف فيزيائي. وتلتقط الأسماء البديلة المهجورة أيضًا.

lint-probe.tsx
// wrong: one error per class string
className="pl-4 text-left"
// R-5.3-1: "pl-" is physical. use ps- or pe-.
// fix it, and the next run names text-left

// right
className="ps-4 text-start"
التاليالخادم أولًا