From 942ba251d039a9413859209bb7d5a96972740a0e Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Mon, 9 Nov 2015 12:15:32 +0100 Subject: [PATCH 01/21] Moved React deps to devDependencies. Fixes #13 --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 9b199cd..443db61 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,7 @@ "license": "MIT", "dependencies": { "lodash.debounce": "^3.1.1", - "lodash.sortby": "^3.1.5", - "react": "0.14.0", - "react-dom": "0.14.0" + "lodash.sortby": "^3.1.5" }, "peerDependencies": { "react": "^0.14.0" @@ -27,6 +25,8 @@ "eslint-plugin-react": "^2.4.0", "lodash": "^3.10.1", "node-libs-browser": "^0.5.2", + "react": "^0.14.0", + "react-dom": "^0.14.0", "webpack": "^1.9.10", "webpack-dev-server": "^1.9.0" }, From 918e83d149a8289c287e602cac9b7bf22bfce3b0 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Mon, 9 Nov 2015 12:18:36 +0100 Subject: [PATCH 02/21] Added react-dom to peerDependencies --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 443db61..038262d 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "lodash.sortby": "^3.1.5" }, "peerDependencies": { - "react": "^0.14.0" + "react": "^0.14.0", + "react-dom": "^0.14.0" }, "devDependencies": { "babel-core": "^5.4.7", From 0a138185f5ceb890c2e46501cc9bfdbad8fd2cea Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Wed, 11 Nov 2015 11:36:59 +0100 Subject: [PATCH 03/21] Updated webpack and webpack-dev-server --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 038262d..d39831d 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,8 @@ "node-libs-browser": "^0.5.2", "react": "^0.14.0", "react-dom": "^0.14.0", - "webpack": "^1.9.10", - "webpack-dev-server": "^1.9.0" + "webpack": "^1.12.4", + "webpack-dev-server": "^1.12.1" }, "browserify": { "transform": [ From 8b21cdc523e84abcc92ecc173a425c0ea5541873 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Wed, 11 Nov 2015 11:48:58 +0100 Subject: [PATCH 04/21] Removed redundant var --- lib/AbsoluteGrid.jsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/AbsoluteGrid.jsx b/lib/AbsoluteGrid.jsx index 074b819..681fc0e 100644 --- a/lib/AbsoluteGrid.jsx +++ b/lib/AbsoluteGrid.jsx @@ -59,14 +59,12 @@ export default class AbsoluteGrid extends React.Component { var index = sortedIndex[key]; var style = layout.getStyle(index, this.props.animation, item[this.props.filterProp]); - var gridItem = React.cloneElement(this.props.displayObject, { + return React.cloneElement(this.props.displayObject, { ...this.props.displayObject.props, style, item, index, key, itemsLength: this.props.items.length, dragEnabled: this.props.dragEnabled, dragManager: this.dragManager }); - - return gridItem; }); var gridStyle = { From e20bc63e96c49bd3654c84cc7210300a99e78203 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Wed, 11 Nov 2015 11:51:22 +0100 Subject: [PATCH 05/21] Better code style. --- lib/AbsoluteGrid.jsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/AbsoluteGrid.jsx b/lib/AbsoluteGrid.jsx index 681fc0e..9db34c8 100644 --- a/lib/AbsoluteGrid.jsx +++ b/lib/AbsoluteGrid.jsx @@ -54,13 +54,17 @@ export default class AbsoluteGrid extends React.Component { } }); - var gridItems = this.props.items.map((item) => { + var gridItems = this.props.items.map(item => { var key = item[this.props.keyProp]; var index = sortedIndex[key]; var style = layout.getStyle(index, this.props.animation, item[this.props.filterProp]); return React.cloneElement(this.props.displayObject, { - ...this.props.displayObject.props, style, item, index, key, + ...this.props.displayObject.props, + style, + item, + index, + key, itemsLength: this.props.items.length, dragEnabled: this.props.dragEnabled, dragManager: this.dragManager From 2518a2635598d6ac946a8ff148d37522de7d04d9 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Wed, 11 Nov 2015 11:54:33 +0100 Subject: [PATCH 06/21] Use const and let instead of var --- lib/AbsoluteGrid.jsx | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/AbsoluteGrid.jsx b/lib/AbsoluteGrid.jsx index 9db34c8..18b95e7 100644 --- a/lib/AbsoluteGrid.jsx +++ b/lib/AbsoluteGrid.jsx @@ -28,17 +28,17 @@ export default class AbsoluteGrid extends React.Component { return
; } - var options = { + const options = { itemWidth: this.props.itemWidth, itemHeight: this.props.itemHeight, verticalMargin: this.props.verticalMargin, zoom: this.props.zoom }; - var layout = new LayoutManager(options, this.state.layoutWidth); + const layout = new LayoutManager(options, this.state.layoutWidth); - var filteredIndex = 0; - var sortedIndex = {}; + let filteredIndex = 0; + let sortedIndex = {}; /* If we actually sorted the array, React would re-render the DOM nodes @@ -46,18 +46,18 @@ export default class AbsoluteGrid extends React.Component { This also clears out filtered items from the sort order and eliminates gaps and duplicate sorts */ - sortBy(this.props.items, this.props.sortProp).forEach((item) => { + sortBy(this.props.items, this.props.sortProp).forEach(item => { if(!item[this.props.filterProp]){ - var key = item[this.props.keyProp]; + const key = item[this.props.keyProp]; sortedIndex[key] = filteredIndex; filteredIndex++; } }); - var gridItems = this.props.items.map(item => { - var key = item[this.props.keyProp]; - var index = sortedIndex[key]; - var style = layout.getStyle(index, this.props.animation, item[this.props.filterProp]); + const gridItems = this.props.items.map(item => { + const key = item[this.props.keyProp]; + const index = sortedIndex[key]; + const style = layout.getStyle(index, this.props.animation, item[this.props.filterProp]); return React.cloneElement(this.props.displayObject, { ...this.props.displayObject.props, @@ -71,7 +71,7 @@ export default class AbsoluteGrid extends React.Component { }); }); - var gridStyle = { + const gridStyle = { position: 'relative', display: 'block', height: layout.getTotalHeight(filteredIndex) @@ -106,7 +106,7 @@ export default class AbsoluteGrid extends React.Component { } getDOMWidth = () => { - var width = ReactDOM.findDOMNode(this).clientWidth; + const width = ReactDOM.findDOMNode(this).clientWidth; if(this.state.layoutWidth !== width){ this.setState({layoutWidth: width}); From a89b9dd9854bf4d7ebd901a0499836800a833ce8 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Wed, 11 Nov 2015 12:08:52 +0100 Subject: [PATCH 07/21] Removed this.running since it seems redundant. Closes #15 --- lib/AbsoluteGrid.jsx | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/lib/AbsoluteGrid.jsx b/lib/AbsoluteGrid.jsx index 18b95e7..456e09d 100644 --- a/lib/AbsoluteGrid.jsx +++ b/lib/AbsoluteGrid.jsx @@ -10,11 +10,8 @@ import sortBy from 'lodash.sortby'; export default class AbsoluteGrid extends React.Component { - running; - constructor(props){ super(props); - this.running = false; this.onResize = debounce(this.onResize, 150); this.dragManager = new DragManager(this.props.onMove, this.props.keyProp); this.state = { @@ -93,15 +90,10 @@ export default class AbsoluteGrid extends React.Component { } onResize = () => { - if (!this.running) { - this.running = true; - - if (window.requestAnimationFrame) { - window.requestAnimationFrame(this.getDOMWidth); - } else { - setTimeout(this.getDOMWidth, 66); - } - + if (window.requestAnimationFrame) { + window.requestAnimationFrame(this.getDOMWidth); + } else { + setTimeout(this.getDOMWidth, 66); } } From 33cc74fbc4d53868f0d5708cb9a0ec1209db7c7e Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Wed, 11 Nov 2015 12:13:33 +0100 Subject: [PATCH 08/21] Use ref instead of ReactDOM.findDOMNode. Removed react-dom from peerDependencies --- lib/AbsoluteGrid.jsx | 15 +++++++++++---- package.json | 3 +-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/AbsoluteGrid.jsx b/lib/AbsoluteGrid.jsx index 456e09d..41e48ff 100644 --- a/lib/AbsoluteGrid.jsx +++ b/lib/AbsoluteGrid.jsx @@ -1,7 +1,6 @@ 'use strict'; import React from 'react'; -import ReactDOM from 'react-dom'; import GridItem from './GridItem.jsx'; import LayoutManager from './LayoutManager.js'; import DragManager from './DragManager.js'; @@ -22,7 +21,7 @@ export default class AbsoluteGrid extends React.Component { render() { if(!this.state.layoutWidth || !this.props.items.length){ - return
; + return
this.container = node}>
; } const options = { @@ -74,7 +73,15 @@ export default class AbsoluteGrid extends React.Component { height: layout.getTotalHeight(filteredIndex) }; - return
{gridItems}
; + return ( +
this.container = node} + > + {gridItems} +
+ ); } componentDidMount() { @@ -98,7 +105,7 @@ export default class AbsoluteGrid extends React.Component { } getDOMWidth = () => { - const width = ReactDOM.findDOMNode(this).clientWidth; + const width = this.container && this.container.clientWidth; if(this.state.layoutWidth !== width){ this.setState({layoutWidth: width}); diff --git a/package.json b/package.json index d39831d..7a635ef 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,7 @@ "lodash.sortby": "^3.1.5" }, "peerDependencies": { - "react": "^0.14.0", - "react-dom": "^0.14.0" + "react": "^0.14.0" }, "devDependencies": { "babel-core": "^5.4.7", From 2b98deff12f33f0195bae0f8620e2f5f61d5f72f Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Wed, 11 Nov 2015 12:45:01 +0100 Subject: [PATCH 09/21] Use composition instead of class inheritance. Wrapping displayObject into BaseDisplayObject and passing props to it removes complexity. Now the displayObject is completely separated from grid component. It recieves `item` as prop. Closes #7 --- demo/SampleDisplay.jsx | 12 +++++++----- lib/AbsoluteGrid.jsx | 28 +++++++++++++++------------- lib/BaseDisplayObject.jsx | 23 ++++++++++++++--------- lib/GridItem.jsx | 16 ---------------- 4 files changed, 36 insertions(+), 43 deletions(-) delete mode 100644 lib/GridItem.jsx diff --git a/demo/SampleDisplay.jsx b/demo/SampleDisplay.jsx index 9ff33b7..f899218 100644 --- a/demo/SampleDisplay.jsx +++ b/demo/SampleDisplay.jsx @@ -1,14 +1,16 @@ 'use strict'; import React from 'react'; -import BaseDisplayObject from '../lib/BaseDisplayObject.jsx'; -export default class SampleDisplay extends BaseDisplayObject{ +export default class SampleDisplay extends React.Component { render() { - //IMPORTANT: Without the style, nothing happens :( - var itemStyle = super.getStyle.call(this); - itemStyle.backgroundImage = 'url(\'' + this.props.item.url + '\')'; + const itemStyle = { + display: 'block', + width: '100%', + height: '100%', + backgroundImage: `url('${this.props.item.url}')` + }; return
+ { React.cloneElement(this.props.displayObject, { ...this.props.displayObject.props, item }) } + + ); }); const gridStyle = { @@ -118,7 +121,7 @@ export default class AbsoluteGrid extends React.Component { AbsoluteGrid.propTypes = { items: React.PropTypes.arrayOf(React.PropTypes.object).isRequired, - displayObject: React.PropTypes.object, + displayObject: React.PropTypes.element.isRequired, itemWidth: React.PropTypes.number, itemHeight: React.PropTypes.number, verticalMargin: React.PropTypes.number, @@ -134,7 +137,6 @@ AbsoluteGrid.propTypes = { AbsoluteGrid.defaultProps = { items: [], - displayObject: , keyProp: 'key', filterProp: 'filtered', sortProp: 'sort', diff --git a/lib/BaseDisplayObject.jsx b/lib/BaseDisplayObject.jsx index a41695c..eb4da8b 100644 --- a/lib/BaseDisplayObject.jsx +++ b/lib/BaseDisplayObject.jsx @@ -5,12 +5,12 @@ import ReactDOM from 'react-dom'; export default class BaseDisplayObject extends React.Component { - constructor(){ + constructor() { super(); this.onDrag = this.onDrag.bind(this); } - updateDrag(x, y){ + updateDrag(x, y) { //Pause Animation lets our item return to a snapped position without being animated var pauseAnimation = false; if(!this.props.dragManager.dragItem){ @@ -26,20 +26,19 @@ export default class BaseDisplayObject extends React.Component { }); } - onDrag(e){ + onDrag(e) { if(this.props.dragManager){ var domNode = ReactDOM.findDOMNode(this); this.props.dragManager.startDrag(e, domNode, this.props.item, this.updateDrag.bind(this)); } } - getStyle(){ - + getStyle() { //If this is the object being dragged, return a different style - if(this.props.dragManager.dragItem === this.props.item){ + if (this.props.dragManager.dragItem === this.props.item) { var dragStyle = this.props.dragManager.getStyle(this.state.dragX, this.state.dragY); return {...this.props.style, ...dragStyle}; - }else if(this.state && this.state.pauseAnimation){ + } else if (this.state && this.state.pauseAnimation) { var pauseAnimationStyle = {...this.props.style}; pauseAnimationStyle.WebkitTransition = 'none'; pauseAnimationStyle.MozTransition = 'none'; @@ -51,7 +50,7 @@ export default class BaseDisplayObject extends React.Component { return this.props.style; } - componentDidMount(){ + componentDidMount() { if(this.props.dragEnabled){ ReactDOM.findDOMNode(this).addEventListener('mousedown', this.onDrag); ReactDOM.findDOMNode(this).addEventListener('touchstart', this.onDrag); @@ -59,9 +58,15 @@ export default class BaseDisplayObject extends React.Component { } } - componentWillUnmount(){ + componentWillUnmount() { this.props.dragManager.endDrag(); } + + render() { + return ( +
{ this.props.children }
+ ); + } } BaseDisplayObject.propTypes = { diff --git a/lib/GridItem.jsx b/lib/GridItem.jsx deleted file mode 100644 index e7a0cba..0000000 --- a/lib/GridItem.jsx +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -import React from 'react'; -import BaseDisplayObject from './BaseDisplayObject.jsx'; - -export default class GridItem extends BaseDisplayObject{ - - render() { - //IMPORTANT: Without the style, nothing happens :( - var itemStyle = super.getStyle.call(this); - - return
{this.props.item.name}
; - } -} From bfc3dfedc6fc5aa414d0e9c034451610ccb7208c Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Wed, 11 Nov 2015 12:48:42 +0100 Subject: [PATCH 10/21] Use ref instead of findDOMNode also in BaseDisplayObject. Removed react-dom dependency. --- lib/BaseDisplayObject.jsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/BaseDisplayObject.jsx b/lib/BaseDisplayObject.jsx index eb4da8b..c903c86 100644 --- a/lib/BaseDisplayObject.jsx +++ b/lib/BaseDisplayObject.jsx @@ -1,7 +1,6 @@ 'use strict'; import React from 'react'; -import ReactDOM from 'react-dom'; export default class BaseDisplayObject extends React.Component { @@ -28,8 +27,7 @@ export default class BaseDisplayObject extends React.Component { onDrag(e) { if(this.props.dragManager){ - var domNode = ReactDOM.findDOMNode(this); - this.props.dragManager.startDrag(e, domNode, this.props.item, this.updateDrag.bind(this)); + this.props.dragManager.startDrag(e, this.domNode, this.props.item, this.updateDrag.bind(this)); } } @@ -52,9 +50,9 @@ export default class BaseDisplayObject extends React.Component { componentDidMount() { if(this.props.dragEnabled){ - ReactDOM.findDOMNode(this).addEventListener('mousedown', this.onDrag); - ReactDOM.findDOMNode(this).addEventListener('touchstart', this.onDrag); - ReactDOM.findDOMNode(this).setAttribute('data-key', this.props.key); + this.domNode.addEventListener('mousedown', this.onDrag); + this.domNode.addEventListener('touchstart', this.onDrag); + this.domNode.setAttribute('data-key', this.props.key); } } @@ -64,7 +62,7 @@ export default class BaseDisplayObject extends React.Component { render() { return ( -
{ this.props.children }
+
this.domNode = node} style={this.getStyle()}>{ this.props.children }
); } } From 47529b02b42063b5ae9d6bc62889d7752ee3e9d9 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Wed, 11 Nov 2015 12:49:44 +0100 Subject: [PATCH 11/21] Added missing argument to setTimeout --- lib/BaseDisplayObject.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/BaseDisplayObject.jsx b/lib/BaseDisplayObject.jsx index c903c86..dad7888 100644 --- a/lib/BaseDisplayObject.jsx +++ b/lib/BaseDisplayObject.jsx @@ -16,7 +16,7 @@ export default class BaseDisplayObject extends React.Component { pauseAnimation = true; setTimeout(() => { this.setState({pauseAnimation: false}); - }); + }, 0); } this.setState({ dragX: x, From d0544c6ff5e5775df50d8b69766c738717a3143d Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Wed, 11 Nov 2015 12:50:49 +0100 Subject: [PATCH 12/21] Do a proper clean up in componentWillUnmount --- lib/BaseDisplayObject.jsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/BaseDisplayObject.jsx b/lib/BaseDisplayObject.jsx index dad7888..3bcb567 100644 --- a/lib/BaseDisplayObject.jsx +++ b/lib/BaseDisplayObject.jsx @@ -49,7 +49,7 @@ export default class BaseDisplayObject extends React.Component { } componentDidMount() { - if(this.props.dragEnabled){ + if (this.props.dragEnabled) { this.domNode.addEventListener('mousedown', this.onDrag); this.domNode.addEventListener('touchstart', this.onDrag); this.domNode.setAttribute('data-key', this.props.key); @@ -57,7 +57,11 @@ export default class BaseDisplayObject extends React.Component { } componentWillUnmount() { - this.props.dragManager.endDrag(); + if (this.props.dragEnabled) { + this.props.dragManager.endDrag(); + this.domNode.removeEventListener('mousedown', this.onDrag); + this.domNode.removeEventListener('touchstart', this.onDrag); + } } render() { From ca804e693f2a9f3b5757c50a703f4cb3faeaae54 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Wed, 11 Nov 2015 14:23:23 +0100 Subject: [PATCH 13/21] Don't use internal key attr. It will not be passed in props. --- lib/AbsoluteGrid.jsx | 1 + lib/BaseDisplayObject.jsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/AbsoluteGrid.jsx b/lib/AbsoluteGrid.jsx index d5d38d4..699ccee 100644 --- a/lib/AbsoluteGrid.jsx +++ b/lib/AbsoluteGrid.jsx @@ -60,6 +60,7 @@ export default class AbsoluteGrid extends React.Component { style={style} item={item} index={index} + id={key} key={key} itemsLength={this.props.items.length} dragEnabled={this.props.dragEnabled} diff --git a/lib/BaseDisplayObject.jsx b/lib/BaseDisplayObject.jsx index 3bcb567..83b9340 100644 --- a/lib/BaseDisplayObject.jsx +++ b/lib/BaseDisplayObject.jsx @@ -52,7 +52,7 @@ export default class BaseDisplayObject extends React.Component { if (this.props.dragEnabled) { this.domNode.addEventListener('mousedown', this.onDrag); this.domNode.addEventListener('touchstart', this.onDrag); - this.domNode.setAttribute('data-key', this.props.key); + this.domNode.setAttribute('data-key', this.props.id); } } From 53b2f7ff96e1941c2c1ff4d2efcce1b9bee27212 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Wed, 11 Nov 2015 14:31:34 +0100 Subject: [PATCH 14/21] Removed deprecation warning --- demo.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo.js b/demo.js index bfe1963..377f673 100644 --- a/demo.js +++ b/demo.js @@ -59,7 +59,7 @@ function demo() { var onMoveDebounced = _.debounce(onMove, 80); var unMountTest = function(){ - if(React.unmountComponentAtNode(document.getElementById('Demo'))){ + if(ReactDOM.unmountComponentAtNode(document.getElementById('Demo'))){ ReactDOM.render(, document.getElementById('UnmountButton')); }else{ render(); From 0e8a570145d49c1da034b7c422a4bf808c83d88c Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Thu, 12 Nov 2015 09:38:38 +0100 Subject: [PATCH 15/21] Pass context to super in AbsoluteGrid class. Removed constructor method in BaseDisplayObject. Use => instead. --- lib/AbsoluteGrid.jsx | 4 ++-- lib/BaseDisplayObject.jsx | 7 +------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/lib/AbsoluteGrid.jsx b/lib/AbsoluteGrid.jsx index 699ccee..ac07f13 100644 --- a/lib/AbsoluteGrid.jsx +++ b/lib/AbsoluteGrid.jsx @@ -9,8 +9,8 @@ import sortBy from 'lodash.sortby'; export default class AbsoluteGrid extends React.Component { - constructor(props){ - super(props); + constructor(props, context){ + super(props, context); this.onResize = debounce(this.onResize, 150); this.dragManager = new DragManager(this.props.onMove, this.props.keyProp); this.state = { diff --git a/lib/BaseDisplayObject.jsx b/lib/BaseDisplayObject.jsx index 83b9340..0e170d2 100644 --- a/lib/BaseDisplayObject.jsx +++ b/lib/BaseDisplayObject.jsx @@ -4,11 +4,6 @@ import React from 'react'; export default class BaseDisplayObject extends React.Component { - constructor() { - super(); - this.onDrag = this.onDrag.bind(this); - } - updateDrag(x, y) { //Pause Animation lets our item return to a snapped position without being animated var pauseAnimation = false; @@ -25,7 +20,7 @@ export default class BaseDisplayObject extends React.Component { }); } - onDrag(e) { + onDrag = (e) => { if(this.props.dragManager){ this.props.dragManager.startDrag(e, this.domNode, this.props.item, this.updateDrag.bind(this)); } From e6362853ffc4811d47b59e0d2ae1c5e1d3d99982 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Thu, 12 Nov 2015 10:02:47 +0100 Subject: [PATCH 16/21] Added build task and webpack config to compile as UMD library. Added pre-publish task. --- .gitignore | 1 + package.json | 13 +++++++------ webpack/build.config.js | 20 ++++++++++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 webpack/build.config.js diff --git a/.gitignore b/.gitignore index 9cf6fff..3881e74 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ +dist/ .idea diff --git a/package.json b/package.json index 7a635ef..761c173 100644 --- a/package.json +++ b/package.json @@ -2,18 +2,17 @@ "name": "react-absolute-grid", "version": "1.0.4", "description": "An absolutely positioned responsive touch-enabled fully configurable React grid with drag/drop, filtering, and sorting", - "main": "demos/index.html", + "main": "dist/index.js", "scripts": { + "build": "webpack --config webpack/build.config.js --optimize-minimize", "build-demo": "webpack --config 'webpack/demo.config.js' --optimize-minimize --content-base demo", "dev": "webpack-dev-server --config 'webpack/dev.config.js' --devtool eval --progress --colors --hot --content-base demo", - "lint": "eslint src" + "lint": "eslint lib", + "pre-publish": "npm run lint && npm run build" }, "author": "Jonathan Rowny", "license": "MIT", - "dependencies": { - "lodash.debounce": "^3.1.1", - "lodash.sortby": "^3.1.5" - }, + "dependencies": {}, "peerDependencies": { "react": "^0.14.0" }, @@ -24,6 +23,8 @@ "eslint": "^0.21.2", "eslint-plugin-react": "^2.4.0", "lodash": "^3.10.1", + "lodash.debounce": "^3.1.1", + "lodash.sortby": "^3.1.5", "node-libs-browser": "^0.5.2", "react": "^0.14.0", "react-dom": "^0.14.0", diff --git a/webpack/build.config.js b/webpack/build.config.js new file mode 100644 index 0000000..ac4a1ae --- /dev/null +++ b/webpack/build.config.js @@ -0,0 +1,20 @@ +module.exports = { + entry: './index.js', + output: { + path: './dist', + filename: 'index.js', + libraryTarget: 'umd', + library: 'AbsoluteGrid' + }, + module: { + loaders: [{ + test: /\.jsx?$/, // A regexp to test the require path. accepts either js or jsx + loader: 'babel' // The module to load. "babel" is short for "babel-loader" + }] + }, + externals: { + react: 'React' + } +}; + + From a0a1c8d55c3acc2a0f43a406ed31eb8a654661a7 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Thu, 12 Nov 2015 10:09:00 +0100 Subject: [PATCH 17/21] Use lodash with babel-plugin-lodash to slightly reduce dist size --- .babelrc | 3 ++- lib/AbsoluteGrid.jsx | 3 +-- package.json | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.babelrc b/.babelrc index 15d27ad..17ae582 100644 --- a/.babelrc +++ b/.babelrc @@ -1,4 +1,5 @@ { "stage": 0, - "loose": "all" + "loose": "all", + "plugins": ["lodash"] } diff --git a/lib/AbsoluteGrid.jsx b/lib/AbsoluteGrid.jsx index ac07f13..1c1e436 100644 --- a/lib/AbsoluteGrid.jsx +++ b/lib/AbsoluteGrid.jsx @@ -1,11 +1,10 @@ 'use strict'; import React from 'react'; +import { debounce, sortBy } from 'lodash'; import BaseStyleObject from './BaseDisplayObject.jsx'; import LayoutManager from './LayoutManager.js'; import DragManager from './DragManager.js'; -import debounce from 'lodash.debounce'; -import sortBy from 'lodash.sortby'; export default class AbsoluteGrid extends React.Component { diff --git a/package.json b/package.json index 761c173..6ed9679 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "An absolutely positioned responsive touch-enabled fully configurable React grid with drag/drop, filtering, and sorting", "main": "dist/index.js", "scripts": { - "build": "webpack --config webpack/build.config.js --optimize-minimize", + "build": "NODE_ENV=production webpack --config webpack/build.config.js --optimize-minimize", "build-demo": "webpack --config 'webpack/demo.config.js' --optimize-minimize --content-base demo", "dev": "webpack-dev-server --config 'webpack/dev.config.js' --devtool eval --progress --colors --hot --content-base demo", "lint": "eslint lib", @@ -20,11 +20,10 @@ "babel-core": "^5.4.7", "babel-eslint": "^3.1.9", "babel-loader": "^5.1.3", + "babel-plugin-lodash": "^0.2.0", "eslint": "^0.21.2", "eslint-plugin-react": "^2.4.0", "lodash": "^3.10.1", - "lodash.debounce": "^3.1.1", - "lodash.sortby": "^3.1.5", "node-libs-browser": "^0.5.2", "react": "^0.14.0", "react-dom": "^0.14.0", From 82a0d3f1e63801629b28e578ab9efe204c5f393a Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Thu, 12 Nov 2015 10:24:37 +0100 Subject: [PATCH 18/21] Proper task name --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6ed9679..1870f18 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "build-demo": "webpack --config 'webpack/demo.config.js' --optimize-minimize --content-base demo", "dev": "webpack-dev-server --config 'webpack/dev.config.js' --devtool eval --progress --colors --hot --content-base demo", "lint": "eslint lib", - "pre-publish": "npm run lint && npm run build" + "prepublish": "npm run lint && npm run build" }, "author": "Jonathan Rowny", "license": "MIT", From aceb7f6e8736c5f647c1a123c96f405c4b2f66fe Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Thu, 12 Nov 2015 10:24:51 +0100 Subject: [PATCH 19/21] Proper externals assignment --- webpack/build.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webpack/build.config.js b/webpack/build.config.js index ac4a1ae..3f3cb59 100644 --- a/webpack/build.config.js +++ b/webpack/build.config.js @@ -13,7 +13,7 @@ module.exports = { }] }, externals: { - react: 'React' + react: 'react' } }; From 400ae097851a0cf141a443a699f7488942b46c70 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Thu, 12 Nov 2015 10:41:08 +0100 Subject: [PATCH 20/21] Updated README + passing more props to displayObject --- README.md | 21 ++++++++------------- lib/AbsoluteGrid.jsx | 11 +++++++++-- lib/BaseDisplayObject.jsx | 1 + 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 9958ac1..7d8975e 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Options (Properties) | Property | Default | Description | |---|:---:|---| | **items** | [] | The array of items in the grid | -| **displayObject** | <GridItem/> | The React component used to display items | +| **displayObject** | (required) | The React component to render items | | **keyProp** | 'key' | The property to be used as a key | | **filterProp** | 'filtered' | The property to be used for filtering, if the filtered value is true, the item won't be displayed. It's important to not remove items from the array because that will cause React to remove the DOM, for performance we would rather hide it then remove it. | | **sortProp** | 'sort' | The property to sort on | @@ -39,26 +39,22 @@ Options (Properties) Creating a DisplayObject component ------ -Display objects will receive item, style, and index as properties. You must apply the style to the root element in your render. Here's the simplest possible example: - - 'use strict'; +displayObject component will receive `item`, `index` and `itemsLength` as props. Here's the simplest possible example: import React from 'react'; - import BaseDisplayObject from '../lib/BaseDisplayObject.jsx'; - - export default class SampleDisplay extends BaseDisplayObject{ + + export default class SampleDisplay extends React.Component { render() { - //IMPORTANT: Without the style, nothing happens :( - var itemStyle = super.getStyle.call(this); - return
; + // Supposing your item shape is something like {name: 'foo'} + const { item, index, itemsLength } = this.props; + return
Item {index} of {itemsLength}: {item.name}
; } } Once you've created a display object, use it like this: - var dispalyObject = (); - var grid = (); + var grid = ()}/>); What Makes AbsoluteGrid Unique? ---- @@ -70,7 +66,6 @@ Each GridItem component is passed the following props. | Property | Description | |---|:---| -| **style** | The inline styles that ReactAbsoluteGrid generates for the grid item. **NOTE**: Remember to apply to your GridItem element | | **item** | The data associated with the GridItem | | **index** | The index of the item data in the `items` array | | **itemsLength** | The total length of the `items` array | diff --git a/lib/AbsoluteGrid.jsx b/lib/AbsoluteGrid.jsx index 1c1e436..f8d9e68 100644 --- a/lib/AbsoluteGrid.jsx +++ b/lib/AbsoluteGrid.jsx @@ -49,6 +49,7 @@ export default class AbsoluteGrid extends React.Component { } }); + const itemsLength = this.props.items.length; const gridItems = this.props.items.map(item => { const key = item[this.props.keyProp]; const index = sortedIndex[key]; @@ -61,11 +62,17 @@ export default class AbsoluteGrid extends React.Component { index={index} id={key} key={key} - itemsLength={this.props.items.length} dragEnabled={this.props.dragEnabled} dragManager={this.dragManager} > - { React.cloneElement(this.props.displayObject, { ...this.props.displayObject.props, item }) } + { + React.cloneElement(this.props.displayObject, { + ...this.props.displayObject.props, + item, + index, + itemsLength + }) + } ); }); diff --git a/lib/BaseDisplayObject.jsx b/lib/BaseDisplayObject.jsx index 0e170d2..aaa5204 100644 --- a/lib/BaseDisplayObject.jsx +++ b/lib/BaseDisplayObject.jsx @@ -67,6 +67,7 @@ export default class BaseDisplayObject extends React.Component { } BaseDisplayObject.propTypes = { + id: React.PropTypes.any, item: React.PropTypes.object, style: React.PropTypes.object, index: React.PropTypes.number, From 295ba40f4418ce7da290aff9b6fad9f54ee0b065 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Thu, 12 Nov 2015 10:52:27 +0100 Subject: [PATCH 21/21] 2.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1870f18..15e6df5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-absolute-grid", - "version": "1.0.4", + "version": "2.0.0", "description": "An absolutely positioned responsive touch-enabled fully configurable React grid with drag/drop, filtering, and sorting", "main": "dist/index.js", "scripts": {