-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
124 lines (108 loc) · 2.98 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import { View, FlatList, Dimensions } from 'react-native'
const d2 = (input, length) => {
const output = []
input.forEach((item, key) => {
const x = Math.floor(key / length)
if (!output[x]) {
output[x] = []
}
output[x].push(item)
})
return output
}
class GridView extends PureComponent {
static defaultProps = {
data: [],
span: 1,
render: () => {},
spacing: 0,
border: 0,
borderColor: 'black',
square: false,
flat: true,
}
constructor (props) {
super(props)
this.state = this.getDimensions()
}
getDimensions = (lvWidth) => {
const { span, spacing } = this.props
const totalWidth = lvWidth || Dimensions.get('window').width
const totalSpacing = (span + 1) * spacing
const itemWidth = Math.floor((totalWidth - totalSpacing) / span)
return {
itemWidth,
}
}
onLayout = (e) => {
const { width } = e.nativeEvent.layout || {}
this.setState({
...this.getDimensions(width),
})
}
itemStyle = (index) => {
const { data, span, spacing, square, flat, border, borderColor } = this.props
const { itemWidth } = this.state
const isEnd = index >= ((Math.floor(data.length / span) - 1) * span)
const style = {
marginLeft: spacing,
marginBottom: (!flat || isEnd) ? spacing : 0,
marginTop: (index < span) ? spacing : 0,
height: square ? itemWidth : 'auto',
borderWidth: border,
borderColor,
borderLeftWidth: !spacing ? 0 : border,
borderTopWidth: (!spacing && (index >= span)) ? 0 : border,
borderRightWidth: (!spacing && !((index + 1) % span)) ? 0 : border,
}
return style
}
renderItem = ({ item, index }) => {
const { itemWidth } = this.state
const { render } = this.props
return (
<View style={[{ width: itemWidth }, this.itemStyle(index)]} key={index}>
{render(item)}
</View>
)
}
render () {
const { data, span, spacing, flat, ...props } = this.props
return flat ? (
<FlatList
ItemSeparatorComponent={() => <View style={{ height: spacing }} />}
onLayout={this.onLayout}
data={data}
numColumns={span}
keyExtractor={(item, index) => index}
renderItem={this.renderItem}
{...props}
/>
) : (
<View onLayout={this.onLayout} {...props}>
{d2(data, span).map((tr, key) => (
<View key={key} style={{ flexDirection: 'row' }}>
{tr.map((td, k) => (
<View key={k}>
{this.renderItem({ item: td, index: (key * span) + k })}
</View>
))}
</View>
))}
</View>
)
}
}
GridView.propTypes = {
data: PropTypes.array,
span: PropTypes.number,
render: PropTypes.func,
spacing: PropTypes.number,
border: PropTypes.number,
square: PropTypes.bool,
borderColor: PropTypes.string,
flat: PropTypes.bool,
}
export default GridView