RTL Support
How Cynosure handles right-to-left layouts using logical CSS properties and DirectionProvider.
RTL support
Section titled “RTL support”Cynosure is RTL-safe by construction. The rules:
- Every internal
.css.tsuses logical CSS properties (padding-inline,margin-inline,inset-inline,border-inline-end, …). Physical*-left/*-rightdeclarations live only in the publicLayoutPropsescape hatch and in two deliberately-physical files documented in the RTL audit. - Icons that imply direction (chevrons, arrows, indicators) mirror via
transform: scaleX(-1)when the document direction flips. - Focus-order and tab sequence are unaffected by direction — the document still flows from first to last.
Enable RTL
Section titled “Enable RTL”Wrap your app in DirectionProvider:
import { DirectionProvider } from '@arshad-shah/cynosure-react';
<DirectionProvider dir="rtl"> {children}</DirectionProvider>This sets dir="rtl" on the wrapping element and exposes a
useDirectionContext() hook every Cynosure component reads. Arrow-key
navigation in Tabs, RadioGroup, ToggleGroup, the menu family, and
NavigationMenu swaps the next/prev semantics so visual “right” always
matches the reading order.
Mix LTR + RTL on the same page
Section titled “Mix LTR + RTL on the same page”Nest another DirectionProvider:
<DirectionProvider dir="rtl"> <ArabicChrome> <DirectionProvider dir="ltr"> <EnglishExcerpt /> </DirectionProvider> </ArabicChrome></DirectionProvider>Each subtree resolves its own direction.
Author-facing escape hatch
Section titled “Author-facing escape hatch”If you need a physical property at the call site (e.g. “always add 8px to the
left”), use the LayoutProps escape hatch:
<Box paddingLeft="2">Physical padding — will NOT flip in RTL.</Box>Prefer the logical variants (paddingStart, paddingInline) unless you are
deliberately opting out.
pnpm audit:rtl walks every .css.ts in packages/react/src and fails
if it finds a physical *-left / *-right declaration outside the
allowlist. Run it locally before pushing RTL-sensitive changes.