diff --git a/src/components/decorators.js b/src/components/decorators.js index 0ebe13f..30f6c44 100644 --- a/src/components/decorators.js +++ b/src/components/decorators.js @@ -62,11 +62,12 @@ class Container extends React.Component { super(props); } render(){ - const {style, decorators, terminal, onClick, node} = this.props; + const {style, decorators, terminal, onClick,onDoubleClick, node} = this.props; return (
{ !terminal ? this.renderToggle() : null } @@ -46,7 +47,8 @@ NodeHeader.propTypes = { React.PropTypes.bool ]).isRequired, node: React.PropTypes.object.isRequired, - onClick: React.PropTypes.func + onClick: React.PropTypes.func, + onDoubleClick : React.PropTypes.func }; export default NodeHeader; diff --git a/src/components/node.js b/src/components/node.js index 16393aa..5953d8c 100644 --- a/src/components/node.js +++ b/src/components/node.js @@ -9,12 +9,17 @@ class TreeNode extends React.Component { constructor(props){ super(props); this.onClick = this.onClick.bind(this); + this.onDoubleClick = this.onDoubleClick.bind(this); } onClick(){ let toggled = !this.props.node.toggled; let onToggle = this.props.onToggle; if(onToggle){ onToggle(this.props.node, toggled); } } + onDoubleClick(){ + let onDblClick = this.props.onDblClick; + if(onDblClick){ onDblClick(this.props.node); } + } animations(){ const props = this.props; if(props.animations === false){ return false; } @@ -60,6 +65,7 @@ class TreeNode extends React.Component { style={this.props.style} node={Object.assign({}, this.props.node)} onClick={this.onClick} + onDoubleClick={this.onDoubleClick} /> ); } @@ -92,7 +98,9 @@ class TreeNode extends React.Component { ); } _eventBubbles(){ - return { onToggle: this.props.onToggle }; + return { onToggle: this.props.onToggle , + onDblClick : this.props.onDblClick + }; } } @@ -104,7 +112,8 @@ TreeNode.propTypes = { React.PropTypes.object, React.PropTypes.bool ]).isRequired, - onToggle: React.PropTypes.func + onToggle: React.PropTypes.func, + onDblClick: React.PropTypes.func }; export default TreeNode; diff --git a/src/components/treebeard.js b/src/components/treebeard.js index 7573f55..5fa4971 100644 --- a/src/components/treebeard.js +++ b/src/components/treebeard.js @@ -22,6 +22,7 @@ class TreeBeard extends React.Component { key={node.id || index} node={node} onToggle={this.props.onToggle} + onDblClick={this.props.onDblClick} animations={this.props.animations} decorators={this.props.decorators} style={this.props.style.tree.node} @@ -43,6 +44,7 @@ TreeBeard.propTypes = { React.PropTypes.bool ]), onToggle: React.PropTypes.func, + onDblClick: React.PropTypes.func, decorators: React.PropTypes.object }; diff --git a/test/src/components/decorator-tests.js b/test/src/components/decorator-tests.js index 248c4a9..5cfe09e 100644 --- a/test/src/components/decorator-tests.js +++ b/test/src/components/decorator-tests.js @@ -15,7 +15,8 @@ const defaults = { animations: { toggle: {} }, terminal: false, decorators: factory.createDecorators(), - onClick: function(){} + onClick: function(){}, + onDoubleClick: function(){} }; const Container = defaultDecorators.Container; @@ -33,6 +34,18 @@ describe('container decorator component', () => { onClick.should.be.called.once; }); + it('should render a clickable element with a doubleClick event handler', () => { + const onDoubleClick = sinon.spy(); + const container = TestUtils.renderIntoDocument( + + ); + const clickable = container.refs.clickable; + TestUtils.Simulate.doubleClick(clickable); + onDoubleClick.should.be.called.once; + }); + it('should render the toggle decorator not terminal', () => { const toggleType = React.createClass({ render: () =>
}); const decorators = factory.createDecorators({ toggle: toggleType }); diff --git a/test/src/components/node-tests.js b/test/src/components/node-tests.js index 2120965..631e9bb 100644 --- a/test/src/components/node-tests.js +++ b/test/src/components/node-tests.js @@ -52,6 +52,18 @@ describe('node component', () => { onToggle.should.be.called.once; }); + it('should call the onDblClick callback once if it is registered on doubleClick', () => { + const onDblClick = sinon.spy(); + const treeNode = TestUtils.renderIntoDocument( + + ); + treeNode.onDoubleClick(); + onDblClick.should.be.called.once; + }); + it('should not throw an exception if a callback is not registered on click', () => { const treeNode = TestUtils.renderIntoDocument( diff --git a/test/src/components/treebeard-tests.js b/test/src/components/treebeard-tests.js index 7f3b35b..53982cf 100644 --- a/test/src/components/treebeard-tests.js +++ b/test/src/components/treebeard-tests.js @@ -104,4 +104,16 @@ describe('treebeard component', () => { element.dataset.reactid.should.contain(expectedId); }); + it('should pass the top level tree node the onDblClick props', () => { + const treebeard = TestUtils.renderIntoDocument( + {}} + /> + ); + const node = TestUtils.findRenderedComponentWithType(treebeard, TreeNode); + node.props.node.should.equal(treebeard.props.data); + node.props.onDblClick.should.equal(treebeard.props.onDblClick); + }); + });