From 0b5ca976944ff56c0659cd70fcf53a3de783b232 Mon Sep 17 00:00:00 2001 From: MohamedKassim Date: Sun, 28 Jun 2026 00:08:01 +0300 Subject: [PATCH] fix(rtl): horizontal list is blank in a native-RTL app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A horizontal list renders completely blank when the app itself is RTL (`I18nManager.isRTL === true`). The library emulates RTL in logical (LTR) coordinates and mirrors item positions in JS, which assumes a native-LTR scroll container — which is exactly why `direction: "ltr"` is already forced on web (Container.tsx). On native the scroll container also flips under `I18nManager.isRTL`, so the JS mirror and the native flip compound and the rendered window is painted offscreen → blank everywhere. Neutralize the native flip on the scroll container too (`Platform.OS !== "web"`), mirroring the existing web handling, so the library's JS mirror is the only RTL flip. LTR and vertical lists are unaffected. Fixes #477 Co-Authored-By: Claude Opus 4.8 (1M context) --- src/components/ListComponent.tsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/components/ListComponent.tsx b/src/components/ListComponent.tsx index 163856e4..bb737279 100644 --- a/src/components/ListComponent.tsx +++ b/src/components/ListComponent.tsx @@ -30,6 +30,7 @@ import { useArr$, useStateContext } from "@/state/state"; import { type GetRenderedItem, type LegendListPropsBase, typedMemo } from "@/types.internal"; import { IS_DEV } from "@/utils/devEnvironment"; import { getComponent } from "@/utils/getComponent"; +import { isHorizontalRTL } from "@/utils/rtl"; interface ListComponentProps extends Omit< @@ -200,7 +201,18 @@ export const ListComponent = typedMemo(function ListComponent({ onScroll={onScroll} ref={refScrollView as any} ScrollComponent={snapToIndices ? ScrollComponent : (undefined as any)} - style={autoOtherAxisStyle ? [autoOtherAxisStyle, style] : style} + // RTL is emulated in logical (LTR) coordinates with item positions mirrored + // in JS, so the scroll container must stay LTR. On web that's done per-item + // (Container.tsx); on native the container itself also flips under + // I18nManager.isRTL, and the double flip renders the list blank — so + // neutralize the native flip here too. See #477. Keep this array flat: the + // web scroll view flattens it shallowly, so a nested array would drop the + // measured cross-axis size. + style={[ + isHorizontalRTL(ctx.state) && Platform.OS !== "web" ? { direction: "ltr" } : null, + autoOtherAxisStyle, + style, + ]} > {ListHeaderComponent && (