Skip to content

Commit 63aa80d

Browse files
authored
Feature/new props (#5)
* allow to render children * add test for children * update readme
1 parent b712d3e commit 63aa80d

7 files changed

Lines changed: 168 additions & 37 deletions

File tree

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ module.exports = {
4343
'react-native/split-platform-components': 1,
4444
'react/jsx-filename-extension': 0,
4545
'react/no-array-index-key': 0,
46+
'react/require-default-props': 0,
4647
'react/forbid-prop-types': [0, { forbid: ['any', 'array'] }],
4748
'react/jsx-no-bind': 1,
4849
'react/no-multi-comp': 1,

README.md

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# :foggy: Grid list component
22

3-
<p align="left">
4-
<a href="https://npmjs.org/package/react-native-grid-list"><img alt="npm version" src="http://img.shields.io/npm/v/react-native-grid-list.svg"></a>
5-
<a href="https://npmjs.org/package/react-native-grid-list"><img alt="npm version" src="http://img.shields.io/npm/dm/react-native-grid-list.svg"></a>
6-
<img alt="npm version" src="https://travis-ci.org/gusgard/react-native-grid-list.svg?branch=master">
7-
</p>
3+
![platforms](https://img.shields.io/badge/platforms-Android%20|%20iOS-brightgreen.svg)
4+
[![npm](https://img.shields.io/npm/v/react-native-grid-list.svg)](https://www.npmjs.com/package/react-native-grid-list)
5+
[![npm](https://img.shields.io/npm/dm/react-native-grid-list.svg)](https://www.npmjs.com/package/react-native-grid-list)
6+
[![travis](https://travis-ci.org/gusgard/react-native-grid-list.svg?branch=master)](https://travis-ci.org/gusgard/react-native-grid-list)
7+
![license](https://img.shields.io/npm/l/react-native-grid-list.svg)
88

99
![Demo](./demo.gif)
1010

@@ -80,20 +80,21 @@ http://facebook.github.io/react-native/docs/flatlist.html
8080

8181
## Props
8282

83-
| Prop | Default | Type | Description |
84-
| :------------------------------ | :--------: | :-------------: | :----------------------------------------- |
85-
| numColumns | 3 | `number` | Number of elements in a row |
86-
| data | _required_ | `array` | Data used when render items |
87-
| renderItem | _required_ | `func` | Function that render each item of the grid |
88-
| itemStyle | {} | `ViewPropTypes` | Style for the wrapper of item |
83+
| Prop | Default | Type | Description |
84+
| :------------------------------ | :--------------------------------: | :-------------: | :----------------------------------------- |
85+
| children | - | `node` | Children elements |
86+
| data | _not required if children is used_ | `array` | Data to use in renderItem |
87+
| renderItem | _not required if children is used_ | `func` | Function that render each item of the grid |
88+
| numColumns | 3 | `number` | Number of elements in a row |
89+
| itemStyle | {} | `ViewPropTypes` | Style for the wrapper of item |
8990
| **Separator** |
90-
| showSeparator | false | `bool` | Show a separator between items |
91-
| separatorBorderWidth | 0 | `number` | Set separator width |
92-
| separatorBorderColor | 'white' | `string` | Set separator color |
91+
| showSeparator | false | `bool` | Show a separator between items |
92+
| separatorBorderWidth | 0 | `number` | Set separator width |
93+
| separatorBorderColor | 'white' | `string` | Set separator color |
9394
| **Animation** |
94-
| showAnimation | false | `bool` | Show an animation when load item |
95-
| animationInitialBackgroundColor | 'white' | `string` | Set initial backgroundColor for animation |
96-
| animationDuration | 500 | `number` | Duration of the animation |
95+
| showAnimation | false | `bool` | Show an animation when load item |
96+
| animationInitialBackgroundColor | 'white' | `string` | Set initial backgroundColor for animation |
97+
| animationDuration | 500 | `number` | Duration of the animation |
9798

9899
## Author
99100

example/App.js

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
import React, { PureComponent } from 'react';
2-
import { Text, ScrollView, Image, StyleSheet, View } from 'react-native';
2+
import {
3+
Dimensions,
4+
Text,
5+
ScrollView,
6+
Image,
7+
StyleSheet,
8+
View,
9+
} from 'react-native';
310
import GridList from 'react-native-grid-list';
411

12+
export const { width, height } = Dimensions.get('window');
13+
514
const newImage = {
615
0: 'business',
716
1: 'cats',
@@ -44,9 +53,6 @@ export default class App extends PureComponent {
4453
onLoad={() => animation.start()}
4554
/>
4655
);
47-
renderItemSeparator = ({ item }) => (
48-
<Image style={styles.image} source={item.thumbnail} />
49-
);
5056

5157
render() {
5258
return (
@@ -77,17 +83,24 @@ export default class App extends PureComponent {
7783
/>
7884
</View>
7985

80-
{/* Separator */}
81-
<Text>Separator</Text>
86+
{/* Separator with children */}
87+
<Text>Separator with children</Text>
8288
<View style={styles.girdSeparator}>
8389
<GridList
8490
showSeparator
85-
data={itemsSeparator}
8691
numColumns={2}
87-
renderItem={this.renderItemSeparator}
8892
separatorBorderWidth={25}
89-
separatorBorderColor={'white'}
90-
/>
93+
separatorBorderColor={'teal'}
94+
>
95+
<View style={[styles.child, { backgroundColor: 'thistle' }]}>
96+
<Text style={styles.text}>1</Text>
97+
</View>
98+
<Image style={styles.image} source={itemsSeparator[0].thumbnail} />
99+
<View style={[styles.child, { backgroundColor: 'skyblue' }]}>
100+
<Text style={styles.text}>3</Text>
101+
</View>
102+
<Image style={styles.image} source={itemsSeparator[3].thumbnail} />
103+
</GridList>
91104
</View>
92105
</ScrollView>
93106
);
@@ -117,4 +130,12 @@ const styles = StyleSheet.create({
117130
width: '100%',
118131
height: '100%',
119132
},
133+
child: {
134+
flex: 1,
135+
justifyContent: 'center',
136+
},
137+
text: {
138+
fontSize: width * 0.2,
139+
textAlign: 'center',
140+
},
120141
});

src/components/GridList/__snapshots__/test.js.snap

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,63 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`grid list renders children 1`] = `
4+
<FlatList
5+
ItemSeparatorComponent={[Function]}
6+
animationDuration={500}
7+
animationInitialBackgroundColor="#FFFFFF"
8+
contentContainerStyle={false}
9+
data={
10+
Array [
11+
<Image
12+
source={
13+
Object {
14+
"uri": "https://...",
15+
}
16+
}
17+
/>,
18+
<Image
19+
source={
20+
Object {
21+
"uri": "https://...",
22+
}
23+
}
24+
/>,
25+
]
26+
}
27+
disableVirtualization={false}
28+
horizontal={false}
29+
initialNumToRender={10}
30+
itemStyle={Object {}}
31+
keyExtractor={[Function]}
32+
maxToRenderPerBatch={10}
33+
numColumns={3}
34+
onEndReachedThreshold={2}
35+
renderItem={[Function]}
36+
scrollEventThrottle={50}
37+
separatorBorderColor="#FFFFFF"
38+
separatorBorderWidth={0}
39+
showAnimation={false}
40+
showsVerticalScrollIndicator={false}
41+
updateCellsBatchingPeriod={50}
42+
windowSize={21}
43+
>
44+
<Image
45+
source={
46+
Object {
47+
"uri": "https://...",
48+
}
49+
}
50+
/>
51+
<Image
52+
source={
53+
Object {
54+
"uri": "https://...",
55+
}
56+
}
57+
/>
58+
</FlatList>
59+
`;
60+
361
exports[`grid list renders correctly 1`] = `
462
<FlatList
563
ItemSeparatorComponent={[Function]}

src/components/GridList/index.js

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,27 @@ export default class GridList extends PureComponent {
99
static propTypes = {
1010
animationDuration: PropTypes.number,
1111
animationInitialBackgroundColor: PropTypes.string,
12-
data: PropTypes.array.isRequired,
1312
itemStyle: ViewPropTypes.style,
1413
numColumns: PropTypes.number.isRequired,
15-
renderItem: PropTypes.func.isRequired,
1614
separatorBorderColor: PropTypes.string,
1715
separatorBorderWidth: PropTypes.number,
1816
showAnimation: PropTypes.bool,
1917
showSeparator: PropTypes.bool,
18+
19+
data: PropTypes.array,
20+
renderItem: PropTypes.func,
21+
22+
// Only is allowed children or data not both
23+
children(props, propName) {
24+
const { data } = props;
25+
if (!props[propName] && data && data.length === 0) {
26+
return new Error('Invalid props, `data` or `children` is required');
27+
}
28+
if (data && data.length !== 0 && !props.renderItem) {
29+
return new Error('Invalid props, `renderItem` is required');
30+
}
31+
return undefined;
32+
},
2033
};
2134

2235
static defaultProps = {
@@ -53,17 +66,30 @@ export default class GridList extends PureComponent {
5366
}
5467
this.styles = generateStyles(stylesOptions);
5568

69+
this.setup(this.props);
5670
this.animate();
5771
}
58-
componentWillUpdate() {
72+
componentWillUpdate(nextProps) {
73+
this.setup(nextProps);
5974
this.animate();
6075
}
76+
77+
setup = ({ children, data, renderItem }) => {
78+
if (children) {
79+
this._data = children;
80+
this._renderItem = this.renderChildren;
81+
} else if (data) {
82+
this._data = data;
83+
this._renderItem = renderItem;
84+
}
85+
};
86+
6187
animate() {
6288
if (this.props.showAnimation) {
63-
const { data, numColumns, animationDuration } = this.props;
89+
const { numColumns, animationDuration } = this.props;
6490
this.animatedValue = [];
6591

66-
this.animations = data.map((_, index) => {
92+
this.animations = this._data.map((_, index) => {
6793
this.animatedValue[index] = new Animated.Value(0);
6894
return Animated.stagger(0, [
6995
Animated.timing(this.animatedValue[index], {
@@ -77,8 +103,8 @@ export default class GridList extends PureComponent {
77103

78104
_keyExtractor = (item, index) => index;
79105

80-
_renderItem = ({ item, index }) => {
81-
const { showAnimation, showSeparator, renderItem, itemStyle } = this.props;
106+
renderItem = ({ item, index }) => {
107+
const { showAnimation, showSeparator, itemStyle } = this.props;
82108

83109
const viewStyles = [];
84110
viewStyles.push(this.styles.itemContainer);
@@ -100,15 +126,26 @@ export default class GridList extends PureComponent {
100126
{ opacity: this.animatedValue[index] },
101127
]}
102128
>
103-
{renderItem({ item, index, animation: this.animations[index] })}
129+
{this._renderItem({
130+
item,
131+
index,
132+
animation: this.animations[index],
133+
})}
104134
</Animated.View>
105135
) : (
106-
renderItem({ item, index })
136+
this._renderItem({ item, index })
107137
)}
108138
</View>
109139
);
110140
};
111141

142+
renderChildren = ({ item, animation }) => {
143+
if (animation) {
144+
animation.start();
145+
}
146+
return item;
147+
};
148+
112149
render() {
113150
const { showSeparator, ...props } = this.props;
114151
return (
@@ -120,7 +157,8 @@ export default class GridList extends PureComponent {
120157
}
121158
showsVerticalScrollIndicator={false}
122159
{...props}
123-
renderItem={this._renderItem}
160+
data={this._data}
161+
renderItem={this.renderItem}
124162
/>
125163
);
126164
}

src/components/GridList/styles.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export default ({
2020
},
2121
itemContainerAnimationEnd: {
2222
backgroundColor: separatorBorderColor,
23+
width: '100%',
24+
height: '100%',
2325
},
2426
separator: {
2527
borderColor: separatorBorderColor,

src/components/GridList/test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,14 @@ describe('grid list', () => {
6969
);
7070
expect(wrapper).toMatchSnapshot();
7171
});
72+
73+
it('renders children', () => {
74+
const wrapper = shallow(
75+
<GridList>
76+
<Image source={items[0].thumbnail} />
77+
<Image source={items[1].thumbnail} />
78+
</GridList>,
79+
);
80+
expect(wrapper).toMatchSnapshot();
81+
});
7282
});

0 commit comments

Comments
 (0)