Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Row): Forward ref added for row #53

Merged
merged 2 commits into from
Nov 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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