Created
September 20, 2024 13:03
-
-
Save Ali72/0a126513a7194d42739135f5a1468aff to your computer and use it in GitHub Desktop.
HorizontalRTLSupportFlatList
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
import React, {useEffect, useRef, useState} from 'react'; | |
import {FlatList, I18nManager} from 'react-native'; | |
/** | |
* HorizontalRTLSupportFlatList | |
* | |
* This component is a custom wrapper around React Native's FlatList to add support | |
* for Right-to-Left (RTL) layouts when rendering horizontal lists. It automatically | |
* handles reversing the scroll direction and item order in RTL mode while maintaining | |
* the correct visual order of list items. Additionally, it includes logic to manage | |
* scrolling behavior in large screens and to handle potential scroll failures. | |
* | |
* Why this component was created: | |
* - React Native's FlatList does not provide native RTL scrolling for horizontal lists. | |
* - This component ensures correct scrolling direction and item order in RTL layouts. | |
* - It solves the need for a reusable RTL-friendly horizontal FlatList component. | |
* | |
* Key Features: | |
* - Automatically flips the FlatList's horizontal scrolling in RTL mode by reversing the data and using the `inverted` prop. | |
* - Reverses the data array to display items in the correct visual order for RTL layouts. | |
* - Scrolls to the last item in RTL mode (or the first item in LTR mode) after the layout is complete. | |
* - Adjusts the scroll offset to center the selected item for large screens. | |
* - Handles potential `scrollToIndex` failures by using `onScrollToIndexFailed` to retry scrolling after a small delay. | |
* | |
* Scroll Behavior: | |
* - Uses the `inverted` prop to flip the scrolling direction in RTL mode without the need for a `scaleX` transformation. | |
* - Scrolls to the last item in RTL mode once the layout is complete and retries scrolling on failure. | |
* - Adjusts the scroll offset on large screens for better centering of items. | |
*/ | |
const HorizontalRTLSupportFlatList = ({renderItem, data, ...props}) => { | |
const flatListRef = useRef(null); // Reference for accessing FlatList methods like scrollToIndex | |
const [isLayoutComplete, setIsLayoutComplete] = useState(false); // Tracks whether the FlatList has completed layout | |
const [isScrollToIndexFailed, setScrollToIndexFailed] = useState(false); // Tracks if scrollToIndex has failed | |
// Reverse the data if RTL mode is active to ensure the correct visual order of items. | |
const processedData = I18nManager.isRTL ? [...data].reverse() : data; | |
useEffect(() => { | |
// Scroll to the last item in RTL mode after the layout is complete | |
if (I18nManager.isRTL && isLayoutComplete && flatListRef.current && processedData.length > 0) { | |
flatListRef.current.scrollToIndex({index: processedData.length - 1, animated: false}); | |
} | |
}, [isLayoutComplete, isScrollToIndexFailed, processedData]); | |
return ( | |
<FlatList | |
ref={flatListRef} // Ref to programmatically control FlatList | |
horizontal // Specifies horizontal list layout | |
inverted={I18nManager.isRTL} // Inverts scrolling in RTL mode | |
data={processedData} // Use processed (reversed) data for correct RTL order | |
{...props} // Spread other props like keyExtractor, extraData, etc. | |
renderItem={renderItem} // Function to render each item in the list | |
onLayout={() => setIsLayoutComplete(true)} // Trigger layout completion callback | |
onScrollToIndexFailed={info => { | |
// Handle scrollToIndex failure and retry after a short delay | |
const wait = new Promise(resolve => setTimeout(resolve, 200)); | |
wait.then(() => { | |
setScrollToIndexFailed(true); | |
}); | |
}} | |
/> | |
); | |
}; | |
export default HorizontalRTLSupportFlatList; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment