Skip to content

Commit

Permalink
Item container override (Flipkart#675)
Browse files Browse the repository at this point in the history
* Item container support added

* Added description for renderItemContainer

* version bump

* fixed bug where layout size was ignored on first load by scroll component callback

Co-authored-by: Talha Naqvi <talha.naqvi@shopify.com>
  • Loading branch information
naqvitalha and naqvitalha authored Jan 27, 2022
1 parent 9d19a45 commit 9098c31
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 31 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "recyclerlistview",
"version": "3.0.5",
"version": "3.1.0-beta.2",
"description": "The listview that you need and deserve. It was built for performance, uses cell recycling to achieve smooth scrolling.",
"main": "dist/reactnative/index.js",
"types": "dist/reactnative/index.d.ts",
Expand Down
7 changes: 6 additions & 1 deletion src/core/RecyclerListView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export interface RecyclerListViewProps {
style?: object | number;
debugHandlers?: DebugHandlers;
renderContentContainer?: (props?: object, children?: React.ReactNode) => React.ReactNode | null;
renderItemContainer?: (props: object, parentProps: object, children?: React.ReactNode) => React.ReactNode;
//For all props that need to be proxied to inner/external scrollview. Put them in an object and they'll be spread
//and passed down. For better typescript support.
scrollViewProps?: object;
Expand Down Expand Up @@ -628,6 +629,7 @@ export default class RecyclerListView<P extends RecyclerListViewProps, S extends
itemAnimator={Default.value<ItemAnimator>(this.props.itemAnimator, this._defaultItemAnimator)}
extendedState={this.props.extendedState}
internalSnapshot={this.state.internalSnapshot}
renderItemContainer={this.props.renderItemContainer}
onItemLayout={this.props.onItemLayout}/>
);
}
Expand Down Expand Up @@ -796,12 +798,15 @@ RecyclerListView.propTypes = {
//animations are JS driven to avoid workflow interference. Also, please note LayoutAnimation is buggy on Android.
itemAnimator: PropTypes.instanceOf(BaseItemAnimator),

//The Recyclerlistview item cells are enclosed inside this item container. The idea is pass a native UI component which implements a
//All of the Recyclerlistview item cells are enclosed inside this item container. The idea is pass a native UI component which implements a
//view shifting algorithm to remove the overlaps between the neighbouring views. This is achieved by shifting them by the appropriate
//amount in the correct direction if the estimated sizes of the item cells are not accurate. If this props is passed, it will be used to
//enclose the list items and otherwise a default react native View will be used for the same.
renderContentContainer: PropTypes.func,

//This container is for wrapping individual cells that are being rendered by recyclerlistview unlike contentContainer which wraps all of them.
renderItemContainer: PropTypes.func,

//Enables you to utilize layout animations better by unmounting removed items. Please note, this might increase unmounts
//on large data changes.
optimizeForInsertDeleteAnimations: PropTypes.bool,
Expand Down
1 change: 1 addition & 0 deletions src/core/scrollcomponent/BaseScrollComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface ScrollComponentProps {
onLayout?: any;
renderContentContainer?: (props?: object, children?: React.ReactNode) => React.ReactNode | null;
renderAheadOffset: number;
layoutSize?: Dimension;
}
export default abstract class BaseScrollComponent extends React.Component<ScrollComponentProps, {}> {
public abstract scrollTo(x: number, y: number, animate: boolean): void;
Expand Down
1 change: 1 addition & 0 deletions src/core/viewrenderer/BaseViewRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface ViewRendererProps<T> {
internalSnapshot?: object;
layoutProvider?: BaseLayoutProvider;
onItemLayout?: (index: number) => void;
renderItemContainer?: (props: object, parentProps: ViewRendererProps<T>, children?: React.ReactNode) => React.ReactNode;
}
export default abstract class BaseViewRenderer<T> extends ComponentCompat<ViewRendererProps<T>, {}> {
protected animatorStyleOverrides: object | undefined;
Expand Down
5 changes: 3 additions & 2 deletions src/platform/reactnative/scrollcomponent/ScrollComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export default class ScrollComponent extends BaseScrollComponent {

constructor(args: ScrollComponentProps) {
super(args);
this._height = 0;
this._width = 0;
this._height = (args.layoutSize && args.layoutSize.height) || 0;
this._width = (args.layoutSize && args.layoutSize.width) || 0;
this._offset = 0;
this._isSizeChangedCalledOnce = false;
}
Expand All @@ -53,6 +53,7 @@ export default class ScrollComponent extends BaseScrollComponent {
},
horizontal : this.props.isHorizontal,
scrollOffset : this._offset,
renderAheadOffset: this.props.renderAheadOffset,
windowSize: (this.props.isHorizontal ? this._width : this._height) + this.props.renderAheadOffset,
};
//TODO:Talha
Expand Down
57 changes: 30 additions & 27 deletions src/platform/reactnative/viewrenderer/ViewRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,39 +13,42 @@ export default class ViewRenderer extends BaseViewRenderer<any> {
private _dim: Dimension = { width: 0, height: 0 };
private _viewRef: React.Component<ViewProperties, React.ComponentState> | null = null;
public renderCompat(): JSX.Element {
return this.props.forceNonDeterministicRendering ? (
<View ref={this._setRef}
onLayout={this._onLayout}
style={{
flexDirection: this.props.isHorizontal ? "column" : "row",
left: this.props.x,
position: "absolute",
top: this.props.y,
...this.props.styleOverrides,
...this.animatorStyleOverrides,
}}>
{this.renderChild()}
</View>
) : (
<View ref={this._setRef}
style={{
left: this.props.x,
position: "absolute",
top: this.props.y,
height: this.props.height,
width: this.props.width,
...this.props.styleOverrides,
...this.animatorStyleOverrides,
}}>
{this.renderChild()}
</View>
);
const props = this.props.forceNonDeterministicRendering
? {
ref: this._setRef,
onLayout: this._onLayout,
style: {
flexDirection: this.props.isHorizontal ? "column" : "row",
left: this.props.x,
position: "absolute",
top: this.props.y,
...this.props.styleOverrides,
...this.animatorStyleOverrides,
},
}
: {
ref: this._setRef,
style: {
left: this.props.x,
position: "absolute",
top: this.props.y,
height: this.props.height,
width: this.props.width,
...this.props.styleOverrides,
...this.animatorStyleOverrides,
},
};
return this._renderItemContainer(props, this.props, this.renderChild()) as JSX.Element;
}

protected getRef(): object | null {
return this._viewRef;
}

private _renderItemContainer(props: object, parentProps: ViewRendererProps<any>, children: React.ReactNode): React.ReactNode {
return (this.props.renderItemContainer && this.props.renderItemContainer(props, parentProps, children)) || (<View {...props}>{children}</View>);
}

private _setRef = (view: React.Component<ViewProperties, React.ComponentState> | null): void => {
this._viewRef = view;
}
Expand Down

0 comments on commit 9098c31

Please sign in to comment.