feat: introduce rudimentary RTL support to the RN SDK#3522
Merged
isekovanic merged 16 commits intodevelopfrom Mar 31, 2026
Merged
feat: introduce rudimentary RTL support to the RN SDK#3522isekovanic merged 16 commits intodevelopfrom
isekovanic merged 16 commits intodevelopfrom
Conversation
Contributor
SDK Size
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🎯 Goal
This PR addresses a bunch of RTL issues our SDK has had over the last couple of majors and makes sure we have first class support for it.
Summary
This PR fixes a set of RTL specific UI regressions that were affecting several surfaces in the SDK.
The issues were not all caused by the same thing. Some were caused by relying on implicit platform mirroring, some by scroll/list containers using the wrong coordinate space in RTL, and some by spacing being applied on the wrong level of a scrollable surface. The result was a mix of broken alignment, unstable animations, blank gallery content, and inconsistent behavior between iOS and Android.
This PR makes those behaviors explicit and stabilizes the affected components without changing their public API.
Problems fixed
What changed
Gesture driven bugs in RTL
For a lot of the features in the SDK, such as channel swipeables, STR and similar we rely on gestures directly in order to be able to do an action. Gestures in RN are never RTL compliant and so we need to handle these cases explicitly. Most of the time, simple inversions work just fine however in certain instances (like our
SwipeableWrapper) a small adapter layer is needed to be able to distinguish between left and right.RTL attachment preview stability
The attachment preview strip now uses a stable coordinate-space approach in RTL so it no longer fights the list/pager/layout system.
Unfortunately, I could not at all get RTL to work natively here due to the fact that
reanimated's layout animations were completely messing with the underlyingScrollView's width calculations when horizontal. After a couple of hours of debugging I settled with disabling RTL directly and handling all edge cases manually.This was the area with the most platform sensitivity, especially on Android.
Poll modal spacing and layout fixes
The poll modal issue turned out not to be an individual-screen bug. The main problem was that outer padding was being applied on scroll/list wrappers, which behaves badly in Android RTL and can look like horizontal padding is only applied from one side.
The fix was to move spacing from outer scroll containers into their content containers for the shared poll modal surfaces.
This fixes layout issues in:
As part of that cleanup, earlier safe-area wrapper changes were reverted because they were not the actual fix.
Poll text alignment on iOS RTL
Poll titles, labels, cards, and result text were relying too much on implicit platform behavior. Android happened to look mostly correct, while iOS did not.
This PR makes the relevant non-input poll text alignment explicit where needed so the iOS rendering matches the intended RTL layout.
It also replaces a few LTR-only spacing rules with logical start-aware spacing where the text/result rows needed it.
Poll input alignment consistency
Poll inputs now follow the same RTL alignment rule as the existing autocomplete composer input instead of using a separate behavior.
That means poll inputs now use:
This was applied to the poll-specific input surfaces, including modal inputs, so editable text behaves consistently across the SDK.
Image gallery rendering in RTL
The gallery rendering issue was caused by a coordinate-space mismatch.
The pager/slide math in the image gallery is LTR-based, but the gallery container was still inheriting RTL layout direction. In practice, that meant the gallery could open and still respond to swipe/
close gestures, while the image slides themselves were effectively laid out off-screen.
The fix was to force only the gallery pager strip into LTR coordinates while leaving the rest of the experience intact.
This restores image rendering in RTL without changing the gallery gesture model.
Thread list item alignment
The channel name at the top of thread list items now uses explicit alignment so it renders correctly in RTL.
This is a narrow change scoped only to that text style.
Why this approach
The common theme across these issues is that implicit RTL handling was not reliable enough for these components.
The fixes in this PR intentionally avoid broad “flip everything” logic. Instead, each surface now expresses the behavior it actually needs:
That keeps the fixes targeted and avoids introducing new regressions in already. correct layouts.
I'm sure there are other edge cases with RTL that I did not manage to notice, however as a first step this should do just fine, especially considering we've never had any RTL support before.
🛠 Implementation details
🎨 UI Changes
iOS
Android
🧪 Testing
☑️ Checklist
developbranch