diff --git a/README.md b/README.md index 189be1b..f1d2796 100644 --- a/README.md +++ b/README.md @@ -255,6 +255,13 @@ The `style` property is used to set the style of a Pane component. ## Changelog +### V0.5.0 + +- Fixes a nasty bug +- Add isResizable props to Pane component +- Set `user-select: none` when resizeing or moving. +- update example + ### V0.4.1 - Fixes a nasty bug where all Panes could end up sharing the same static style #44 (thanks @ara4n) diff --git a/example/index.html b/example/index.html index e77d1c9..5fea6bc 100644 --- a/example/index.html +++ b/example/index.html @@ -1,25 +1,70 @@ - - - React-resizable-and-movable example - - - + + + react-sortable-pane example + + + + + + +
+ + + diff --git a/example/src/example.js b/example/src/example.js index 2059b3c..58ec217 100644 --- a/example/src/example.js +++ b/example/src/example.js @@ -1,15 +1,12 @@ import React, { Component } from 'react'; import { SortablePane, Pane } from '../../src'; +import { Button } from 're-bulma'; const style = { fontSize: '40px', textAlign: 'center', - paddingTop: '60px', - paddingRight: '60px', - height: '400px', - border: 'solid 1px #ccc', borderRadius: '5px', - backgroundColor: '#fff', + padding: '15px', }; export default class Example extends Component { @@ -22,43 +19,46 @@ export default class Example extends Component { - 1 + no1
resize or sort me!!
, - 2 + no2
resize or sort me!!
, - 3 + no3
resize or sort me!!
, ], }; this.add = ::this.add; this.remove = ::this.remove; this.onResize = ::this.onResize; - setInterval(() => this.setState({ order: this.state.order.map(order => (order + 1) % 3) }), 1000); + // setInterval(() => this.setState({ order: this.state.order.map(order => (order + 1) % 3) }), 1000); } onResize(i) { @@ -70,13 +70,14 @@ export default class Example extends Component { - {this.id} + no{this.id}
resize or sort me!!
)); this.setState({ list: this.state.list }); @@ -90,11 +91,29 @@ export default class Example extends Component { render() { return (
- add - remove +

sortable pane

+ + console.dir(pane)} order={this.state.order} diff --git a/package.json b/package.json index d0999bc..4f3ae20 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-sortable-pane", - "version": "0.4.1", + "version": "0.5.0", "description": "", "main": "lib/index.js", "scripts": { @@ -52,22 +52,8 @@ "eslint": "^2.7.0", "eslint-config-airbnb": "^6.2.0", "eslint-plugin-react": "^4.2.0", - "espower-babel": "^3.3.0", - "espower-loader": "^1.0.0", - "espowerify": "^1.0.0", - "estraverse": "^4.1.1", - "estraverse-fb": "^1.3.1", "husky": "^0.11.4", - "intelli-espower-loader": "^1.0.0", - "karma": "^0.13.19", - "karma-browserify": "^4.4.0", - "karma-cli": "^0.1.1", - "karma-mocha": "^0.2.0", - "karma-phantomjs-launcher": "^0.2.1", - "mocha": "^2.3.3", - "phantomjs": "^1.9.18", - "phantomjs-polyfill": "^0.0.1", - "power-assert": "^1.1.0", + "re-bulma": "0.0.5", "react": "^15.0.1", "react-addons-test-utils": "^15.0.1", "sinon": "^1.17.2", @@ -83,7 +69,7 @@ ], "dependencies": { "lodash.isequal": "^4.1.1", - "react-motion": "^0.4.3", - "react-resizable-box": "^1.2.1" + "react-motion": "^0.4.4", + "react-resizable-box": "^1.3.2" } } diff --git a/screenshot/screenshot.gif b/screenshot/screenshot.gif index 7e11583..012d43b 100644 Binary files a/screenshot/screenshot.gif and b/screenshot/screenshot.gif differ diff --git a/src/index.js b/src/index.js index 08b9bf4..80937df 100644 --- a/src/index.js +++ b/src/index.js @@ -31,12 +31,8 @@ class SortablePane extends Component { onOrderChange: PropTypes.func, className: PropTypes.string, disableEffect: PropTypes.bool, - isResizable: PropTypes.shape({ - x: React.PropTypes.bool, - y: React.PropTypes.bool, - xy: React.PropTypes.bool, - }), isSortable: PropTypes.bool, + zIndex: PropTypes.number, }; static defaultProps = { @@ -54,12 +50,8 @@ class SortablePane extends Component { customStyle: {}, className: '', disableEffect: false, - isResizable: { - x: true, - y: true, - xy: true, - }, isSortable: true, + zIndex: 100, }; constructor(props) { @@ -77,7 +69,6 @@ class SortablePane extends Component { order, })), }; - this.hasAdded = false; this.sizePropsUpdated = false; this.handleTouchMove = ::this.handleTouchMove; this.handleMouseUp = ::this.handleMouseUp; @@ -113,23 +104,16 @@ class SortablePane extends Component { } } - componentWillUpdate(next) { + componentDidUpdate(next) { const { panes } = this.state; if (next.children.length > panes.length) return this.addPane(next); if (next.children.length < panes.length) return this.removePane(next); - return null; - } - - componentDidUpdate() { - if (this.hasAdded) { - this.hasAdded = false; - this.setSize(); - } if (this.sizePropsUpdated) { this.sizePropsUpdated = false; this.setSize(); } + return null; } componentWillUnmount() { @@ -144,9 +128,10 @@ class SortablePane extends Component { const order = this.getPanePropsArrayOf('order'); panes = panes.map((pane, index) => { if (order.indexOf(i) === index) { + const { offsetWidth, offsetHeight } = this.refs.panes.children[i]; return { - width: rect.width, - height: rect.height, + width: offsetWidth, + height: offsetHeight, order: pane.order, id: pane.id, }; @@ -235,11 +220,11 @@ class SortablePane extends Component { setSize() { const panes = this.props.children.map((child, i) => { - const { width, height } = this.refs.panes.children[i].getBoundingClientRect(); + const { offsetWidth, offsetHeight } = this.refs.panes.children[i]; return { id: child.props.id, - width, - height, + width: offsetWidth, + height: offsetHeight, order: i, }; }); @@ -273,13 +258,13 @@ class SortablePane extends Component { const ids = this.state.panes.map(pane => pane.id); if (ids.indexOf(child.props.id) === -1) { newPanes = this.updateOrder(newPanes, i, 'add'); - const { id, width, height } = child.props; + const { id } = child.props; + const { width, height } = this.refs.panes.children[i].getBoundingClientRect(); const pane = { id, width, height, order: i }; newPanes.splice(i, 0, pane); } }); this.setState({ panes: newPanes }); - this.hasAdded = true; } removePane(next) { @@ -343,6 +328,7 @@ class SortablePane extends Component { } handleMouseUp() { + if (this.props.children.length === 0) return; this.setState({ isPressed: false, delta: 0 }); this.props.children[this.state.lastPressed].props.onDragEnd(); const lastPressedId = this.props.children[this.state.lastPressed].props.id; @@ -350,9 +336,9 @@ class SortablePane extends Component { } renderPanes() { - const { mouse, isPressed, lastPressed } = this.state; + const { mouse, isPressed, lastPressed, isResizing } = this.state; const order = this.getPanePropsArrayOf('order'); - const { children, disableEffect, isSortable } = this.props; + const { children, disableEffect, isSortable, zIndex } = this.props; return children.map((child, i) => { const springPosition = spring(this.getItemPositionByIndex(order.indexOf(i)), springConfig); const style = lastPressed === i && isPressed @@ -376,6 +362,18 @@ class SortablePane extends Component { const onTouchStart = this.handleTouchStart.bind(this, i, x, y); const onResizeStart = this.handleResizeStart.bind(this, i); const onResizeStop = this.handleResizeStop.bind(this, i); + const userSelect = (isPressed || isResizing) + ? { + userSelect: 'none', + MozUserSelect: 'none', + WebkitUserSelect: 'none', + MsUserSelect: 'none', + } : { + userSelect: 'auto', + MozUserSelect: 'auto', + WebkitUserSelect: 'auto', + MsUserSelect: 'auto', + }; // take a copy rather than direct-manipulating the child's prop, which violates React // and causes problems if the child's prop is a static default {}, which then will be @@ -387,8 +385,9 @@ class SortablePane extends Component { WebkitTransform: `translate3d(${x}px, ${y}px, 0px) scale(${scale})`, MozTransform: `translate3d(${x}px, ${y}px, 0px) scale(${scale})`, MsTransform: `translate3d(${x}px, ${y}px, 0px) scale(${scale})`, - zIndex: i === lastPressed ? 99 : i, // TODO: Add this.props.zIndex + zIndex: i === lastPressed ? zIndex + children.length : zIndex + i, position: 'absolute', + ...userSelect, }); return ( @@ -397,9 +396,9 @@ class SortablePane extends Component { onResize={onResize} isResizable={{ top: false, - right: this.props.isResizable.x, - bottomRight: this.props.isResizable.xy, - bottom: this.props.isResizable.y, + right: child.props.isResizable.x, + bottomRight: child.props.isResizable.xy, + bottom: child.props.isResizable.y, left: false, topRight: false, bottomLeft: false, diff --git a/src/pane.js b/src/pane.js index f5beae7..ebe9cca 100644 --- a/src/pane.js +++ b/src/pane.js @@ -23,6 +23,11 @@ export default class Pane extends Component { style: PropTypes.object, className: PropTypes.string, children: PropTypes.any, + isResizable: PropTypes.shape({ + x: React.PropTypes.bool, + y: React.PropTypes.bool, + xy: React.PropTypes.bool, + }), }; static defaultProps = { @@ -30,6 +35,11 @@ export default class Pane extends Component { onDragEnd: () => null, style: {}, className: '', + isResizable: { + x: true, + y: true, + xy: true, + }, }; render() {