Skip to content
1 change: 1 addition & 0 deletions packages/react-bootstrap-table2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
],
"dependencies": {
"classnames": "2.2.5",
"react-transition-group": "^2.5.3",
"underscore": "1.9.1"
},
"peerDependencies": {
Expand Down
35 changes: 27 additions & 8 deletions packages/react-bootstrap-table2/src/contexts/row-expand-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,56 @@ class RowExpandProvider extends React.Component {
children: PropTypes.node.isRequired,
data: PropTypes.array.isRequired,
keyField: PropTypes.string.isRequired
}
};

state = { expanded: this.props.expandRow.expanded || [] };
state = { expanded: this.props.expandRow.expanded || [],
isClosing: this.props.expandRow.isClosing || [] };

componentWillReceiveProps(nextProps) {
if (nextProps.expandRow) {
const isClosing = this.state.expanded.reduce((acc, cur) => {
if (!nextProps.expandRow.expanded.includes(cur)) {
acc.push(cur);
}
return acc;
}, []);
this.setState(() => ({ expanded: nextProps.expandRow.expanded, isClosing }));
} else {
this.setState(() => ({
expanded: nextProps.expandRow.expanded || this.state.expanded
expanded: this.state.expanded
}));
}
}

onClosed = (closedRow) => {
this.setState({ isClosing: this.state.isClosing.filter(value => value !== closedRow) });
};

handleRowExpand = (rowKey, expanded, rowIndex, e) => {
const { data, keyField, expandRow: { onExpand, onlyOneExpanding, nonExpandable } } = this.props;
if (nonExpandable && nonExpandable.includes(rowKey)) {
return;
}

let currExpanded = [...this.state.expanded];
let isClosing = [...this.state.isClosing];

if (expanded) {
if (onlyOneExpanding) currExpanded = [rowKey];
else currExpanded.push(rowKey);
if (onlyOneExpanding) {
isClosing = isClosing.concat(currExpanded);
currExpanded = [rowKey];
} else currExpanded.push(rowKey);
} else {
isClosing.push(rowKey);
currExpanded = currExpanded.filter(value => value !== rowKey);
}

if (onExpand) {
const row = dataOperator.getRowByRowId(data, keyField, rowKey);
onExpand(row, expanded, rowIndex, e);
}
this.setState(() => ({ expanded: currExpanded }));
}
this.setState(() => ({ expanded: currExpanded, isClosing }));
};

handleAllRowExpand = (e, expandAll) => {
const {
Expand All @@ -68,7 +85,7 @@ class RowExpandProvider extends React.Component {
}

this.setState(() => ({ expanded: currExpanded }));
}
};

render() {
const { data, keyField } = this.props;
Expand All @@ -78,6 +95,8 @@ class RowExpandProvider extends React.Component {
...this.props.expandRow,
nonExpandable: this.props.expandRow.nonExpandable,
expanded: this.state.expanded,
isClosing: this.state.isClosing,
onClosed: this.onClosed,
isAnyExpands: dataOperator.isAnyExpands(data, keyField, this.state.expanded),
onRowExpand: this.handleRowExpand,
onAllRowExpand: this.handleAllRowExpand
Expand Down
29 changes: 24 additions & 5 deletions packages/react-bootstrap-table2/src/row-expand/expand-row.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,37 @@
import React from 'react';
import PropTypes from 'prop-types';
import { CSSTransition } from 'react-transition-group';

const ExpandRow = ({ children, ...rest }) => (
<tr className="expanding-row">
<td { ...rest }>{ children }</td>
const ExpandRow = ({ children, expanded, onClosed, ...rest }) => (
<tr>
<td className="reset-expansion-style" { ...rest }>
<CSSTransition
appear
in={ expanded }
timeout={ 400 }
classNames="row-expand-slide"
onExited={ onClosed }
>
<div>
<div className="row-expansion-style">
{ children }
</div>
</div>
</CSSTransition>
</td>
</tr>
);

ExpandRow.propTypes = {
children: PropTypes.node
children: PropTypes.node,
expanded: PropTypes.bool,
onClosed: PropTypes.func
};

ExpandRow.defaultProps = {
children: null
children: null,
expanded: false,
onClosed: null
};

export default ExpandRow;
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export default (Component) => {
const key = props.value;

const expanded = expandRow.expanded.includes(key);
const isClosing = expandRow.isClosing.includes(key);
const expandable = !expandRow.nonExpandable || !expandRow.nonExpandable.includes(key);

return [
<Component
{ ...props }
Expand All @@ -18,9 +18,11 @@ export default (Component) => {
expandable={ expandable }
expandRow={ { ...expandRow } }
/>,
expanded ? <ExpandRow
expanded || isClosing ? <ExpandRow
key={ `${key}-expanding` }
colSpan={ props.visibleColumnSize }
expanded={ expanded }
onClosed={ () => expandRow.onClosed(key) }
>
{ expandRow.renderer(props.row) }
</ExpandRow> : null
Expand Down
28 changes: 23 additions & 5 deletions packages/react-bootstrap-table2/style/react-bootstrap-table2.scss
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@
text-align: center;
}

tr.expanding-row {
padding: 5px;
}

td.react-bootstrap-table-editing-cell {
.animated {
animation-fill-mode: both;
Expand Down Expand Up @@ -161,4 +157,26 @@
animation-name: bounceOut;
}
}
}
.reset-expansion-style{
padding: 0;
}
.row-expansion-style{
padding: 8px;
}
.row-expand-slide-appear{
max-height: 0;
overflow: hidden;
}
.row-expand-slide-appear-active{
max-height: 1000px;
transition: max-height 3s linear;
}
.row-expand-slide-exit{
max-height: 1000px;
}
.row-expand-slide-exit-active{
max-height: 0;
overflow: hidden;
transition: max-height 400ms cubic-bezier(0, 0.95, 0, 0.95)
}
}