Skip to content

Commit

Permalink
Merge pull request #53 from flexn-io/fix/recycler-ref
Browse files Browse the repository at this point in the history
feat(Row): Forward ref added for row
  • Loading branch information
aurimasmi committed Nov 9, 2022
2 parents a54d8d4 + 6f25346 commit 4221cd3
Show file tree
Hide file tree
Showing 3 changed files with 3,454 additions and 3,440 deletions.
236 changes: 126 additions & 110 deletions packages/sdk/src/complexComponents/Row/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useRef, useEffect } from 'react';
import React, { useState, useRef, useEffect, forwardRef } from 'react';
import { StyleProp, ViewStyle, TextStyle, StyleSheet } from 'react-native';
import { isPlatformTvos } from '@rnv/renative';
import Text from '../../components/Text';
Expand All @@ -11,6 +11,8 @@ import { Ratio } from '../../helpers';
import { Context, RecyclableListFocusOptions } from '../../focusManager/types';
import { PosterCard } from '../Card';
import useDimensionsCalculator from '../../hooks/useDimensionsCalculator';
import type { RecyclerListViewProps } from '../../recyclerListView';
import type { RecyclerListViewState } from '../../recyclerListView/core/RecyclerListView';

type RowItem = {
backgroundImage: string;
Expand Down Expand Up @@ -41,127 +43,141 @@ interface RowProps {
disableItemContainer?: boolean;
}

const Row = ({
items,
title,
itemsInViewport,
parentContext,
repeatContext,
focusOptions,
animatorOptions,
style = {},
cardStyle = {},
titleStyle = {},
rerenderData,
onFocus,
onPress,
onBlur,
renderCard,
itemDimensions,
itemSpacing = 30,
verticalItemSpacing = 0,
horizontalItemSpacing = 0,
initialXOffset = 0,
disableItemContainer = false,
}: RowProps) => {
const ref: any = useRef();
const layoutProvider: any = useRef();
const dataProviderInstance = useRef(new RecyclableListDataProvider((r1, r2) => r1 !== r2)).current;
const [dataProvider, setDataProvider] = useState(dataProviderInstance.cloneWithRows(items));
const flattenTitleStyles = StyleSheet.flatten(titleStyle);
const { boundaries, isLoading, spacings, onLayout, rowDimensions } = useDimensionsCalculator({
style,
initialXOffset,
itemSpacing,
verticalItemSpacing,
horizontalItemSpacing,
itemDimensions,
itemsInViewport,
ref,
});
export type RecylerListRef = RecyclableList<RecyclerListViewProps, RecyclerListViewState>;

useEffect(() => {
setDataProvider(dataProviderInstance.cloneWithRows(items));
}, [rerenderData]);
const Row = forwardRef<RecylerListRef, RowProps>(
(
{
items,
title,
itemsInViewport,
parentContext,
repeatContext,
focusOptions,
animatorOptions,
style = {},
cardStyle = {},
titleStyle = {},
rerenderData,
onFocus,
onPress,
onBlur,
renderCard,
itemDimensions,
itemSpacing = 30,
verticalItemSpacing = 0,
horizontalItemSpacing = 0,
initialXOffset = 0,
disableItemContainer = false,
},
recyclerRef
) => {
const ref: any = useRef();
const layoutProvider: any = useRef();
const dataProviderInstance = useRef(new RecyclableListDataProvider((r1, r2) => r1 !== r2)).current;
const [dataProvider, setDataProvider] = useState(dataProviderInstance.cloneWithRows(items));
const flattenTitleStyles = StyleSheet.flatten(titleStyle);
const { boundaries, isLoading, spacings, onLayout, rowDimensions } = useDimensionsCalculator({
style,
initialXOffset,
itemSpacing,
verticalItemSpacing,
horizontalItemSpacing,
itemDimensions,
itemsInViewport,
ref,
});

const setLayoutProvider = () => {
if (!isLoading && !layoutProvider.current) {
layoutProvider.current = new RecyclableListLayoutProvider(
() => '_',
(_: string | number, dim: { width: number; height: number }) => {
dim.width = rowDimensions.layout.width;
dim.height = rowDimensions.layout.height;
}
);
}
};
useEffect(() => {
setDataProvider(dataProviderInstance.cloneWithRows(items));
}, [rerenderData]);

setLayoutProvider();
const setLayoutProvider = () => {
if (!isLoading && !layoutProvider.current) {
layoutProvider.current = new RecyclableListLayoutProvider(
() => '_',
(_: string | number, dim: { width: number; height: number }) => {
dim.width = rowDimensions.layout.width;
dim.height = rowDimensions.layout.height;
}
);
}
};

const rowRenderer = (_type: string | number, data: any, _index: number, _repeatContext: any, _renderProps: any) => {
if (renderCard) {
return renderCard(data, _repeatContext, { ...rowDimensions.item }, _renderProps);
}
return (
<PosterCard
src={{ uri: data.backgroundImage }}
title={data.title}
style={[cardStyle, { width: rowDimensions.item.width, height: rowDimensions.item.height }]}
onFocus={() => onFocus?.(data)}
onBlur={() => onBlur?.(data)}
onPress={() => onPress?.(data)}
repeatContext={_repeatContext}
renderProps={_renderProps}
focusOptions={{
animatorOptions,
}}
/>
);
};
setLayoutProvider();

const renderRecycler = () => {
if (!isLoading) {
const rowRenderer = (
_type: string | number,
data: any,
_index: number,
_repeatContext: any,
_renderProps: any
) => {
if (renderCard) {
return renderCard(data, _repeatContext, { ...rowDimensions.item }, _renderProps);
}
return (
<RecyclableList
type="row"
dataProvider={dataProvider}
layoutProvider={layoutProvider.current}
initialXOffset={Ratio(initialXOffset)}
repeatContext={repeatContext}
rowRenderer={rowRenderer}
disableItemContainer={disableItemContainer && isPlatformTvos}
isHorizontal
style={[{ width: boundaries.width, height: boundaries.height }]}
contentContainerStyle={{ ...spacings }}
scrollViewProps={{
showsHorizontalScrollIndicator: false,
}}
focusOptions={focusOptions}
unmeasurableRelativeDimensions={{
y: flattenTitleStyles?.fontSize || 0,
x: 0,
<PosterCard
src={{ uri: data.backgroundImage }}
title={data.title}
style={[cardStyle, { width: rowDimensions.item.width, height: rowDimensions.item.height }]}
onFocus={() => onFocus?.(data)}
onBlur={() => onBlur?.(data)}
onPress={() => onPress?.(data)}
repeatContext={_repeatContext}
renderProps={_renderProps}
focusOptions={{
animatorOptions,
}}
/>
);
}
};

return null;
};
const renderRecycler = () => {
if (!isLoading) {
return (
<RecyclableList
ref={recyclerRef}
type="row"
dataProvider={dataProvider}
layoutProvider={layoutProvider.current}
initialXOffset={Ratio(initialXOffset)}
repeatContext={repeatContext}
rowRenderer={rowRenderer}
disableItemContainer={disableItemContainer && isPlatformTvos}
isHorizontal
style={[{ width: boundaries.width, height: boundaries.height }]}
contentContainerStyle={{ ...spacings }}
scrollViewProps={{
showsHorizontalScrollIndicator: false,
}}
focusOptions={focusOptions}
unmeasurableRelativeDimensions={{
y: flattenTitleStyles?.fontSize || 0,
x: 0,
}}
/>
);
}

const renderTitle = () => {
if (title) {
return <Text style={[{ left: spacings.paddingLeft }, titleStyle]}>{title}</Text>;
}
return null;
};

return null;
};
const renderTitle = () => {
if (title) {
return <Text style={[{ left: spacings.paddingLeft }, titleStyle]}>{title}</Text>;
}

return (
<View parentContext={parentContext} style={style} onLayout={onLayout} ref={ref}>
{renderTitle()}
{renderRecycler()}
</View>
);
};
return null;
};

return (
<View parentContext={parentContext} style={style} onLayout={onLayout} ref={ref}>
{renderTitle()}
{renderRecycler()}
</View>
);
}
);

export default Row;
3 changes: 3 additions & 0 deletions packages/sdk/src/recyclerListView/core/RecyclerListView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import ScrollComponent from '../platform/reactnative/scrollcomponent/ScrollCompo
import ViewRenderer from '../platform/reactnative/viewrenderer/ViewRenderer';
import { Platform } from 'react-native';
import { isPlatformTvos, isPlatformAndroidtv, isPlatformFiretv } from '@rnv/renative';
import { Context } from '../../focusManager/types';
const IS_WEB = !Platform || Platform.OS === 'web';
const IS_NATIVE_TV = isPlatformTvos || isPlatformAndroidtv || isPlatformFiretv;
//#endif
Expand Down Expand Up @@ -129,6 +130,8 @@ export interface RecyclerListViewProps {
scrollViewProps?: object;
applyWindowCorrection?: (offsetX: number, offsetY: number, windowCorrection: WindowCorrection) => void;
onItemLayout?: (index: number) => void;
repeatContext?: Context;
unmeasurableRelativeDimensions?: { x?: number; y?: number };
}

export interface RecyclerListViewState {
Expand Down
Loading

0 comments on commit 4221cd3

Please sign in to comment.