Files
skills/docs/localization/i18n/i18n-shared/src/constants/rtl-locales.md
2026-05-29 08:20:56 +01:00

2.7 KiB

RTL_LOCALES and RTL_LOCALE_LIST — right-to-left locale set

Purpose

RTL_LOCALES and RTL_LOCALE_LIST are the canonical inventory of ISO 639-1 language codes whose primary script renders right-to-left. Together they let any consumer (the locale detector, a UI component deciding dir="rtl", a logger annotating a span) determine text direction with one O(1) lookup and zero parsing. Centralising the list here means every package in the i18n family agrees on the same seven RTL codes — no drift between formatters that might independently hard-code Arabic + Hebrew while ignoring Persian or Urdu.

Features

  • 7 ISO 639-1 codes: ar, he, fa, ur, ps, sd, yi
  • Two shapes — ReadonlySet<string> for membership checks, readonly tuple for iteration / serialisation
  • Both shapes share the same data and the test suite asserts they agree on cardinality
  • Tree-shake-friendly subpath at @suaveplan/i18n-shared/constants/rtl-locales for size-sensitive consumers

Usage: Basic Example

import { RTL_LOCALES } from "@suaveplan/i18n-shared";

if (RTL_LOCALES.has("ar")) {
    document.documentElement.dir = "rtl";
}

Usage: Advanced Example

import {
    RTL_LOCALE_LIST,
    RTL_LOCALES,
} from "@suaveplan/i18n-shared/constants/rtl-locales";

// Membership check — O(1) on the Set
function getDirection(locale: string): "ltr" | "rtl" {
    const language = locale.split("-")[0]?.toLowerCase() ?? "";
    return RTL_LOCALES.has(language) ? "rtl" : "ltr";
}

// Iteration — stable order from the tuple
for (const code of RTL_LOCALE_LIST) {
    console.log(`Loading RTL bundle for ${code}`);
}

// Serialisation — bundlers can inline the tuple as a JSON literal
const manifest = { rtl: [...RTL_LOCALE_LIST] };

API Reference

RTL_LOCALES: ReadonlySet<string>

Set of ISO 639-1 codes whose primary script is right-to-left. Use this for O(1) membership checks.

RTL_LOCALE_LIST: readonly ["ar", "he", "fa", "ur", "ps", "sd", "yi"]

Tuple form of the same data. Use this when iteration order matters, when bundling into a manifest, or when the consumer wants to ship the code list without the Set overhead.

Implementation Notes

  • The two exports are deliberately not derived from one another at module-init time — the Set takes the array path on construction and the tuple is a literal. A unit test asserts RTL_LOCALE_LIST.length === RTL_LOCALES.size so any future addition to one stays in sync with the other.
  • The seven codes match the pre-split monolith exactly. Future additions (e.g. dv for Dhivehi) require updating both exports AND adding a corresponding LOCALE_DESCRIPTORS entry with direction: "rtl".