Skip to content

Commit

Permalink
Fix RTL ScrollView position when content smaller than container
Browse files Browse the repository at this point in the history
Summary:
Noticed in the screenshots of facebook#47230 that Android's logic of setting scroll content origin to zero, than right aligning scroll offset, won't correctly handle case where content is smaller than scrolling container. We can fix that by only resetting the origin when content overflows container, since we otherwise are not scrollable, and scroll adjustment will not translate.

Changelog:
[Android][Fixed] - Fix RTL ScrollView position when content smaller than container

Differential Revision: D65136654
  • Loading branch information
NickGerleman authored and facebook-github-bot committed Oct 29, 2024
1 parent c1e964a commit 5de32c1
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ void AndroidHorizontalScrollContentViewShadowNode::layout(
ConcreteViewShadowNode::layout(layoutContext);

// When the layout direction is RTL, we expect Yoga to give us a layout
// that extends off the screen to the left so we re-center it with left=0
if (layoutMetrics_.layoutDirection == LayoutDirection::RightToLeft) {
// that extends off the screen to the left so we re-center it to be at most
// zero (where the scrolling offset will be adjusted to match if larger than
// parent width on the Android component side).
if (layoutMetrics_.layoutDirection == LayoutDirection::RightToLeft &&
layoutMetrics_.frame.origin.x < 0) {
layoutMetrics_.frame.origin.x = 0;
}
}
Expand Down
23 changes: 21 additions & 2 deletions packages/rn-tester/js/examples/ScrollView/ScrollViewExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,19 @@ const examples: Array<RNTesterModuleExample> = [
);
},
},
{
name: 'stubbyHorizontalScrollView',
title: '<ScrollView> (horizontal = true) in RTL not filling content\n',
description:
'A horizontal RTL ScrollView whose content is smaller thatn its containner',
render(): React.Node {
return (
<View testID="stubby-horizontal-rtl-scrollview">
<HorizontalScrollView direction="rtl" itemCount={1} />
</View>
);
},
},
{
title: '<ScrollView> enable & disable\n',
description: 'ScrollView scrolling behaviour can be disabled and enabled',
Expand Down Expand Up @@ -541,10 +554,16 @@ const AndroidScrollBarOptions = () => {
);
};

const HorizontalScrollView = (props: {direction: 'ltr' | 'rtl'}) => {
const HorizontalScrollView = (props: {
direction: 'ltr' | 'rtl',
itemCount?: number,
}) => {
const {direction} = props;
const scrollRef = React.useRef<?React.ElementRef<typeof ScrollView>>();
const title = direction === 'ltr' ? 'LTR Layout' : 'RTL Layout';
const items =
props.itemCount == null ? ITEMS : ITEMS.slice(0, props.itemCount);

return (
<View style={{direction}}>
<RNTesterText style={styles.text}>{title}</RNTesterText>
Expand All @@ -555,7 +574,7 @@ const HorizontalScrollView = (props: {direction: 'ltr' | 'rtl'}) => {
horizontal={true}
style={[styles.scrollView, styles.horizontalScrollView]}
testID={'scroll_horizontal'}>
{ITEMS.map(createItemRow)}
{items.map(createItemRow)}
</ScrollView>
<Button
label="Scroll to start"
Expand Down

0 comments on commit 5de32c1

Please sign in to comment.