mirror of
https://github.com/zhigang1992/react-native-super-grid.git
synced 2026-01-12 17:42:52 +08:00
Initial Commit
This commit is contained in:
11
.eslintrc.js
Normal file
11
.eslintrc.js
Normal file
@@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
"extends": "airbnb",
|
||||
"plugins": [
|
||||
"react",
|
||||
"jsx-a11y",
|
||||
"import"
|
||||
],
|
||||
"rules": {
|
||||
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }]
|
||||
}
|
||||
};
|
||||
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
16
.npmignore
Normal file
16
.npmignore
Normal file
@@ -0,0 +1,16 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Screenshots
|
||||
screenshots
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Saleel
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
136
README.md
Normal file
136
README.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# React Native Super Grid
|
||||
|
||||
Responsive Grid View for React Native.
|
||||
|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
This component renders a Grid View that adapts itself to various screen resolutions.
|
||||
|
||||
Instead of passing an itemPerRow argument, you pass ```itemWidth``` and each item will be rendered with a width equal to or more than (to fill the screen) the given width.
|
||||
|
||||
Internally, this component use the native [ListView](https://facebook.github.io/react-native/docs/listview.html).
|
||||
|
||||
|
||||
### Installing
|
||||
|
||||
You can install the package via npm.
|
||||
|
||||
```
|
||||
npm install react-native-super-grid
|
||||
```
|
||||
|
||||
|
||||
### Usage
|
||||
```
|
||||
import GridView from 'react-native-super-grid';
|
||||
```
|
||||
```
|
||||
<GridView
|
||||
itemWidth={130}
|
||||
items={[1,2,3,4,5,6]}
|
||||
renderRow={item => (<Text>{item}</Text>)}
|
||||
/>
|
||||
```
|
||||
|
||||
#### Properties
|
||||
|
||||
| Property | Type | Default Value | Description |
|
||||
|---|---|---|---|
|
||||
| renderItem | Function | | Function to render each object. Should return a react native component. |
|
||||
| items | Array | | Items to be rendered. renderItem will be called with each item in this array. | |
|
||||
| itemWidth | Number | 120 | Minimum width for each item in pixels (virtual). |
|
||||
| fixed | Boolean | false | If true, the exact ```itemWidth``` will be used and won't be adjusted to fit the screen. |
|
||||
| spacing | Number | 10 | Spacing between each item. |
|
||||
| style | [ListView](https://facebook.github.io/react-native/docs/listview.html) styles (Object) | | Styles for the container. Styles for an item should be applied inside ```renderItem```. |
|
||||
|
||||
|
||||
|
||||
## Example
|
||||
```
|
||||
import React, { Component } from 'react';
|
||||
import { StyleSheet, View, Text } from 'react-native';
|
||||
import GridView from 'react-native-super-grid';
|
||||
|
||||
export default class Example extends Component {
|
||||
render() {
|
||||
// Taken from https://flatuicolors.com/
|
||||
const items = [
|
||||
{ name: 'TURQUOISE', code: '#1abc9c' }, { name: 'EMERALD', code: '#2ecc71' },
|
||||
{ name: 'PETER RIVER', code: '#3498db' }, { name: 'AMETHYST', code: '#9b59b6' },
|
||||
{ name: 'WET ASPHALT', code: '#34495e' }, { name: 'GREEN SEA', code: '#16a085' },
|
||||
{ name: 'NEPHRITIS', code: '#27ae60' }, { name: 'BELIZE HOLE', code: '#2980b9' },
|
||||
{ name: 'WISTERIA', code: '#8e44ad' }, { name: 'MIDNIGHT BLUE', code: '#2c3e50' },
|
||||
{ name: 'SUN FLOWER', code: '#f1c40f' }, { name: 'CARROT', code: '#e67e22' },
|
||||
{ name: 'ALIZARIN', code: '#e74c3c' }, { name: 'CLOUDS', code: '#ecf0f1' },
|
||||
{ name: 'CONCRETE', code: '#95a5a6' }, { name: 'ORANGE', code: '#f39c12' },
|
||||
{ name: 'PUMPKIN', code: '#d35400' }, { name: 'POMEGRANATE', code: '#c0392b' },
|
||||
{ name: 'SILVER', code: '#bdc3c7' }, { name: 'ASBESTOS', code: '#7f8c8d' },
|
||||
];
|
||||
|
||||
return (
|
||||
<GridView
|
||||
itemWidth={130}
|
||||
items={items}
|
||||
style={styles.gridView}
|
||||
renderItem={item => (
|
||||
<View style={[styles.itemContainer, { backgroundColor: item.code }]}>
|
||||
<Text style={styles.itemName}>{item.name}</Text>
|
||||
<Text style={styles.itemCode}>{item.code}</Text>
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
gridView: {
|
||||
paddingTop: 25,
|
||||
flex: 1,
|
||||
},
|
||||
itemContainer: {
|
||||
justifyContent: 'flex-end',
|
||||
borderRadius: 5,
|
||||
padding: 10,
|
||||
height: 150,
|
||||
},
|
||||
itemName: {
|
||||
fontSize: 16,
|
||||
color: '#fff',
|
||||
fontWeight: '600',
|
||||
},
|
||||
itemCode: {
|
||||
fontWeight: '600',
|
||||
fontSize: 12,
|
||||
color: '#fff',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
| |  |
|
||||
|:---:|:---:|
|
||||
| iPhone6 Portrait | iPhone6 Landscape |
|
||||
|
||||
|  |  |
|
||||
|:---:|:---:|
|
||||
| iPad Air 2 Portrait | iPad Air 2 Landscape |
|
||||
|
||||
|  |  |
|
||||
|:---:|:---:|
|
||||
| Android Portrait | Android Landscape |
|
||||
|
||||
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.
|
||||
|
||||
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Colors in the example from https://flatuicolors.com/.
|
||||
|
||||
Screenshot Mockup generated from https://mockuphone.com.
|
||||
109
index.js
Normal file
109
index.js
Normal file
@@ -0,0 +1,109 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { View, ListView, Dimensions } from 'react-native';
|
||||
import { chunkArray } from './utils';
|
||||
|
||||
class SuperGrid extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.renderRow = this.renderRow.bind(this);
|
||||
this.onLayout = this.onLayout.bind(this);
|
||||
this.getDimensions = this.getDimensions.bind(this);
|
||||
this.state = this.getDimensions();
|
||||
}
|
||||
|
||||
onLayout(e) {
|
||||
const { width } = e.nativeEvent.layout || {};
|
||||
this.setState({
|
||||
...this.getDimensions(width),
|
||||
});
|
||||
}
|
||||
|
||||
getDimensions(lvWidth) {
|
||||
const { itemWidth, spacing, fixed } = this.props;
|
||||
const totalWidth = lvWidth || Dimensions.get('window').width;
|
||||
|
||||
const itemTotalWidth = itemWidth + spacing;
|
||||
const availableWidth = totalWidth - spacing; // One spacing extra
|
||||
const itemsPerRow = Math.floor(availableWidth / itemTotalWidth);
|
||||
const containerWidth = availableWidth / itemsPerRow;
|
||||
|
||||
return {
|
||||
itemWidth,
|
||||
spacing,
|
||||
itemsPerRow,
|
||||
containerWidth,
|
||||
fixed,
|
||||
};
|
||||
}
|
||||
|
||||
renderRow(data, sectionId, rowId) {
|
||||
const { itemWidth, spacing, containerWidth, fixed } = this.state;
|
||||
|
||||
const rowStyle = {
|
||||
flexDirection: 'row',
|
||||
paddingLeft: spacing,
|
||||
paddingBottom: spacing,
|
||||
};
|
||||
const columnStyle = {
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
width: containerWidth,
|
||||
paddingRight: spacing,
|
||||
};
|
||||
let itemStyle = { };
|
||||
if (fixed) {
|
||||
itemStyle = {
|
||||
width: itemWidth,
|
||||
alignSelf: 'center',
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={rowStyle}>
|
||||
{(data || []).map((item, i) => (
|
||||
<View key={`${rowId}_${i}`} style={columnStyle}>
|
||||
<View style={itemStyle}>
|
||||
{this.props.renderItem(item)}
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { items, style, renderItem, spacing, fixed, itemWidth, ...props } = this.props;
|
||||
const { itemsPerRow } = this.state;
|
||||
|
||||
const rows = chunkArray(items, itemsPerRow);
|
||||
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
|
||||
|
||||
return (
|
||||
<ListView
|
||||
style={[{ paddingTop: spacing }, style]}
|
||||
onLayout={this.onLayout}
|
||||
dataSource={ds.cloneWithRows(rows)}
|
||||
renderRow={this.renderRow}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SuperGrid.propTypes = {
|
||||
renderItem: PropTypes.func.isRequired,
|
||||
items: PropTypes.arrayOf(PropTypes.any).isRequired,
|
||||
itemWidth: PropTypes.number,
|
||||
fixed: PropTypes.bool,
|
||||
spacing: PropTypes.number,
|
||||
style: View.propTypes.style,
|
||||
};
|
||||
|
||||
SuperGrid.defaultProps = {
|
||||
fixed: false,
|
||||
itemWidth: 120,
|
||||
spacing: 10,
|
||||
style: {},
|
||||
};
|
||||
|
||||
export default SuperGrid;
|
||||
34
package.json
Normal file
34
package.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "react-native-super-grid",
|
||||
"version": "1.0.2",
|
||||
"description": "Responsive Grid View for React Native",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/saleel97/react-native-super-grid.git"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react-native": ">=0.26.0"
|
||||
},
|
||||
"homepage": "https://github.com/saleel97/react-native-super-grid",
|
||||
"keywords": [
|
||||
"react",
|
||||
"native",
|
||||
"responsive",
|
||||
"super",
|
||||
"grid",
|
||||
"view"
|
||||
],
|
||||
"author": "Saleel",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-airbnb": "^14.1.0",
|
||||
"eslint-plugin-import": "^2.2.0",
|
||||
"eslint-plugin-jsx-a11y": "^4.0.0",
|
||||
"eslint-plugin-react": "^6.10.3"
|
||||
}
|
||||
}
|
||||
BIN
screenshots/android_landscape.png
Normal file
BIN
screenshots/android_landscape.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
BIN
screenshots/android_portrait.png
Normal file
BIN
screenshots/android_portrait.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
BIN
screenshots/ipadair2_landscape.png
Normal file
BIN
screenshots/ipadair2_landscape.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 161 KiB |
BIN
screenshots/ipadair2_portrait.png
Normal file
BIN
screenshots/ipadair2_portrait.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 284 KiB |
BIN
screenshots/iphone6_landscape.png
Normal file
BIN
screenshots/iphone6_landscape.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 163 KiB |
BIN
screenshots/iphone6_portrait.png
Normal file
BIN
screenshots/iphone6_portrait.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 178 KiB |
13
utils.js
Normal file
13
utils.js
Normal file
@@ -0,0 +1,13 @@
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export function chunkArray(array, size) {
|
||||
return array.reduce((acc, val) => {
|
||||
if (acc.length === 0) acc.push([]);
|
||||
const last = acc[acc.length - 1];
|
||||
if (last.length < size) {
|
||||
last.push(val);
|
||||
} else {
|
||||
acc.push([val]);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
}
|
||||
Reference in New Issue
Block a user