To have a mobile friendly Navbar that handles multiple Nav components use CollapsableNav. The toggleNavKey must still be set, however, the corresponding eventKey must now be on the CollapsableNav component.
+
To have a mobile friendly Navbar that handles multiple Nav components use CollapsibleNav. The toggleNavKey must still be set, however, the corresponding eventKey must now be on the CollapsibleNav component.
Div collapse
-
The navbar-collapse div gets created as the collapsable element which follows the bootstrap collapsable navbar documentation.
+
The navbar-collapse div gets created as the collapsible element which follows the bootstrap collapsible navbar documentation.
<div class="collapse navbar-collapse"></div>
-
+
{/* Tabbed Areas */}
diff --git a/docs/src/ReactPlayground.js b/docs/src/ReactPlayground.js
index 4a0c64cbaa..2aa45b8406 100644
--- a/docs/src/ReactPlayground.js
+++ b/docs/src/ReactPlayground.js
@@ -6,8 +6,8 @@ import * as modBadge from '../../src/Badge';
import * as modmodButton from '../../src/Button';
import * as modButtonGroup from '../../src/ButtonGroup';
import * as modmodButtonToolbar from '../../src/ButtonToolbar';
-import * as modCollapsableNav from '../../src/CollapsableNav';
-import * as modCollapsableMixin from '../../src/CollapsableMixin';
+import * as modCollapsibleNav from '../../src/CollapsibleNav';
+import * as modCollapsibleMixin from '../../src/CollapsibleMixin';
import * as modCarousel from '../../src/Carousel';
import * as modCarouselItem from '../../src/CarouselItem';
import * as modCol from '../../src/Col';
@@ -53,8 +53,8 @@ const Badge = modBadge.default;
const Button = modmodButton.default;
const ButtonGroup = modButtonGroup.default;
const ButtonToolbar = modmodButtonToolbar.default;
-const CollapsableNav = modCollapsableNav.default;
-const CollapsableMixin = modCollapsableMixin.default;
+const CollapsibleNav = modCollapsibleNav.default;
+const CollapsibleMixin = modCollapsibleMixin.default;
const Carousel = modCarousel.default;
const CarouselItem = modCarouselItem.default;
const Col = modCol.default;
diff --git a/docs/src/Samples.js b/docs/src/Samples.js
index 459943615e..004fe581d7 100644
--- a/docs/src/Samples.js
+++ b/docs/src/Samples.js
@@ -28,7 +28,7 @@ export default {
PanelGroupControlled: require('fs').readFileSync(__dirname + '/../examples/PanelGroupControlled.js', 'utf8'),
PanelGroupUncontrolled: require('fs').readFileSync(__dirname + '/../examples/PanelGroupUncontrolled.js', 'utf8'),
PanelGroupAccordion: require('fs').readFileSync(__dirname + '/../examples/PanelGroupAccordion.js', 'utf8'),
- CollapsableParagraph: require('fs').readFileSync(__dirname + '/../examples/CollapsableParagraph.js', 'utf8'),
+ CollapsibleParagraph: require('fs').readFileSync(__dirname + '/../examples/CollapsibleParagraph.js', 'utf8'),
ModalStatic: require('fs').readFileSync(__dirname + '/../examples/ModalStatic.js', 'utf8'),
ModalTrigger: require('fs').readFileSync(__dirname + '/../examples/ModalTrigger.js', 'utf8'),
ModalOverlayMixin: require('fs').readFileSync(__dirname + '/../examples/ModalOverlayMixin.js', 'utf8'),
@@ -52,8 +52,8 @@ export default {
NavJustified: require('fs').readFileSync(__dirname + '/../examples/NavJustified.js', 'utf8'),
NavbarBasic: require('fs').readFileSync(__dirname + '/../examples/NavbarBasic.js', 'utf8'),
NavbarBrand: require('fs').readFileSync(__dirname + '/../examples/NavbarBrand.js', 'utf8'),
- NavbarCollapsable: require('fs').readFileSync(__dirname + '/../examples/NavbarCollapsable.js', 'utf8'),
- CollapsableNav: require('fs').readFileSync(__dirname + '/../examples/CollapsableNav.js', 'utf8'),
+ NavbarCollapsible: require('fs').readFileSync(__dirname + '/../examples/NavbarCollapsible.js', 'utf8'),
+ CollapsibleNav: require('fs').readFileSync(__dirname + '/../examples/CollapsibleNav.js', 'utf8'),
TabbedAreaUncontrolled: require('fs').readFileSync(__dirname + '/../examples/TabbedAreaUncontrolled.js', 'utf8'),
TabbedAreaControlled: require('fs').readFileSync(__dirname + '/../examples/TabbedAreaControlled.js', 'utf8'),
TabbedAreaNoAnimation: require('fs').readFileSync(__dirname + '/../examples/TabbedAreaNoAnimation.js', 'utf8'),
diff --git a/src/CollapsableMixin.js b/src/CollapsableMixin.js
index 182843c34a..1aae543000 100644
--- a/src/CollapsableMixin.js
+++ b/src/CollapsableMixin.js
@@ -1,168 +1,38 @@
-import React from 'react';
-import TransitionEvents from 'react/lib/ReactTransitionEvents';
+import assign from './utils/Object.assign';
+import deprecationWarning from './utils/deprecationWarning';
+import CollapsibleMixin from './CollapsibleMixin';
-const CollapsableMixin = {
-
- propTypes: {
- defaultExpanded: React.PropTypes.bool,
- expanded: React.PropTypes.bool
- },
-
- getInitialState(){
- let defaultExpanded = this.props.defaultExpanded != null ?
- this.props.defaultExpanded :
- this.props.expanded != null ?
- this.props.expanded :
- false;
-
- return {
- expanded: defaultExpanded,
- collapsing: false
- };
- },
-
- componentWillUpdate(nextProps, nextState){
- let willExpanded = nextProps.expanded != null ? nextProps.expanded : nextState.expanded;
- if (willExpanded === this.isExpanded()) {
- return;
- }
-
- // if the expanded state is being toggled, ensure node has a dimension value
- // this is needed for the animation to work and needs to be set before
- // the collapsing class is applied (after collapsing is applied the in class
- // is removed and the node's dimension will be wrong)
-
- let node = this.getCollapsableDOMNode();
- let dimension = this.dimension();
- let value = '0';
-
- if(!willExpanded){
- value = this.getCollapsableDimensionValue();
- }
-
- node.style[dimension] = value + 'px';
-
- this._afterWillUpdate();
- },
-
- componentDidUpdate(prevProps, prevState){
- // check if expanded is being toggled; if so, set collapsing
- this._checkToggleCollapsing(prevProps, prevState);
-
- // check if collapsing was turned on; if so, start animation
- this._checkStartAnimation();
- },
-
- // helps enable test stubs
- _afterWillUpdate(){
- },
-
- _checkStartAnimation(){
- if(!this.state.collapsing) {
- return;
- }
-
- let node = this.getCollapsableDOMNode();
- let dimension = this.dimension();
- let value = this.getCollapsableDimensionValue();
-
- // setting the dimension here starts the transition animation
- let result;
- if(this.isExpanded()) {
- result = value + 'px';
- } else {
- result = '0px';
- }
- node.style[dimension] = result;
- },
-
- _checkToggleCollapsing(prevProps, prevState){
- let wasExpanded = prevProps.expanded != null ? prevProps.expanded : prevState.expanded;
- let isExpanded = this.isExpanded();
- if(wasExpanded !== isExpanded){
- if(wasExpanded) {
- this._handleCollapse();
- } else {
- this._handleExpand();
- }
- }
- },
-
- _handleExpand(){
- let node = this.getCollapsableDOMNode();
- let dimension = this.dimension();
-
- let complete = () => {
- this._removeEndEventListener(node, complete);
- // remove dimension value - this ensures the collapsable item can grow
- // in dimension after initial display (such as an image loading)
- node.style[dimension] = '';
- this.setState({
- collapsing:false
- });
- };
-
- this._addEndEventListener(node, complete);
-
- this.setState({
- collapsing: true
- });
- },
-
- _handleCollapse(){
- let node = this.getCollapsableDOMNode();
-
- let complete = () => {
- this._removeEndEventListener(node, complete);
- this.setState({
- collapsing: false
- });
- };
-
- this._addEndEventListener(node, complete);
-
- this.setState({
- collapsing: true
- });
- },
-
- // helps enable test stubs
- _addEndEventListener(node, complete){
- TransitionEvents.addEndEventListener(node, complete);
- },
-
- // helps enable test stubs
- _removeEndEventListener(node, complete){
- TransitionEvents.removeEndEventListener(node, complete);
- },
-
- dimension(){
- return (typeof this.getCollapsableDimension === 'function') ?
- this.getCollapsableDimension() :
- 'height';
- },
-
- isExpanded(){
- return this.props.expanded != null ? this.props.expanded : this.state.expanded;
- },
+let link = 'https://github.com/react-bootstrap/react-bootstrap/issues/425#issuecomment-97110963';
+const CollapsableMixin = assign({}, CollapsibleMixin, {
getCollapsableClassSet(className) {
- let classes = {};
-
- if (typeof className === 'string') {
- className.split(' ').forEach(subClasses => {
- if (subClasses) {
- classes[subClasses] = true;
- }
- });
- }
-
- classes.collapsing = this.state.collapsing;
- classes.collapse = !this.state.collapsing;
- classes.in = this.isExpanded() && !this.state.collapsing;
-
- return classes;
+ deprecationWarning(
+ 'CollapsableMixin.getCollapsableClassSet()',
+ 'CollapsibleMixin.getCollapsibleClassSet()',
+ link
+ );
+ return CollapsibleMixin.getCollapsibleClassSet.call(this, className);
+ },
+
+ getCollapsibleDOMNode() {
+ deprecationWarning(
+ 'CollapsableMixin.getCollapsableDOMNode()',
+ 'CollapsibleMixin.getCollapsibleDOMNode()',
+ link
+ );
+ return this.getCollapsableDOMNode();
+ },
+
+ getCollapsibleDimensionValue() {
+ deprecationWarning(
+ 'CollapsableMixin.getCollapsableDimensionValue()',
+ 'CollapsibleMixin.getCollapsibleDimensionValue()',
+ link
+ );
+ return this.getCollapsableDimensionValue();
}
-};
+});
+
+deprecationWarning('CollapsableMixin', 'CollapsibleMixin', link);
export default CollapsableMixin;
diff --git a/src/CollapsableNav.js b/src/CollapsableNav.js
index e0ca719dc1..cc211684f3 100644
--- a/src/CollapsableNav.js
+++ b/src/CollapsableNav.js
@@ -1,111 +1,12 @@
-import React, { cloneElement } from 'react';
-import BootstrapMixin from './BootstrapMixin';
-import CollapsableMixin from './CollapsableMixin';
-import classNames from 'classnames';
-import domUtils from './utils/domUtils';
+import deprecationWarning from './utils/deprecationWarning';
+import CollapsibleNav from './CollapsibleNav';
-import ValidComponentChildren from './utils/ValidComponentChildren';
-import createChainedFunction from './utils/createChainedFunction';
+let CollapsableNav = CollapsibleNav;
-const CollapsableNav = React.createClass({
- mixins: [BootstrapMixin, CollapsableMixin],
-
- propTypes: {
- onSelect: React.PropTypes.func,
- activeHref: React.PropTypes.string,
- activeKey: React.PropTypes.any,
- collapsable: React.PropTypes.bool,
- expanded: React.PropTypes.bool,
- eventKey: React.PropTypes.any
- },
-
- getCollapsableDOMNode() {
- return this.getDOMNode();
- },
-
- getCollapsableDimensionValue() {
- let height = 0;
- let nodes = this.refs;
- for (let key in nodes) {
- if (nodes.hasOwnProperty(key)) {
-
- let n = nodes[key].getDOMNode()
- , h = n.offsetHeight
- , computedStyles = domUtils.getComputedStyles(n);
-
- height += (h + parseInt(computedStyles.marginTop, 10) + parseInt(computedStyles.marginBottom, 10));
- }
- }
- return height;
- },
-
- render() {
- /*
- * this.props.collapsable is set in NavBar when a eventKey is supplied.
- */
- let classes = this.props.collapsable ? this.getCollapsableClassSet() : {};
- /*
- * prevent duplicating navbar-collapse call if passed as prop. kind of overkill... good cadidate to have check implemented as a util that can
- * also be used elsewhere.
- */
- if (this.props.className === undefined || this.props.className.split(' ').indexOf('navbar-collapse') === -2) {
- classes['navbar-collapse'] = this.props.collapsable;
- }
-
- return (
-