rtl
Installation
SKILL.md
RTL Compatibility Audit (stream-chat-react-native)
Use this skill whenever code changes can affect users in RTL locales (Hebrew he ships today; Arabic/Persian/Urdu integrators are common). React Native flips some layout properties automatically via I18nManager.isRTL, but absolute positioning, hardcoded margins/paddings, transforms, swipe gestures, and SVG icons must be handled by hand.
When the user asks for an "RTL audit" or "RTL review," walk the Audit checklist against the diff (or the named files), then return findings grouped by severity. When writing new code, apply the Patterns to follow rather than just the anti-patterns at the end.
Non-negotiable rules
- Read direction at runtime. Use
I18nManager.isRTLfromreact-native. Never assume LTR. Never assume a value at module load time only —I18nManager.isRTLis a static snapshot per JS bundle (RN reloads the bundle on direction change), so module-scope reads are fine, but state that depends on it must not be cached across user-driven direction toggles within a single session unless the bundle is reloaded. - Logical properties beat physical ones. Prefer
start/endvariants (paddingStart,marginEnd,borderStartWidth,insetStart) overleft/rightfor spacing and borders. RN auto-flipsstart/endbased onI18nManager.isRTL. The exception is absolute positioning — RN does NOT auto-flipleft/righton absolutely positioned elements; those need an explicitI18nManager.isRTLconditional. - flexDirection: 'row' auto-flips. Default
flexDirection: 'row'reverses in RTL. Do NOT counter this by manually setting'row-reverse'for "alignment fixes" — that double-flips and breaks RTL. Only use'row-reverse'when the visual order must be opposite of reading order in both directions. - Text alignment defaults to writing direction. For
Text, defaulttextAlignis already direction-aware. SettextAlign: 'left'/'right'ONLY when you need a fixed visual side; otherwise omit it or usetextAlign: 'auto'. When you need "align to start of reading direction" explicitly, writetextAlign: I18nManager.isRTL ? 'right' : 'left'. writingDirectionon Text that mixes scripts. When user-generated text could contain RTL characters (messages, channel names, member names, poll options, inputs), setwritingDirection: I18nManager.isRTL ? 'rtl' : 'ltr'(iOS) so bidi resolution matches the app direction. Or wrap withWritingDirectionAwareTextfrompackage/src/components/RTLComponents/.- Mirror directional icons; don't mirror neutral ones. Arrows, chevrons, reply, send, thread, search-magnifier, message-bubble must flip in RTL. Symmetric icons (checkmark, bell, settings gear, like-heart, emoji face) must NOT flip. Use SVG
transform={I18nManager.isRTL ? 'matrix(-1 0 0 1 W 0)' : undefined}whereWis the SVG width. - Swipe gestures need a direction multiplier. Any gesture that moves content along the X-axis (swipe-to-reply, swipe-to-delete, paging) must multiply
translationXbyI18nManager.isRTL ? -1 : 1. Otherwise swipe-from-right-to-left does the wrong thing in RTL. - Backward-compatible. RTL fixes should not change LTR behavior. When in doubt, the conditional form
I18nManager.isRTL ? rtl : ltris safer than swapping a default.