mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2025-10-16 11:55:39 +00:00
implement expand row sketch
This commit is contained in:
parent
6eaffe1993
commit
35b1e37940
26
packages/react-bootstrap-table2/src/body.js
vendored
26
packages/react-bootstrap-table2/src/body.js
vendored
@ -7,6 +7,7 @@ import cs from 'classnames';
|
||||
|
||||
import _ from './utils';
|
||||
import Row from './row';
|
||||
import ExpandRow from './row-expand/expand-row';
|
||||
import RowSection from './row-section';
|
||||
import Const from './const';
|
||||
|
||||
@ -23,7 +24,8 @@ const Body = (props) => {
|
||||
selectedRowKeys,
|
||||
rowStyle,
|
||||
rowClasses,
|
||||
rowEvents
|
||||
rowEvents,
|
||||
expandRow
|
||||
} = props;
|
||||
|
||||
const {
|
||||
@ -74,8 +76,10 @@ const Body = (props) => {
|
||||
}
|
||||
|
||||
const selectable = !nonSelectable || !nonSelectable.includes(key);
|
||||
const expandable = expandRow && !expandRow.nonExpandable.includes(key);
|
||||
const expanded = expandRow && expandRow.expanded.includes(key);
|
||||
|
||||
return (
|
||||
const result = [
|
||||
<Row
|
||||
key={ key }
|
||||
row={ row }
|
||||
@ -85,13 +89,29 @@ const Body = (props) => {
|
||||
cellEdit={ cellEdit }
|
||||
editable={ editable }
|
||||
selectable={ selectable }
|
||||
expandable={ expandable }
|
||||
selected={ selected }
|
||||
expanded={ expanded }
|
||||
selectRow={ selectRow }
|
||||
expandRow={ expandRow }
|
||||
style={ style }
|
||||
className={ classes }
|
||||
attrs={ attrs }
|
||||
/>
|
||||
);
|
||||
];
|
||||
|
||||
if (expanded) {
|
||||
result.push((
|
||||
<ExpandRow
|
||||
key={ `${key}-expanding` }
|
||||
colSpan={ visibleColumnSize }
|
||||
>
|
||||
{ expandRow.renderer(row) }
|
||||
</ExpandRow>
|
||||
));
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -97,6 +97,7 @@ class BootstrapTable extends PropsBaseResolver(Component) {
|
||||
cellEdit={ this.props.cellEdit || {} }
|
||||
selectRow={ cellSelectionInfo }
|
||||
selectedRowKeys={ selected }
|
||||
expandRow={ this.resolveExpandRowProps() }
|
||||
rowStyle={ rowStyle }
|
||||
rowClasses={ rowClasses }
|
||||
rowEvents={ rowEvents }
|
||||
@ -145,6 +146,14 @@ BootstrapTable.propTypes = {
|
||||
}),
|
||||
onRowSelect: PropTypes.func,
|
||||
onAllRowsSelect: PropTypes.func,
|
||||
expandRow: PropTypes.shape({
|
||||
renderer: PropTypes.func.isRequired,
|
||||
expanded: PropTypes.array,
|
||||
nonExpandable: PropTypes.array,
|
||||
showExpandColumn: PropTypes.bool,
|
||||
expandColumnRenderer: PropTypes.func
|
||||
}),
|
||||
onRowExpand: PropTypes.func,
|
||||
rowStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
|
||||
rowEvents: PropTypes.object,
|
||||
rowClasses: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
|
||||
|
||||
@ -5,6 +5,7 @@ import _ from '../utils';
|
||||
import createDataContext from './data-context';
|
||||
import createSortContext from './sort-context';
|
||||
import createSelectionContext from './selection-context';
|
||||
import createRowExpandContext from './row-expand-context';
|
||||
import remoteResolver from '../props-resolver/remote-resolver';
|
||||
import dataOperator from '../store/operators';
|
||||
|
||||
@ -23,6 +24,10 @@ const withContext = Base =>
|
||||
this.SelectionContext = createSelectionContext(dataOperator);
|
||||
}
|
||||
|
||||
if (props.expandRow) {
|
||||
this.RowExpandContext = createRowExpandContext(dataOperator);
|
||||
}
|
||||
|
||||
if (props.cellEdit && props.cellEdit.createContext) {
|
||||
this.CellEditContext = props.cellEdit.createContext(
|
||||
_, dataOperator, this.isRemoteCellEdit, this.handleRemoteCellChange);
|
||||
@ -52,6 +57,7 @@ const withContext = Base =>
|
||||
searchProps,
|
||||
sortProps,
|
||||
paginationProps,
|
||||
expandProps,
|
||||
selectionProps
|
||||
) => (
|
||||
<Base
|
||||
@ -62,6 +68,7 @@ const withContext = Base =>
|
||||
{ ...filterProps }
|
||||
{ ...searchProps }
|
||||
{ ...paginationProps }
|
||||
{ ...expandProps }
|
||||
data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) }
|
||||
/>
|
||||
);
|
||||
@ -74,7 +81,8 @@ const withContext = Base =>
|
||||
filterProps,
|
||||
searchProps,
|
||||
sortProps,
|
||||
paginationProps
|
||||
paginationProps,
|
||||
expandProps
|
||||
) => (
|
||||
<this.SelectionContext.Provider
|
||||
{ ...baseProps }
|
||||
@ -90,6 +98,7 @@ const withContext = Base =>
|
||||
searchProps,
|
||||
sortProps,
|
||||
paginationProps,
|
||||
expandProps,
|
||||
selectionProps
|
||||
)
|
||||
}
|
||||
@ -98,6 +107,37 @@ const withContext = Base =>
|
||||
);
|
||||
}
|
||||
|
||||
renderWithRowExpandCtx(base, baseProps) {
|
||||
return (
|
||||
rootProps,
|
||||
cellEditProps,
|
||||
filterProps,
|
||||
searchProps,
|
||||
sortProps,
|
||||
paginationProps
|
||||
) => (
|
||||
<this.RowExpandContext.Provider
|
||||
{ ...baseProps }
|
||||
expandRow={ this.props.expandRow }
|
||||
data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) }
|
||||
>
|
||||
<this.RowExpandContext.Consumer>
|
||||
{
|
||||
expandProps => base(
|
||||
rootProps,
|
||||
cellEditProps,
|
||||
filterProps,
|
||||
searchProps,
|
||||
sortProps,
|
||||
paginationProps,
|
||||
expandProps
|
||||
)
|
||||
}
|
||||
</this.RowExpandContext.Consumer>
|
||||
</this.RowExpandContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
renderWithPaginationCtx(base) {
|
||||
return (
|
||||
rootProps,
|
||||
@ -232,6 +272,10 @@ const withContext = Base =>
|
||||
base = this.renderWithSelectionCtx(base, baseProps);
|
||||
}
|
||||
|
||||
if (this.RowExpandContext) {
|
||||
base = this.renderWithRowExpandCtx(base, baseProps);
|
||||
}
|
||||
|
||||
if (this.PaginationContext) {
|
||||
base = this.renderWithPaginationCtx(base, baseProps);
|
||||
}
|
||||
|
||||
62
packages/react-bootstrap-table2/src/contexts/row-expand-context.js
vendored
Normal file
62
packages/react-bootstrap-table2/src/contexts/row-expand-context.js
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export default (
|
||||
dataOperator
|
||||
) => {
|
||||
const RowExpandContext = React.createContext();
|
||||
|
||||
class RowExpandProvider extends React.Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
data: PropTypes.array.isRequired,
|
||||
keyField: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
state = { expanded: this.props.expandRow.expanded || [] };
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.expandRow) {
|
||||
this.setState(() => ({
|
||||
expanded: nextProps.expandRow.expanded || this.state.expanded
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
handleRowExpand = (rowKey, expanded, rowIndex, e) => {
|
||||
const { data, keyField, expandRow: { onExpand } } = this.props;
|
||||
|
||||
let currExpanded = [...this.state.expanded];
|
||||
|
||||
if (expanded) {
|
||||
currExpanded.push(rowKey);
|
||||
} else {
|
||||
currExpanded = currExpanded.filter(value => value !== rowKey);
|
||||
}
|
||||
|
||||
if (onExpand) {
|
||||
const row = dataOperator.getRowByRowId(data, keyField, rowKey);
|
||||
onExpand(row, expanded, rowIndex, e);
|
||||
}
|
||||
this.setState(() => ({ expanded: currExpanded }));
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<RowExpandContext.Provider
|
||||
value={ {
|
||||
expanded: this.state.expanded,
|
||||
onRowExpand: this.handleRowExpand
|
||||
} }
|
||||
>
|
||||
{ this.props.children }
|
||||
</RowExpandContext.Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
return {
|
||||
Provider: RowExpandProvider,
|
||||
Consumer: RowExpandContext.Consumer
|
||||
};
|
||||
};
|
||||
@ -1,10 +1,13 @@
|
||||
export default ExtendBase =>
|
||||
class ColumnResolver extends ExtendBase {
|
||||
visibleColumnSize(includeSelectColumn = true) {
|
||||
const columnLen = this.props.columns.filter(c => !c.hidden).length;
|
||||
let columnLen = this.props.columns.filter(c => !c.hidden).length;
|
||||
if (!includeSelectColumn) return columnLen;
|
||||
if (this.props.selectRow && !this.props.selectRow.hideSelectColumn) {
|
||||
return columnLen + 1;
|
||||
columnLen += 1;
|
||||
}
|
||||
if (this.props.expandRow && this.props.expandRow.showExpandColumn) {
|
||||
columnLen += 1;
|
||||
}
|
||||
return columnLen;
|
||||
}
|
||||
|
||||
15
packages/react-bootstrap-table2/src/props-resolver/expand-row-resolver.js
vendored
Normal file
15
packages/react-bootstrap-table2/src/props-resolver/expand-row-resolver.js
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
export default ExtendBase =>
|
||||
class ExpandRowResolver extends ExtendBase {
|
||||
resolveExpandRowProps() {
|
||||
const { expandRow, expanded, onRowExpand } = this.props;
|
||||
if (expandRow) {
|
||||
return {
|
||||
...expandRow,
|
||||
expanded,
|
||||
onRowExpand,
|
||||
nonExpandable: expandRow.nonExpandable || []
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@ -1,9 +1,11 @@
|
||||
import ColumnResolver from './column-resolver';
|
||||
import ExpandRowResolver from './expand-row-resolver';
|
||||
import Const from '../const';
|
||||
import _ from '../utils';
|
||||
|
||||
export default ExtendBase =>
|
||||
class TableResolver extends ColumnResolver(ExtendBase) {
|
||||
class TableResolver extends
|
||||
ExpandRowResolver(ColumnResolver(ExtendBase)) {
|
||||
validateProps() {
|
||||
const { keyField } = this.props;
|
||||
if (!keyField) {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import _ from './utils';
|
||||
import Const from './const';
|
||||
|
||||
const events = [
|
||||
'onClick',
|
||||
@ -30,11 +31,11 @@ export default ExtendBase =>
|
||||
selected,
|
||||
keyField,
|
||||
selectable,
|
||||
expandable,
|
||||
rowIndex,
|
||||
selectRow: {
|
||||
onRowSelect,
|
||||
clickToEdit
|
||||
},
|
||||
expanded,
|
||||
expandRow,
|
||||
selectRow,
|
||||
cellEdit: {
|
||||
mode,
|
||||
DBCLICK_TO_CELL_EDIT,
|
||||
@ -46,13 +47,16 @@ export default ExtendBase =>
|
||||
if (cb) {
|
||||
cb(e, row, rowIndex);
|
||||
}
|
||||
if (selectable) {
|
||||
const key = _.get(row, keyField);
|
||||
onRowSelect(key, !selected, rowIndex, e);
|
||||
const key = _.get(row, keyField);
|
||||
if (expandRow && expandable) {
|
||||
expandRow.onRowExpand(key, !expanded, rowIndex, e);
|
||||
}
|
||||
if (selectRow.mode !== Const.ROW_SELECT_DISABLED && selectable) {
|
||||
selectRow.onRowSelect(key, !selected, rowIndex, e);
|
||||
}
|
||||
};
|
||||
|
||||
if (mode === DBCLICK_TO_CELL_EDIT && clickToEdit) {
|
||||
if (mode === DBCLICK_TO_CELL_EDIT && selectRow.clickToEdit) {
|
||||
this.clickNum += 1;
|
||||
_.debounce(() => {
|
||||
if (this.clickNum === 1) {
|
||||
@ -68,7 +72,8 @@ export default ExtendBase =>
|
||||
|
||||
delegate(attrs = {}) {
|
||||
const newAttrs = {};
|
||||
if (this.props.selectRow && this.props.selectRow.clickToSelect) {
|
||||
const { expandRow, selectRow } = this.props;
|
||||
if (expandRow || (selectRow && selectRow.clickToSelect)) {
|
||||
newAttrs.onClick = this.createClickEventHandler(attrs.onClick);
|
||||
}
|
||||
Object.keys(attrs).forEach((attr) => {
|
||||
|
||||
18
packages/react-bootstrap-table2/src/row-expand/expand-row.js
vendored
Normal file
18
packages/react-bootstrap-table2/src/row-expand/expand-row.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const ExpandRow = ({ children, ...rest }) => (
|
||||
<tr className="expanding-row">
|
||||
<td { ...rest }>{ children }</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
ExpandRow.propTypes = {
|
||||
children: PropTypes.node
|
||||
};
|
||||
|
||||
ExpandRow.defaultProps = {
|
||||
children: null
|
||||
};
|
||||
|
||||
export default ExpandRow;
|
||||
@ -30,6 +30,10 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
tr.expanding-row {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
td.react-bootstrap-table-editing-cell {
|
||||
.animated {
|
||||
animation-fill-mode: both;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user