├── .gitignore ├── .npmignore ├── LICENSE ├── Makefile ├── README.md ├── examples ├── index.html └── index.js ├── package.json ├── src └── index.cjsx └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Deployed apps should consider commenting this line out: 24 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 25 | node_modules 26 | dist 27 | examples/bundle.js 28 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Deployed apps should consider commenting this line out: 24 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 25 | node_modules 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Kyle Mathews 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | BIN = ./node_modules/.bin 2 | 3 | release-patch: 4 | @$(call release,patch) 5 | 6 | release-minor: 7 | @$(call release,minor) 8 | 9 | release-major: 10 | @$(call release,major) 11 | 12 | build: 13 | @$(BIN)/cjsx -cb -o dist src/index.cjsx 14 | webpack 15 | 16 | publish: 17 | git push --tags origin HEAD:master 18 | @$(BIN)/cjsx -cb -o dist src/index.cjsx 19 | npm publish 20 | 21 | publish-gh-pages: 22 | git checkout gh-pages 23 | git merge master 24 | webpack 25 | cp examples/* . 26 | git add --all . 27 | git commit -m "New release" 28 | git push origin gh-pages 29 | git checkout master 30 | 31 | define release 32 | npm version $(1) 33 | endef 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | react-simple-table 2 | ================== 3 | 4 | For when you just want a table and not sorting, filtering, pagination, 5 | infinite scroll, ajax loading, etc. etc. etc. 6 | 7 | ## Install 8 | `npm install react-simple-table` 9 | 10 | ## Usage 11 | `react-simple-table` takes two props `data` and `columns`. 12 | 13 | ````javascript 14 | var SimpleTable = require('react-simple-table'); 15 | var React = require('react'); 16 | 17 | var fruitColors = [{ 18 | apple: 'Green', 19 | peach: 'Yellow', 20 | cherry: 'Red' 21 | }]; 22 | 23 | React.renderComponent({ 24 | render: function() { 25 | return ( 26 | 27 | ) 28 | } 29 | }); 30 | 31 | // For deeper data structures, you can specify the "path" to your values 32 | // using dot-notation strings. 33 | 34 | var deeperFruitColors = [{ 35 | apple: { 36 | color: 'Green' 37 | }, 38 | peach: { 39 | color: 'Yellow' 40 | }, 41 | cherry: { 42 | 'Red' 43 | } 44 | }]; 45 | 46 | React.renderComponent({ 47 | render: function() { 48 | return ( 49 | 54 | ) 55 | } 56 | }); 57 | 58 | // You can also pass in a function and do whatever you'd like. 59 | React.renderComponent({ 60 | render: function() { 61 | return ( 62 | 67 | {row.peach.color} 68 | 69 | ) 70 | }} 71 | {columnHeader: 'cherry', format: function(row) { 72 | return row.cherry.color + " yeah!" 73 | } 74 | } 75 | ]}, data={deeperFruitColors} /> 76 | ) 77 | } 78 | }); 79 | ```` 80 | 81 | ## Styling 82 | Tables by default have a `react-simple-table` class added. You can pass 83 | in custom class names as a string using the `className` prop. 84 | 85 | ## Demo 86 | http://kyleamathews.github.io/react-simple-table/ 87 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Example 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/index.js: -------------------------------------------------------------------------------- 1 | var SimpleTable = require('../src/index'); 2 | var React = require('react'); 3 | var ReactDOM = require('react-dom'); 4 | var faker = require('faker'); 5 | 6 | var fruitColors = [{ 7 | lime: 'Green', 8 | lemon: 'Yellow', 9 | orange:'Orange' 10 | }]; 11 | 12 | var fakeBizData = []; 13 | for (var i = 0; i < 9; i++) { 14 | newObject = { 15 | company: faker.company.companyName(), 16 | sales: faker.random.number(100,600), 17 | revenue: faker.random.number(1000,100000), 18 | profit: faker.random.number(1000,10000) 19 | }; 20 | fakeBizData.push(newObject); 21 | } 22 | 23 | var fakeContactData = []; 24 | for (var i = 0; i < 9; i++) { 25 | fakeContactData.push(faker.helpers.createCard()); 26 | } 27 | console.log(fakeContactData); 28 | 29 | ReactDOM.render( 30 | React.DOM.div({style:{margin:'0 auto', width: '500px'}}, 31 | [ 32 | React.DOM.h1(null, "React-Simple-Table"), 33 | React.DOM.a({href:"https://github.com/KyleAMathews/react-simple-table"}, "Browse code on Github"), 34 | React.DOM.br(), 35 | React.DOM.br(), 36 | React.DOM.br(), 37 | 38 | React.DOM.code(null, ""), 39 | React.DOM.br(), 40 | React.DOM.br(), 41 | React.createElement(SimpleTable, {className: "test-class", columns: ['Lime', 'Lemon', 'Orange'], data: fruitColors}), 42 | React.DOM.br(), 43 | React.DOM.br(), 44 | React.DOM.hr(), 45 | React.DOM.br(), 46 | React.DOM.br(), 47 | 48 | React.DOM.code(null, ""), 49 | React.DOM.br(), 50 | React.DOM.br(), 51 | React.createElement(SimpleTable, {columns: ['Company', 'Sales', 'Revenue', 'Profit'], data: fakeBizData}), 52 | 53 | React.DOM.br(), 54 | React.DOM.br(), 55 | React.DOM.hr(), 56 | React.DOM.br(), 57 | React.DOM.br(), 58 | React.DOM.h2(null, "Access deep data using dot-notation"), 59 | React.DOM.code(null, ""), 60 | React.DOM.br(), 61 | React.DOM.br(), 62 | React.createElement(SimpleTable, {columns: ['Name', 'Email', {displayName: 'Company', path: 'company.name'}], data: fakeContactData}), 63 | 64 | React.DOM.br(), 65 | React.DOM.br(), 66 | React.DOM.hr(), 67 | React.DOM.br(), 68 | React.DOM.br(), 69 | React.DOM.h2(null, "Access or manipulate data using a function"), 70 | React.DOM.code(null, ""), 71 | React.DOM.br(), 72 | React.DOM.br(), 73 | React.createElement(SimpleTable, {columns: ['Name', 'Email', {displayName: 'Address', function: function(data){return data.address.streetA + ", " + data.address.city}}], data: fakeContactData}), 74 | 75 | ]), document.body); 76 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-simple-table", 3 | "description": "For when you just want a table", 4 | "version": "1.0.1", 5 | "author": "Kyle Mathews ", 6 | "bugs": { 7 | "url": "https://github.com/KyleAMathews/react-simple-table/issues" 8 | }, 9 | "devDependencies": { 10 | "cjsx-loader": "^3.0.0", 11 | "coffee-loader": "^0.7.2", 12 | "coffee-react": "^5.0.0", 13 | "coffee-script": "^1.9.0", 14 | "css-loader": "^0.23.1", 15 | "faker": "^3.1.0", 16 | "react": "^15.0.2", 17 | "react-dom": "^15.0.1", 18 | "style-loader": "^0.13.1", 19 | "webpack": "^1.13.0" 20 | }, 21 | "homepage": "https://github.com/KyleAMathews/react-simple-table", 22 | "keywords": [ 23 | "react", 24 | "react-component", 25 | "table" 26 | ], 27 | "license": "MIT", 28 | "main": "dist/index.js", 29 | "peerDependencies": { 30 | "react": ">=0.11.0" 31 | }, 32 | "repository": { 33 | "type": "git", 34 | "url": "https://github.com/KyleAMathews/react-simple-table.git" 35 | }, 36 | "scripts": { 37 | "test": "echo \"Error: no test specified\" && exit 1" 38 | }, 39 | "dependencies": { 40 | "deep-get-set": "^1.0.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/index.cjsx: -------------------------------------------------------------------------------- 1 | React = require 'react' 2 | deep = require 'deep-get-set' 3 | 4 | module.exports = React.createClass 5 | displayName: "SimpleTable" 6 | 7 | propTypes: 8 | columns: React.PropTypes.array.isRequired 9 | data: React.PropTypes.array.isRequired 10 | className: React.PropTypes.string 11 | 12 | getDefaultProps: -> 13 | className: 'react-simple-table' 14 | 15 | render: -> 16 | columns = @props.columns.map (column) -> 17 | if typeof column is "string" 18 | {column} 19 | else 20 | {column.columnHeader} 21 | 22 | body = @props.data.map (rowData, i) => 23 | row = [] 24 | for column, colIndex in @props.columns 25 | # Columns can either be a simple string or be an object that defines 26 | # both a columnHeader and path for accessing the data. 27 | 28 | # TODO check if more performant to try to tie key to its data 29 | # e.g. use row.id instead of "i". Theory being that React could move 30 | # more elements around instead of destroying and recreating. 31 | # Test this with a 10000 row table when working on sorting. 32 | if typeof column is "string" 33 | datum = deep(rowData, column) 34 | key = i + "-" + column 35 | else if column.path? 36 | datum = deep(rowData, column.path) 37 | key = i + "-" + column.path 38 | else if column.format? 39 | datum = column.format(rowData) 40 | key = i + "-" + colIndex 41 | row.push {datum} 42 | return {row} 43 | 44 | return ( 45 | 46 | 47 | {columns} 48 | 49 | {body} 50 |
51 | ) 52 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | 4 | 5 | module.exports = { 6 | entry: [ 7 | './examples/index' 8 | ], 9 | output: { 10 | path: path.join(__dirname, 'examples'), 11 | filename: 'bundle.js', 12 | }, 13 | resolveLoader: { 14 | modulesDirectories: ['node_modules'] 15 | }, 16 | resolve: { 17 | extensions: ['', '.js', '.cjsx', '.coffee'] 18 | }, 19 | plugins: [ 20 | //new webpack.DefinePlugin({'process.env.NODE_ENV': '"production"'}), 21 | //new webpack.optimize.UglifyJsPlugin() 22 | ], 23 | module: { 24 | loaders: [ 25 | { test: /\.css$/, loaders: ['style', 'css']}, 26 | { test: /\.cjsx$/, loaders: ['coffee', 'cjsx']}, 27 | { test: /\.coffee$/, loader: 'coffee' } 28 | ] 29 | } 30 | }; 31 | --------------------------------------------------------------------------------