كيفية دعم اللغات من اليمين إلى اليسار (RTL) في TanStack Start v1

تصميمات معكوسة للغة العربية والعبرية

المشكلة

تفترض معظم تخطيطات الويب أن النص يتدفق من اليسار إلى اليمين. تثبت قوائم التنقل على اليسار، وتظهر الأشرطة الجانبية على اليسار، ويُقرأ المحتوى من اليسار إلى اليمين. بالنسبة للغات مثل العربية والعبرية التي تُقرأ من اليمين إلى اليسار، يخلق هذا تجربة مربكة حيث يتعارض التدفق المرئي مع اتجاه القراءة. يرى المستخدمون أدوات التنقل على الجانب الخطأ، والأيقونات موضوعة بشكل غير مناسب، وتخطيطات تبدو معكوسة. بدون دعم مناسب للغات من اليمين إلى اليسار (RTL)، تصبح الواجهة صعبة التنقل والفهم لمتحدثي اللغات التي تُكتب من اليمين إلى اليسار.

الحل

تعيين اتجاه نص المستند بشكل ديناميكي بناءً على اللغة الحالية، مما يسمح للمتصفح بعكس التخطيط تلقائيًا للغات التي تُكتب من اليمين إلى اليسار. استخدم خصائص CSS المنطقية بدلاً من الخصائص الاتجاهية الفيزيائية بحيث تتكيف المسافات والموضع والمحاذاة مع اتجاه النص دون كود إضافي. يتيح هذا النهج للتخطيطات أن تظل محايدة الاتجاه: ما يظهر في "بداية" المحتوى باللغة الإنجليزية سيظهر بشكل صحيح في "البداية" (الجانب الأيمن) باللغة العربية، مع قيام المتصفح بمعالجة التحويل.

الخطوات

1. تحديد اتجاه النص من اللغة المحلية

إنشاء دالة مساعدة تُرجع اتجاه النص للغة محلية معينة باستخدام واجهة برمجة التطبيقات للتدويل المدمجة في المتصفح.

export function getTextDirection(locale: string): "ltr" | "rtl" {
  try {
    const localeObj = new Intl.Locale(locale);
    if (
      "getTextInfo" in localeObj &&
      typeof localeObj.getTextInfo === "function"
    ) {
      return localeObj.getTextInfo().direction;
    }
  } catch (e) {
    console.warn(`Could not determine direction for locale: ${locale}`);
  }

  const rtlLocales = ["ar", "he", "fa", "ur"];
  const lang = locale.split("-")[0];
  return rtlLocales.includes(lang) ? "rtl" : "ltr";
}

تستخدم هذه الدالة Intl.Locale.getTextInfo() عندما تكون متاحة وترجع إلى قائمة اللغات المعروفة التي تُكتب من اليمين إلى اليسار. تُرجع إما 'ltr' أو 'rtl' بناءً على اللغة المحلية.

2. تعيين السمة dir على عنصر html

في المسار الجذر الخاص بك، قم باسترجاع اللغة الحالية وتطبيق الاتجاه المقابل على عنصر <html> في المستند.

import {
  createRootRoute,
  Outlet,
  Scripts,
  HeadContent,
} from "@tanstack/react-router";
import { useIntl } from "react-intl";
import { getTextDirection } from "~/utils/text-direction";

export const Route = createRootRoute({
  component: RootComponent,
});

function RootComponent() {
  return (
    <RootDocument>
      <Outlet />
    </RootDocument>
  );
}

function RootDocument({ children }: { children: React.ReactNode }) {
  const intl = useIntl();
  const dir = getTextDirection(intl.locale);

  return (
    <html lang={intl.locale} dir={dir}>
      <head>
        <HeadContent />
      </head>
      <body>
        {children}
        <Scripts />
      </body>
    </html>
  );
}

تخبر السمة dir على عنصر <html> المتصفح بعكس التخطيط للغات RTL. يتم عكس Flexbox وGrid والمحتوى المضمن تلقائيًا.

3. استبدال خصائص CSS الفيزيائية بخصائص منطقية

قم بتحديث أوراق الأنماط الخاصة بك لاستخدام الخصائص المنطقية التي تستجيب لاتجاه النص بدلاً من الاتجاهات الفيزيائية الثابتة.

.sidebar {
  padding-inline-start: 1rem;
  margin-inline-end: 2rem;
  border-inline-start: 1px solid #ccc;
}

.icon {
  margin-inline-end: 0.5rem;
}

.card {
  inset-inline-start: 0;
  text-align: start;
}

الخصائص المنطقية مثل padding-inline-start تتحول إلى padding-left في LTR وpadding-right في RTL. يطبق المتصفح الخاصية الفيزيائية الصحيحة بناءً على السمة dir، لذلك تعمل الأنماط الخاصة بك في كلا الاتجاهين دون تكرار.

4. استخدام قيم محاذاة محايدة الاتجاه

استبدل كلمات المحاذاة الفيزيائية بكلمات منطقية في CSS وأنماط مضمنة.

export function Header() {
  return (
    <header
      style={{
        display: "flex",
        justifyContent: "space-between",
        alignItems: "center",
      }}
    >
      <nav style={{ display: "flex", gap: "1rem" }}>
        <a href="/">Home</a>
        <a href="/about">About</a>
      </nav>
      <div style={{ textAlign: "end" }}>
        <button>Menu</button>
      </div>
    </header>
  );
}

استخدام textAlign: 'end' بدلاً من 'right' يضمن محاذاة النص إلى نهاية اتجاه القراءة. خصائص Flexbox مثل justifyContent وalignItems تحترم تلقائيًا الاتجاه المحدد بواسطة السمة dir.