|
/* |
|
DISCLAIMER: This code is not optimized I just wanted to throw something together as a test to |
|
see if this would be better then the typical flow for handling element height change |
|
*/ |
|
|
|
var AnimateHeightComponent = React.createClass({ |
|
|
|
componentDidMount: function() { |
|
this.$container = $(this.refs.container.getDOMNode()); |
|
this.baseHeight = this.$container.innerHeight(); |
|
this.$container.css("height", this.baseHeight); |
|
}, |
|
|
|
componentDidUpdate: function(prevProps, prevState) { |
|
if (prevProps.children.length < this.props.children.length) { |
|
//if this is the first child only animate the difference |
|
if (prevProps.children.length == 0) { |
|
var childNumber = "item" + prevProps.children.length; |
|
var childHeight = $(this.refs[childNumber].getDOMNode()).height(); |
|
var heightDiff = childHeight - this.$container.height(); |
|
this.$container.animate({ |
|
"height": "+=" + heightDiff |
|
}, 150) |
|
} |
|
else { |
|
var childNumber = "item" + prevProps.children.length; |
|
var childHeight = $(this.refs[childNumber].getDOMNode()).outerHeight(true); |
|
this.$container.animate({ |
|
"height": "+=" + childHeight |
|
}, 150) |
|
} |
|
//save off the last childs height since we don't have access to it when the child |
|
//is deleted and we want to be able to animate the height change |
|
this.lastChildHeight = childHeight; |
|
} |
|
else { |
|
//we are are removing from the container animate the change, |
|
//but don't make it smaller then the base height. |
|
console.log(this.$container.height() - this.lastChildHeight, this.baseHeight); |
|
if (this.$container.height() - this.lastChildHeight < 0) { |
|
this.$container.animate({ |
|
"height": this.baseHeight |
|
}, 150) |
|
} |
|
else { |
|
this.$container.animate({ |
|
"height": "-=" + this.lastChildHeight |
|
}, 150) |
|
} |
|
|
|
} |
|
}, |
|
|
|
render: function() { |
|
return ( |
|
<div ref="container" className="dynamic-height-el"> |
|
{this.getChildren()} |
|
</div> |
|
); |
|
}, |
|
|
|
getChildren: function() { |
|
var children = this.props.children; |
|
if (children && children.length) { |
|
return React.Children.map(this.props.children, function(child, i) { |
|
return React.addons.cloneWithProps(child, { |
|
ref: "item"+i |
|
}); |
|
}); |
|
} |
|
return <i className="fa fa-arrows-v" />; |
|
} |
|
}); |
|
|
|
var Component = React.createClass({ |
|
|
|
getInitialState: function() { |
|
return { |
|
items: [] |
|
} |
|
}, |
|
|
|
addItem: function() { |
|
var itemPos = this.state.items.length; |
|
var newItem = ( |
|
<div key={'item-' + itemPos} className={'item item-' +itemPos}> |
|
<button className="remove-item-button" onClick={this.removeItem}> |
|
<i className="fa fa-times"></i> |
|
</button> |
|
</div> |
|
); |
|
this.setState({ |
|
items: this.state.items.concat([newItem]) |
|
}) |
|
}, |
|
|
|
removeItem: function() { |
|
this.state.items.pop(); |
|
this.setState({ |
|
items: this.state.items |
|
}) |
|
}, |
|
|
|
render: function() { |
|
return ( |
|
<div className="landing-page"> |
|
<div className="container"> |
|
<p className="title">Animate element height change <br/> When items are added</p> |
|
<AnimateHeightComponent> |
|
{this.state.items} |
|
</AnimateHeightComponent> |
|
<button className="add-child-button" onClick={this.addItem}> |
|
Add an element to container |
|
</button> |
|
</div> |
|
</div> |
|
); |
|
} |
|
}); |
|
|
|
React.render(<Component/>, $('#reactEl')[0]); |